我有一個自定義UIView使用UIKit動態來執行動畫時,用戶點擊一個按鈕。有問題的觀點很簡單,我在layoutSubviews()
手動佈局。但是,在UIKit Dynamics處於操作狀態時,每個動畫幀都會調用layoutSubviews()
,並且在此期間我做出的所有佈局更改(例如,響應較高的狀態欄)都會導致動態視圖失真。如何在使用UIKit Dynamics時更新UIView佈局?
如何在UIKit Dynamics動畫正在進行時對視圖大小的變化做出響應?
更新
我創建了一個演示項目(儘管它剝奪了其非常緊密地匹配我的使用情況下,),並張貼on GitHub。故事板使用AutoLayout,但該視圖選擇AutoLayout用於佈置與translatesAutoresizingMaskIntoConstraints = false
自己的子視圖。要重現這種行爲,請在模擬器中運行(我選擇了iPhone 5),然後在恆星擺動時點擊⌘Y以觀察失真。這是視圖代碼:
import UIKit
class CustomView: UIView {
var swingingView: UIView!
var animator: UIDynamicAnimator!
var attachment: UIAttachmentBehavior!
var lastViewFrame = CGRectZero
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.translatesAutoresizingMaskIntoConstraints = false
swingingView = UIImageView(image: UIImage(named: "Star"))
self.addSubview(swingingView)
}
override func layoutSubviews() {
// Don't run for every frame of the animation. Only when responding to a layout change
guard self.frame != lastViewFrame else {
return
}
lastViewFrame = self.frame
swingingView.frame = CGRect(x: 0, y: self.frame.size.height/2, width: 100, height: 100)
// Only run this setup code once
if animator == nil {
animator = UIDynamicAnimator(referenceView: self)
let gravity = UIGravityBehavior(items: [swingingView])
gravity.magnitude = 1.5
animator.addBehavior(gravity)
attachment = UIAttachmentBehavior(item: swingingView,
offsetFromCenter: UIOffset(horizontal: 0, vertical: swingingView.frame.size.height/-2),
attachedToAnchor: CGPoint(x: self.bounds.size.width/2, y: 0))
attachment.length = CGFloat(250.0)
animator.addBehavior(attachment)
}
animator.updateItemUsingCurrentState(swingingView)
}
}
您是否嘗試過創建'UIViewController'的自定義實例,而將您的動畫和佈局放在'viewDidLoad()'裏面?這將解決多次觸發佈局代碼的問題。 – NSGangster
你可以把代碼放在這裏嗎?我認爲可能發生的事情是你的autoLayout是基於你的動畫視圖,所以當它動畫時,updateConstraints被調用,它扭曲了基於動畫的視圖。如果是這種情況,請確保您的其他視圖約束基於佈局指南頁邊距,而不是基於動畫的視圖 – NSGangster
嗯,我想最好的方法是調試,如果您使用變量來設置幀。也許可以在'layoutSubviews()'中設置幀的位置設置斷點並查看哪些值正在更改。沒有我害怕的代碼,我無法得到很多幫助。 – NSGangster