[英]UIView CATransform3DMakeRotation horizontally from left to right
[英]UIView doesn't animate horizontally from right to left
我在水平UIStackView
有兩個UIButtons
。 我想添加一個UIView
作為子視圖,這樣當我按下其中一個按鈕時,視圖會水平移動到所選按鈕。
我有這個代碼:
let selectionView = UIView(frame: CGRect(x: 0, y: 0, width: 70, height: 19))
selectionView.backgroundColor = UIColor.greenColor()
self.incomeButton.addSubview(selectionView) // left button
// left button touched
@IBAction func incomeDidTouch(sender: AnyObject) {
self.incomeButton.setTitleColor(UIColor.whiteColor(), forState: .Normal)
self.expensiveButton.setTitleColor(UIColor.grayColor(), forState: .Normal)
UIView.animateWithDuration(0.3) {
self.selectionView.backgroundColor = UIColor.greenColor()
self.selectionView.center = self.incomeButton.center
}
}
// right button touched
@IBAction func expensiveDidTouch(sender: AnyObject) {
self.expensiveButton.setTitleColor(UIColor.whiteColor(), forState: .Normal)
self.incomeButton.setTitleColor(UIColor.grayColor(), forState: .Normal)
UIView.animateWithDuration(0.3) {
self.selectionView.backgroundColor = UIColor.redColor()
self.selectionView.center = self.expensiveButton.center
}
當視圖添加到左側按鈕時,此代碼實際上有效。 單擊按鈕時,視圖將從左向右和從右向左移動。
但如果我選擇右鍵開始:
let selectionView = UIView(frame: CGRect(x: 0, y: 0, width: 70, height: 19))
selectionView.backgroundColor = UIColor.redColor()
self.expensiveButton.addSubview(selectionView) // right button
視圖僅更改顏色,但不會從右向左移動。
這是為什么 ? 如何修復我的代碼以便可以移動視圖?
UPDATE
:
我嘗試在UIView
添加堆棧視圖,並在其中添加selectionView。 這是一個快照:
當我選擇右鍵運行應用程序時,我仍然遇到問題,selectionView出現在containerView之外(它應該出現在Expensive文本的右側):
當我檢查應該選擇哪個按鈕時,這是viewDidLoad
的代碼:
if type == .Income {
self.selectionView.backgroundColor = UIColor(hex: "28BB9D")
self.selectionView.center = self.incomeButton.center
} else {
self.selectionView.backgroundColor = UIColor(hex: "E5344A")
}
UPDATE 2:
selectionView的當前約束:
目標 :
以編程方式創建selectionView
以將兩個UIButton
切換為子項。
為了更好地解釋我已經添加(開始) selectionView
到expensiveButton
(你有問題的按鈕......)的情況。
您可以在項目中進行一些更正,以確保其運行良好。
class ViewController: UIViewController {
@IBOutlet weak var stackView: UIStackView!
@IBOutlet weak var incomeButton: UIButton!
@IBOutlet weak var expensiveButton: UIButton!
var selectionView : UIView!
override func viewDidLoad() {
super.viewDidLoad()
selectionView = UIView(frame: CGRect(x: 0, y: 0, width: 70, height: 19))
selectionView.backgroundColor = UIColor.greenColor()
selectionView.tag = 666
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
self.expensiveButton.addSubview(selectionView)
self.selectionView.backgroundColor = UIColor.redColor()
self.selectionView.center = CGPointMake(self.expensiveButton.bounds.midX, self.expensiveButton.bounds.midY)
}
@IBAction func incomeDidTouch(sender: AnyObject) {
if let _ = sender.viewWithTag(666) {} else {
self.incomeButton.addSubview(selectionView)
}
self.expensiveButton.viewWithTag(666)?.removeFromSuperview()
self.incomeButton.setTitleColor(UIColor.whiteColor(), forState: .Normal)
self.expensiveButton.setTitleColor(UIColor.grayColor(), forState: .Normal)
UIView.animateWithDuration(0.3) {
self.selectionView.backgroundColor = UIColor.greenColor()
self.selectionView.center = CGPointMake(self.incomeButton.bounds.midX, self.incomeButton.bounds.midY)
}
}
@IBAction func expensiveDidTouch(sender: AnyObject) {
if let _ = sender.viewWithTag(666) {} else {
self.expensiveButton.addSubview(selectionView)
}
self.incomeButton.viewWithTag(666)?.removeFromSuperview()
self.expensiveButton.setTitleColor(UIColor.whiteColor(), forState: .Normal)
self.incomeButton.setTitleColor(UIColor.grayColor(), forState: .Normal)
UIView.animateWithDuration(0.3) {
self.selectionView.backgroundColor = UIColor.redColor()
self.selectionView.center = CGPointMake(self.expensiveButton.bounds.midX, self.expensiveButton.bounds.midY)
}
}
}
一些解釋 :
首先,在您的項目中,您不會報告對selectView
的全局引用,但我認為您只是忘記在您的問題中編寫它。
所以,一個好處是為你的selectionView設置一個標簽,就像一個id號碼,可以在他未來的父視圖的子視圖之間識別它(在你的情況下,它將是一個UIButton
)
你可以看到我添加了viewDidAppear
方法,為什么? 因為當你在viewDidLoad
你的按鈕沒有完全准備就緒,所以你的中心錯誤,當你的視圖最終被繪制時,擁有這個值的正確位置是viewDidAppear
。
現在讓我們來談談selectionView
:它是一個視圖,所以你可以將它添加到incomeButton
但是如果你已經將它添加到另一個按鈕中,則必須使用以下行將其從expensiveButton中刪除:
self.expensiveButton.viewWithTag(666)?.removeFromSuperview()
最后的中心點:記住你在自動布局中,所以找到它的好方法可以是使用邊界:
self.selectionView.center = CGPointMake(self.expensiveButton.bounds.midX, self.expensiveButton.bounds.midY)
這是我的項目結構,我看到你正在研究它:
更新 :
在我看到您的更新后(您開始使用以編程方式創建的selectionView
)對您的問題進行了一些評論和回答,我懷疑您想要實現自定義UISegmentedControl
。 我認為使用UIStackView
來實現一點點控制,這不是一個好主意,你可以在UISegmentedControl
周圍找到許多項目,例如類似於BetterSegmentedControl的子類UIControl
:
一個代碼示例 :
let control = BetterSegmentedControl(
frame: CGRect(x: 0.0, y: 100.0, width: view.bounds.width, height: 44.0),
titles: ["One", "Two", "Three"],
index: 1,
backgroundColor: UIColor(red:0.11, green:0.12, blue:0.13, alpha:1.00),
titleColor: .whiteColor(),
indicatorViewBackgroundColor: UIColor(red:0.55, green:0.26, blue:0.86, alpha:1.00),
selectedTitleColor: .blackColor())
control.titleFont = UIFont(name: "HelveticaNeue", size: 14.0)!
control.selectedTitleFont = UIFont(name: "HelveticaNeue-Medium", size: 14.0)!
control.addTarget(self, action: #selector(ViewController.controlValueChanged(_:)), forControlEvents: .ValueChanged)
view.addSubview(control)
圖片 :
這里的關鍵問題是坐標系。 您正在將selectionView添加為一個按鈕或另一個按鈕的子視圖,但由於它在兩者之間移動,因此它實際上應該是兩個按鈕的某些祖先視圖的子視圖。
當您更改selectionView中心時,它會相對於其超級視圖設置其動畫的位置,在當前代碼中,該視圖是左按鈕或右按鈕。 從左到右進行動畫制作,因為右按鈕的中心是一些坐標,其x值大於selectionView在左按鈕坐標空間內的值。 但是當您從右側按鈕的坐標空間內的selectionView開始時,左側按鈕的中心相對於其自己的超級視圖可能非常接近於選擇視圖 相對於右側按鈕坐標空間的中心。 所以沒有任何真正的運動。
如果您這樣想的話,這可能更容易可視化:為了從右按鈕的坐標空間移動到左按鈕的位置,selectionView的中心x將需要是負數,因為它需要是右鍵前緣左側。 但是,左側按鈕的中心相對於其自己的超級視圖具有正x值。 因此,如果選擇視圖的中心位於右側按鈕的坐標空間內,則將其設置為左側按鈕的中心將永遠不會向左移動。
通過將選擇視圖添加到兩個按鈕所在的同一超視圖中,可以成功使用動畫中的中心坐標,因為所有三個視圖(2個按鈕和selectionView)將位於相同的坐標空間中。
如果2個按鈕位於堆棧視圖中,這可能會有點麻煩,因為您不希望手動設置堆棧視圖排列的內容。 在這種情況下,解決方案是將堆棧視圖包裝在普通的UIView中,並在堆棧視圖前面添加selectionView,作為同一個普通UIView的子項。
只要堆棧視圖框架與包含UIView的邊界匹配,它仍然可以正常工作,以便在左按鈕中心和右按鈕中心之間為selectionView的中心設置動畫。
使用以下視圖層次結構,您的代碼將起作用:
containerView
|____ selectionView
|____ stackView
|_______ leftButton
|_______ rightButton
這是我的解決方案。 我做了以下視圖和約束安排:
選擇視圖具有以下約束:
在4個約束中,第一個約束(將中心X對齊到堆棧視圖)是視圖控制器。 總奧特萊斯如下:
@IBOutlet weak var stackView: UIStackView!
@IBOutlet weak var selectionView: UIView!
@IBOutlet weak var selectionviewCenterCon: NSLayoutConstraint!
@IBOutlet weak var expensiveBtn: UIButton!
@IBOutlet weak var incomeBtn: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
self.selectionView.backgroundColor = UIColor.redColor()
self.selectionviewCenterCon.constant = -stackView.frame.size.width / 4
}
@IBAction func expensiveBtnClicked(sender: AnyObject) {
self.selectionviewCenterCon.constant = -stackView.frame.size.width / 4
UIView.animateWithDuration(0.3) {
self.selectionView.backgroundColor = UIColor.redColor()
self.view.layoutIfNeeded()
}
}
@IBAction func incomeBtnClicked(sender: AnyObject) {
self.selectionviewCenterCon.constant = stackView.frame.size.width / 4
UIView.animateWithDuration(0.3) {
self.selectionView.backgroundColor = UIColor.greenColor()
self.view.layoutIfNeeded()
}
}
此代碼將輸出提供為:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.