我有一个缩放的UIScrollView,和一个非缩放的叠加视图,我在这个视图上设置了动画标记。这些标记需要跟踪UIScrollView的一些内容的位置(类似于在平移和缩放时丢弃的引脚需要在地图上追踪地点的方式)。如何跟踪缩放UIScrollView?
我通过响应UIScrollView的layoutSubviews
触发重叠视图的更新操作。这是有效的,并且在缩放和平移时覆盖层完美地追踪。
但当捏手势结束的UIScrollView自动执行最后的动画,并且该覆盖图是不同步的该动画的持续时间。
我做了一个简化的项目来隔离这个问题。 UIScrollView包含一个橙色正方形,覆盖视图在这个橙色正方形的框架周围显示一个2像素的红色轮廓。正如你在下面看到的那样,红色轮廓总是移动到它应该在的位置,除非触摸结束后的一小段时间,当它明显跳到橙色方块的最终位置时。
本次测试的完整的Xcode项目可以在这里找到:https://github.com/Clafou/ScrollviewZoomTrackTest但所有的代码是在如下所示的两个文件:
TrackedScrollView.swift:
class TrackedScrollView: UIScrollView {
@IBOutlet var overlaysView: UIView?
let square: UIView
required init(coder aDecoder: NSCoder) {
square = UIView(frame: CGRect(x: 50, y: 300, width: 300, height: 300))
square.backgroundColor = UIColor.orangeColor()
super.init(coder: aDecoder)
self.addSubview(square)
self.maximumZoomScale = 1
self.minimumZoomScale = 0.5
self.contentSize = CGSize(width: 500, height: 900)
self.delegate = self
}
override func layoutSubviews() {
super.layoutSubviews()
overlaysView?.setNeedsLayout()
}
}
extension TrackedScrollView: UIScrollViewDelegate {
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
return square
}
}
OverlaysView.swift:
class OverlaysView: UIView {
@IBOutlet var trackedScrollView: TrackedScrollView?
let outline: CALayer
required init(coder aDecoder: NSCoder) {
outline = CALayer()
outline.borderColor = UIColor.redColor().CGColor
outline.borderWidth = 2
super.init(coder: aDecoder)
self.layer.addSublayer(outline)
}
override func layoutSubviews() {
super.layoutSubviews()
if let trackedScrollView = self.trackedScrollView {
CATransaction.begin()
CATransaction.setDisableActions(true)
let frame = trackedScrollView.convertRect(trackedScrollView.square.frame, toView: self)
outline.frame = CGRectIntegral(CGRectInset(frame, -3, -3))
CATransaction.commit()
}
}
}
其中我试过的东西是使用CADisplayLink
和presentationLayer
这允许我为覆盖层设置动画,但我从presentationLayer
获得的坐标稍微落后于实际的UIScrollView,所以这看起来仍然不正确。我认为正确的做法是将我的覆盖更新与系统创建的UIScrollView动画绑定,但是迄今为止我还没有取得成功。
如何更新验证码总是跟踪UIScrollView的缩放内容?
整洁!我的印象是'scrollViewDidZoom:'只被调用一次,而不是在动画的每一步。我非常感谢你的帮助。 – Clafou 2014-11-07 13:25:32
顺便说一下,我向Apple Developer Technical Support发送了同一个项目和动画截图的完全相同的问题,这是他们的回应:“我们的工程师已审核您的请求,并确定这最好作为错误报告处理” 。堆栈1:Apple支持0 – Clafou 2014-11-07 13:30:31
最后说明:代理的'scrollViewDidScroll:'也需要类似的实现,因为在某些情况下,动画不是缩放而是重新重新调入滚动视图的平移。并且非常感谢你Rob的真棒回答! – Clafou 2014-11-07 17:21:58