UIScrollView缓慢滚动



我创建了宽度 = 3500 的UIView

在视图中,我使用带有UIBezierPathCAShapeLayer绘制了一个声波,其中包含 70008 个样本,彼此间隔为 0.05 (70008*0.05=3500)。

UIBezierPath的线宽为 0.10。

使用AVAudioPCMBuffer宽度140016256帧容量仅读取一次内容。

当读取AVAudioPCMBuffer2000 个值时,每 1 个值"未读取"(140016256/2000 = 70008)

UIView的内容是UIScrollView的上下文大小,因此当用户拖动到滚动视图中时,他可以看到声波的不同部分。

问题是滚动时需要很长时间才能执行滚动。

这是代码:

func drawSoundWave(fromSample:Int64, toSample:Int64){
// Drawing code
print("(logClassName): Drawing from = (fromSample) to (toSample)")
if readFile != nil{
let soundPath = UIBezierPath()
soundPath.lineWidth = lineWidth
soundPath.move(to: CGPoint(x:0.0 , y: middleY))
let testTo = Int64(toSample)

let sequence = stride(from: fromSample, to: testTo, by: 2000)

var testIndex = 0
for element in sequence {
let newSample = CGFloat(readFile?.audioBuffer.floatChannelData?.pointee.advanced(by: Int(element)).pointee ?? 0)
print("(logClassName): newSample = (newSample) -> TestIndex = (testIndex) in Element = (element)")
/** Continuous View **/
let nextPoint = CGPoint(x: soundPath.currentPoint.x + sampleSpace,
y: middleY - (newSample * 100) - 1.0)
soundPath.addLine(to: nextPoint)
soundPath.move(to: nextPoint)
testIndex += 1
}

let trackLayer = CAShapeLayer()
trackLayer.path = soundPath.cgPath
trackLayer.strokeColor = UIColor.lightGray.cgColor
trackLayer.lineWidth = 0.10
trackLayer.fillColor = UIColor.green.cgColor
trackLayer.lineCap = kCALineCapRound
self.layer.addSublayer(trackLayer)
}
}

我可以做一些不同的事情来优化代码还是我正在使用许多资源?

编辑:

AVAudioPCMBuffer位于名为 readFile 的结构中。 未在 Draw 方法中调用该函数

我可以做一些不同的事情来优化代码还是我正在使用许多资源?

您可以做的第一件事是分析您的代码,以找出它大部分时间花费在哪里。问题是您一次从文件中读取一个样本吗?也许使用 2000 步幅会导致丢失文件缓冲区的大部分好处,因此从文件中读取每 2000 个样本的成本比您意识到的要高?还是您每次都在创建新的贝塞尔路径或形状图层?也许只是每个样本的打印语句需要时间?在你知道代码慢的地方之前,你无法真正知道如何加快代码的速度。

请记住,在滚动过程中,将重复调用绘制方法,并且它应该尽可能少地执行实际工作。如果您的代码在只需要绘制新暴露的数据时重新计算整个可见区域的数据,那么这是一个大幅提高速度的机会。在滚动过程中以较低的分辨率绘制,然后在滚动停止时以全分辨率重新绘制会有所帮助。保持低分辨率(就样本而言)贝塞尔路径而不是一直创建一个新的路径可能会有所帮助。但同样:首先衡量,其次改进。

跳出的一件事是,您将 70,000 个数据点绘制到一个 3500 像素宽的视图中。每个宽度像素的 20 个数据点远远超过用户即使在视图不移动时也能识别的数据;当用户滚动时,他们几乎看不到任何数据。即使你必须查看那么多样本才能找到波浪的波峰和波谷,你肯定不需要在路径上添加那么多点。

最新更新