Ios UIScrollView缓慢滚动
我创建了宽度为3500的Ios UIScrollView缓慢滚动,ios,swift,uiscrollview,Ios,Swift,Uiscrollview,我创建了宽度为3500的UIView 在视图内部,我使用CAShapeLayer和UIBezierPath绘制了一个声波,其中包含70008个样本,每个样本间隔为0.05(70008*0.05=3500) UIBezierPath的线宽为0.10 使用AVAudioPCMBufferwidth 140016256帧容量,内容仅读取一次 当读取AVAudioPCMBuffer时,每1读取2000个值为“未读取”(140016256/2000=70008) UIView的内容是UIScrollVie
UIView
在视图内部,我使用CAShapeLayer
和UIBezierPath
绘制了一个声波,其中包含70008个样本,每个样本间隔为0.05(70008*0.05=3500)
UIBezierPath
的线宽为0.10
使用AVAudioPCMBuffer
width 140016256帧容量,内容仅读取一次
当读取AVAudioPCMBuffer
时,每1读取2000个值为“未读取”(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个样本的成本比您意识到的要高?还是每次通过时都要创建一个新的贝塞尔路径或形状层?也许只是每个样本的打印声明需要时间只有知道代码的速度慢到哪里,才能真正知道如何加速代码。
请记住,在滚动期间,您的draw方法将被反复调用,并且它应该尽可能少地进行实际工作。如果您的代码重新计算整个可见区域的数据,而它只需要绘制新暴露的数据,那么这是一个大幅度提高速度的机会。在滚动期间以较低的分辨率绘制,然后在滚动停止时以完全分辨率重新绘制可能会有所帮助。保持一个低分辨率(就样本而言)的贝塞尔路径,而不是一直创建一个新的路径可能会有所帮助。但同样:首先衡量,其次改进。
跳出的一件事是,您正在将70000个数据点绘制到3500像素宽的视图中。每个宽度像素20个数据点的数据量远远超过用户在视图不移动时所能识别的数据量;当用户滚动时,他们几乎看不到任何数据。即使您必须查看那么多样本才能找到波浪的波峰和波谷,您当然不需要在路径上添加那么多点。尝试识别。UIBezierPath只绘制一次。我要试着看看这个决议是否太简单了much@ReimondHill每次调用draw方法时,只绘制一次路径,但用户滚动时会重复调用draw方法。1每2000次太多。最后我每4800做一次,所以一秒钟有10个样本