Я хочу показать интерактивную аудио -форму, подобную этой. Используя эти данные, я рисую UibezierPath в ContentView's ScollView. В настоящее время, когда я зажимаю масштаб или увеличиваю ScrollView, я снижаю образец данных, чтобы определить, сколько выборок должно быть показано. < /P>
class WaveformView: UIView {
var amplitudes: [CGFloat] = [] {
didSet {
setNeedsDisplay()
}
}
override func draw(_ rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext(), !amplitudes.isEmpty else { return }
// Set up drawing parameters
context.setStrokeColor(UIColor.black.cgColor)
context.setLineWidth(1.0)
context.setLineCap(.round)
let midY = rect.height / 2
let widthPerSample = rect.width / CGFloat(amplitudes.count)
// Draw waveform
let path = UIBezierPath()
for (index, amplitude) in amplitudes.enumerated() {
let x = CGFloat(index) * widthPerSample
let height = amplitude * rect.height * 0.8
// Draw vertical line for each sample
path.move(to: CGPoint(x: x, y: midY - height))
path.addLine(to: CGPoint(x: x, y: midY + height))
}
path.stroke()
}
}
< /code>
Добавлен Групп жеста < /p>
@objc private func handlePinch(_ gesture: UIPinchGestureRecognizer) {
switch gesture.state {
case .began:
initialPinchDistance = gesture.scale
case .changed:
let scaleFactor = gesture.scale / initialPinchDistance
var newScale = currentScale * scaleFactor
newScale = min(max(newScale, minScale), maxScale)
// Update displayed samples with new scale
updateDisplayedSamples(scale: newScale)
print(newScale)
// Maintain zoom center point
let pinchCenter = gesture.location(in: scrollView)
let offsetX = (pinchCenter.x - scrollView.bounds.origin.x) / scrollView.bounds.width
let newOffsetX = (totalWidth * offsetX) - (pinchCenter.x - scrollView.bounds.origin.x)
scrollView.contentOffset.x = max(0, min(newOffsetX, totalWidth - scrollView.bounds.width))
view.layoutIfNeeded()
case .ended, .cancelled:
currentScale = scrollView.contentSize.width / (baseWidth * widthPerSample)
default:
break
}
}
< /code>
private func updateDisplayedSamples(scale: CGFloat) {
let targetSampleCount = Int(baseWidth * scale)
displayedSamples = downsampleWaveform(samples: rawSamples, targetCount: targetSampleCount)
waveformView.amplitudes = displayedSamples
totalWidth = CGFloat(displayedSamples.count) * widthPerSample
contentWidthConstraint?.constant = totalWidth
scrollView.contentSize = CGSize(width: totalWidth, height: 300)
}
< /code>
private func downsampleWaveform(samples: [CGFloat], targetCount: Int) -> [CGFloat] {
guard samples.count > 0, targetCount > 0 else { return [] }
if samples.count
Подробнее здесь: https://stackoverflow.com/questions/793 ... aphics-ios