[英]UIButton frame doesn't change if its panned
該應用程序具有用於中心紫色按鈕的平移手勢識別器,如果該按鈕與四個橙色按鈕中的任意一個相交,則該按鈕在移動時會移動,該紫色按鈕會進行動畫處理並在與之交界的按鈕范圍內移動,否則會動畫化回到初始起始位置即中心。
第一次平移紫色按鈕時,按鈕的框架會更新,但是如果我第二次嘗試,按鈕的框架將保持不變(當它位於視圖中心時的值)。
我猜想這是我缺少的與“自動版式”相關的內容,因為如果我取消了紫色中心按鈕的約束,則每次平移時幀都會正確更新。
有人可以解釋約束動畫時我要記住的幾點嗎
這是我用於處理平移手勢的代碼:
@objc func handleCenterRectPan(_ pannedView: UIPanGestureRecognizer) {
let fallBackAnimation = UIViewPropertyAnimator(duration: 0.3, dampingRatio: 0.5) {
if self.button1.frame.intersects(self.centerRect.frame) {
self.centerRect.center = self.button1.center
} else if self.button2.frame.contains(self.centerRect.frame) {
self.centerRect.center = self.button2.center
} else if self.button3.frame.contains(self.centerRect.frame) {
self.centerRect.center = self.button3.center
} else if self.button4.frame.contains(self.centerRect.frame) {
self.centerRect.center = self.button4.center
} else {
// no intersection move to original position
self.centerRect.frame = OGValues.oGCenter
}
}
switch pannedView.state {
case .began:
self.centerRect.center = pannedView.location(in: self.view)
case .changed:
print("Changed")
self.centerRect.center = pannedView.location(in: self.view)
case .ended, .cancelled, .failed :
print("Ended")
fallBackAnimation.startAnimation();
//snapTheRectangle()
default:
break
}
}
首先,如果您的目標是平穩地移動視圖,則不應施加任何限制。 而且,如果您無法抵抗約束,則必須繼續更新約束而不是框架(中心),在您的代碼中,我假設您已給出了紫色按鈕中心約束,然后隨着用戶使用平移手勢。 問題是給您的約束仍然處於活動狀態,並且在布局需要更新時會嘗試立即將其重新設置。
所以你可以做的是
不要給出限制,因為它在用戶拖動時需要自由移動
要么
為約束創建IBoutlet,並在用戶拖動時將.isActive設置為false,如果它不在其他任何按鈕內,則將其設置為true,並更新UpdateLayoutIfNeeded,這樣它將返回到原始位置。 (好的方法)
@IBOutlet var horizontalConstraints: NSLayoutConstraint!
@IBOutlet var verticalConstraints: NSLayoutConstraint!
//make active false as the user is dragging the view
horizontalConstraints.isActive = false
verticalConstraints.isActive = false
self.view.layoutIfNeeded()
//make it true again if its not inside any of the other views
horizontalConstraints.isActive = true
verticalConstraints.isActive = true
self.view.layoutIfNeeded()
要么
當用戶移動視圖時,更新constraints.constant以獲取水平和垂直約束(這不是一個好的方法),如果不在其他任何視圖內,請再次將其設為零
//make it true again if its not inside any of the other views
horizontalConstraints.constant = change in horizontal direction
verticalConstraints..constant = change in vertical direction
self.view.layoutIfNeeded()
編輯正如你所說的限制是零設置后isActive = false,因為isActive其實做的就是添加和刪除那些約束蘋果的醫生說什么
激活或停用約束將在視圖上調用addConstraint( :)和removeConstraint( :),該視圖是此約束管理的項目的最接近的共同祖先。 使用此屬性,而不是直接調用addConstraint( :)或removeConstraint( :)。
因此,使約束成為強引用確實可以解決問題,但我認為為IBOutelet設置強引用不是一個好主意,而以編程方式添加和刪除約束則更好。 查看此問題解除約束
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.