我一直對這個問題很頭疼,因為我知道事實上應該是一個簡單的解決方案,但我找不到正確的答案。
我的想法是我有兩個UIViews(我們稱它們為 A 和 B)。我想做的就是在按下按鈕時交換它們的位置,A 視圖下降到 B 位置,B 視圖上升到 A 位置。
這就是我想要實作的目標。
我試圖通過交換.center我需要的元素來實作這一點(因為 A 和 B 都在UIViews其中包含一堆元素)。這是在影片塊內 -UIView.animate
然而,目前正在發生的是影片以完全相反的方式執行:A 視圖將在螢屏上移動,然后重新出現在螢屏底部并最終到達所需位置(B 初始位置) . B 視圖也是一樣,它目前一直走到螢屏底部,然后重新出現在頂部,并在所需位置(A 初始位置)完成影片。
這就是目前正在發生的事情。
到目前為止,這是我的代碼(請注意,它ownAccountTransferView是在另一個檔案中定義的,下面的代碼位于我存盤該視圖的 UIViewController 中)。在兩張卡之間交換資料(如標簽等)后,我在按下按鈕時呼叫此函式。
fileprivate func performSwitchAnimation() {
// NOTE: ownAccountTransferView is a reference to my view, think of it like self.view
let fromAccountCardCenter =
self.ownAccountTransferView.fromAccountCardView.center
let fromAccountTypeLabelCenter =
self.ownAccountTransferView.fromAccountTypeLabel.center
let fromAccountTypeViewCenter =
self.ownAccountTransferView.fromAccountTypeView.center
let fromAccountBalanceLabelCenter =
self.ownAccountTransferView.fromAccountBalanceLabel.center
let fromAccountNameLabelCenter =
self.ownAccountTransferView.fromAccountNameLabel.center
let fromAccountChevronCenter =
self.ownAccountTransferView.fromAccountChevronView.center
let toAccountCardCenter =
self.ownAccountTransferView.toAccountCardView.center
let toAccountTypeLabelCenter =
self.ownAccountTransferView.toAccountTypeLabel.center
let toAccountTypeViewCenter =
self.ownAccountTransferView.toAccountTypeView.center
let toAccountBalanceLabelCenter =
self.ownAccountTransferView.toAccountBalanceLabel.center
let toAccountNameLabelCenter =
self.ownAccountTransferView.toAccountNameLabel.center
let toAccountChevronCenter =
self.ownAccountTransferView.toAccountChevronView.center
UIView.animate(withDuration: 1, delay: 0, options: []) {
self.ownAccountTransferView.switchAccountsButton.isUserInteractionEnabled = false
self.ownAccountTransferView.fromAccountCardView.center = toAccountCardCenter
self.ownAccountTransferView.fromAccountTypeLabel.center = toAccountTypeLabelCenter
self.ownAccountTransferView.fromAccountTypeView.center = toAccountTypeViewCenter
self.ownAccountTransferView.fromAccountBalanceLabel.center = toAccountBalanceLabelCenter
self.ownAccountTransferView.fromAccountNameLabel.center = toAccountNameLabelCenter
self.ownAccountTransferView.fromAccountChevronView.center = toAccountChevronCenter
self.ownAccountTransferView.toAccountCardView.center = fromAccountCardCenter
self.ownAccountTransferView.toAccountTypeLabel.center = fromAccountTypeLabelCenter
self.ownAccountTransferView.toAccountTypeView.center = fromAccountTypeViewCenter
self.ownAccountTransferView.toAccountBalanceLabel.center = fromAccountBalanceLabelCenter
self.ownAccountTransferView.toAccountNameLabel.center = fromAccountNameLabelCenter
self.ownAccountTransferView.toAccountChevronView.center = fromAccountChevronCenter
} completion: { isDone in
if isDone {
self.ownAccountTransferView.switchAccountsButton.isUserInteractionEnabled = true
}
}
}
那么,我怎樣才能讓影片按照我想要的方式作業——A view 到底部,B view 到頂部?
提前致謝。
更新:我通過使用變換修復了它。嘗試過很多影片約束,嘗試了頂部/底部約束之間的所有可能互動,但它要么根本不做任何事情,要么只是破壞我的視圖并將其發送到地獄。我什至堅持在與同事的支持電話中使用影片約束。他們也是。然而,在谷歌搜索絕望措施之后,我最終使用了viewController.myView.myLabel.transform = CGAffineTransform(translationX: 0, y: 236).
當然,您可以將其簡化為:view.transform = CGAffineTransform(translationX: 0, y: 236)。該值是任意的,我不確定它是否會在某天中斷或導致不良行為。我在 iPhone 8 和 iPhone 13 上對其進行了測驗,并且在這兩種影片中都表現得很好(A 視圖下降,B 上升,單擊切換并執行相反的操作,等等)。
旁注:如果你要使用它,當你需要你的視圖“回到”它們開始時的位置時,你不需要復制/粘貼這些值。我分別為 A 和 B 使用了 236 和 -236,但要恢復它們,我需要使用 -2 和 2,否則它會出現超級錯誤。我不知道為什么。但它有效!謝謝大家
uj5u.com熱心網友回復:
將這兩個視圖包含在父視圖中并執行以下操作:
if let firstIndex = view.subviews.firstIndex(of: view1), let secondIndex = view.subviews.firstIndex(of: view2) {
let firstViewFrame = view1.frame
UIView.animate(withDuration: 1, animations: {
self.view1.frame = self.view2.frame
self.view2.frame = firstViewFrame
self.view.exchangeSubview(at: firstIndex, withSubviewAt: secondIndex)
})
}
在這里查看答案。
編輯:我能夠使用自動布局約束實作上述影片。基本上我所做的是最初對兩個視圖有固定的約束。并且有兩組變化的約束 - startConstraints 和 endConstraints。只需激活和停用約束即可完成作業。 查看演示。這是我的代碼:
class ViewController: UIViewController {
var view1: UIView = {
let v = UIView()
v.backgroundColor = .red
return v
}()
var view2: UIView = {
let v = UIView()
v.backgroundColor = .blue
return v
}()
var button: UIButton = {
let b = UIButton()
b.setTitle("Animate", for: .normal)
b.setTitleColor(.black, for: .normal)
return b
}()
var fixedConstraints: [NSLayoutConstraint]!
var startConstraints: [NSLayoutConstraint]!
var endConstraints: [NSLayoutConstraint]!
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(view1)
view.addSubview(view2)
view.addSubview(button)
view1.translatesAutoresizingMaskIntoConstraints = false
view2.translatesAutoresizingMaskIntoConstraints = false
button.translatesAutoresizingMaskIntoConstraints = false
fixedConstraints = [
button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
button.centerYAnchor.constraint(equalTo: view.centerYAnchor),
view1.centerXAnchor.constraint(equalTo: view.centerXAnchor),
view2.centerXAnchor.constraint(equalTo: view.centerXAnchor),
view1.heightAnchor.constraint(equalToConstant: 100),
view1.widthAnchor.constraint(equalToConstant: 100),
view2.heightAnchor.constraint(equalToConstant: 100),
view2.widthAnchor.constraint(equalToConstant: 100),
]
startConstraints = [
view1.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 0),
view.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: view2.bottomAnchor),
]
startConstraints.append(contentsOf: fixedConstraints)
NSLayoutConstraint.activate(startConstraints)
button.addTarget(self, action: #selector(animateSwitchingOfViews), for: .touchUpInside)
}
@objc
private func animateSwitchingOfViews(){
endConstraints = [
view2.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 0),
view.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo:view1.bottomAnchor)
]
endConstraints.append(contentsOf: fixedConstraints)
UIView.animate(withDuration: 2, animations: {
NSLayoutConstraint.deactivate(self.startConstraints)
NSLayoutConstraint.activate(self.endConstraints)
self.view.layoutIfNeeded()
})
}
}
uj5u.com熱心網友回復:
更新:我通過使用變換修復了它。嘗試過很多影片約束,嘗試了頂部/底部約束之間的所有可能互動,但它要么根本不做任何事情,要么只是破壞我的視圖并將其發送到地獄。我什至堅持在與同事的支持電話中使用影片約束。他們也是。然而,在谷歌搜索絕望措施之后,我最終使用了 viewController.myView.myLabel.transform = CGAffineTransform(translationX: 0, y: 236)。
當然,您可以將其簡化為:view.transform = CGAffineTransform(translationX: 0, y: 236)。該值是任意的,我不確定它是否會在某天中斷或導致不良行為。我在 iPhone 8 和 iPhone 13 上對其進行了測驗,并且在這兩種影片中都表現得很好(A 視圖下降,B 上升,單擊切換并執行相反的操作,等等)。
旁注:如果你要使用它,當你需要你的視圖“回到”它們開始時的位置時,你不需要復制/粘貼這些值。我分別為 A 和 B 使用了 236 和 -236,但要恢復它們,我需要使用 -2 和 2,否則它會出現超級錯誤。我不知道為什么。但它有效!謝謝大家
uj5u.com熱心網友回復:
假設你想“交換中心”并且你不想修改約束/常量,你可以使用轉換。
但是,您可以這樣做,而不是硬編碼值:
// if the views are in their "original" positions
if ownAccountTransferView.transform == .identity {
let xOffset = fromAccountTypeView.center.x - ownAccountTransferView.center.x
let yOffset = fromAccountTypeView.center.y - ownAccountTransferView.center.y
UIView.animate(withDuration: 1.0, animations: {
self.ownAccountTransferView.transform = CGAffineTransform(translationX: xOffset, y: yOffset)
self.fromAccountTypeView.transform = CGAffineTransform(translationX: -xOffset, y: -yOffset)
})
} else {
UIView.animate(withDuration: 1.0, animations: {
self.ownAccountTransferView.transform = .identity
self.fromAccountTypeView.transform = .identity
})
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/535486.html
