我有一個縮放的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