UIView没有从右到左水平设置动画

时间:2016-07-17 17:43:42

标签: ios swift

我在水平UIButtons内有两个UIStackView。我想添加一个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。这是一个快照:

enter image description here

当我选择正确的按钮运行应用程序时仍然有问题,selectionView出现在containerView之外(它应该出现在Expensive文本的右侧):

enter image description here

当我检查应该选择哪个按钮时,这是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的当前约束:

enter image description here

3 个答案:

答案 0 :(得分:2)

<强>目标

以编程方式创建 selectionView,以便在孩提时间切换两个UIButton

为了更好地解释我已添加(开始)selectionViewexpensiveButton(您遇到问题的按钮......)的情况。

您可以在项目中进行一些更正,以确保其运作良好。

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)

这是我的项目结构,我看到你正在研究它:

enter image description here

<强>更新

在我看到您的更新后(您开始使用selectionView以编程方式创建)有关您的问题的一些评论和回答,我怀疑您想要实现自定义{{1} }。我认为使用UISegmentedControl来实现一点点控制并不是一个好主意,你可以在UIStackView周围发现许多项目UISegmentedControl,例如BetterSegmentedControl }:

代码示例

UIControl

图片

enter image description here

答案 1 :(得分:0)

这里的关键问题是坐标系。您正在将selectionView添加为一个按钮或另一个按钮的子视图,但由于它在两者之间移动,因此它实际上应该是两个按钮的某些祖先视图的子视图。

当您更改selectionView中心时,它会相对于其超级视图设置其位置的动画,当前代码中的位置是左按钮或右按钮。从左到右动画起作用,因为右按钮的中心是一些坐标,其x值大于selectionView在左按钮坐标空间内的值。但是当您从右侧按钮的坐标空间内的selectionView开始时,左侧按钮的中心相对于其自己的超级视图可能非常接近selectionView的中心相对于右侧按钮的坐标空间。所以没有真正的动作。

如果您这样想的话,这可能更容易想象:为了从右侧按钮的坐标空间移动到左按钮的位置,selectionView的中心x将需要是一个负数,因为它需要留在右键的前沿。但是,左侧按钮相对于其自身超级视图的中心具有正x值。因此,如果选择视图中心位于右侧按钮的坐标空间内,则将其设置为左侧按钮的中心将永远不会向左移动。

通过将选择视图添加到两个按钮所在的同一超视图中,您可以成功使用动画中的中心坐标,因为所有三个视图(2个按钮和selectionView)将位于相同的坐标空间中。

如果2个按钮位于堆栈视图中,这可能会有点麻烦,因为您不想手动设置堆栈视图排列的内容。在这种情况下,解决方案是将堆栈视图包装在普通的UIView中,并在堆栈视图前面添加selectionView,作为同一个普通UIView的子项。

只要堆栈视图框架与包含UIView的边界匹配,它仍然可以正常工作,以便在左按钮中心和右按钮中心之间为selectionView的中心设置动画。

TLDR;

使用以下视图层次结构,您的代码将起作用:

containerView
      |____ selectionView
      |____ stackView
                |_______ leftButton
                |_______ rightButton

答案 2 :(得分:0)

这是我的解决方案。 我做了以下视图和约束安排:

enter image description here

选择视图具有以下约束:

enter image description here

在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()
    }
}

此代码将输出显示为:

enter image description here

enter image description here