如何为分段控件选择设置动画?

问题描述 投票:0回答:1

我有一个UISegmentedControl有3种可能的选择,我在第一个选择中添加了彩色下划线条。我试图弄清楚如何设置下划线的动画,以便它移动以突出显示新的选择,但下划线栏不移动。

我不打算用动画改变索引。我试图弄清楚如何将下划线栏UIView保持在选定的同一段中。我见过这个常见的。

这是一个关于现在正在发生的事情的屏幕录制 - https://imgur.com/a/jTQ8z1M

我通过UISegmentedControl添加了Storyboard,然后在view.addSubview(underlineBar)的代码中添加了下划线。这就是我所拥有的:

    class ViewController: UIViewController {

        @IBOutlet weak var segmentedControl: UISegmentedControl!

    override func viewDidLoad() {
            super.viewDidLoad()

            setSegmentedControlStyle()   
        }

    func setSegmentedControlStyle() {
            segmentedControl.backgroundColor = .clear
            segmentedControl.tintColor = .clear
            segmentedControl.setTitleTextAttributes([NSAttributedStringKey.font : UIFont.systemFont(ofSize: 16), NSAttributedStringKey.foregroundColor: UIColor.lightGray
                ], for: .normal)
            segmentedControl.setTitleTextAttributes([NSAttributedStringKey.font : UIFont.systemFont(ofSize: 16),
                NSAttributedStringKey.foregroundColor: UIColor.blue
                ], for: .selected)

let underlineBar = UIView()
            underlineBar.translatesAutoresizingMaskIntoConstraints = false // false since we are using auto layout constraints
            underlineBar.backgroundColor = UIColor.blue
            view.addSubview(underlineBar)

            underlineBar.topAnchor.constraint(equalTo: segmentedControl.bottomAnchor).isActive = true
            underlineBar.heightAnchor.constraint(equalToConstant: 3).isActive = true
            underlineBar.leftAnchor.constraint(equalTo: segmentedControl.leftAnchor).isActive = true
            underlineBar.widthAnchor.constraint(equalTo: segmentedControl.widthAnchor, multiplier: 1 / CGFloat(segmentedControl.numberOfSegments)).isActive = true
            UIView.animate(withDuration: 0.3) {
                underlineBar.frame.origin.x = (self.segmentedControl.frame.width / CGFloat(self.segmentedControl.numberOfSegments)) * CGFloat(self.segmentedControl.selectedSegmentIndex)
            }
        }

    }

UIView.animate正在被召唤,但没有任何反应。

ios swift uisegmentedcontrol
1个回答
1
投票

问题是您正在为更新X,Y和宽度,高度属性的underlineBar设置约束,因此当您尝试为位置更改设置动画时,视图不会移动,因为约束具有更高的优先级。总之,您需要为约束设置动画。

我创建了一个全局的leftAnchor,每次按下该段时都会修改它。

var underlineBarLeftAnchor: NSLayoutConstraint!

在您设置约束的地方,使用以下方法更新函数:

underlineBar.topAnchor.constraint(equalTo: segmentedControl.bottomAnchor).isActive = true
underlineBar.heightAnchor.constraint(equalToConstant: 3).isActive = true
underlineBar.widthAnchor.constraint(equalTo: segmentedControl.widthAnchor, multiplier: 1 / CGFloat(segmentedControl.numberOfSegments)).isActive = true

underlineBarLeftAnchor = underlineBar.leftAnchor.constraint(equalTo: segmentedControl.leftAnchor, constant: 0)
underlineBarLeftAnchor.isActive = true

现在,您需要使用valueChanged常量为分段控件注册目标操作方法,如下所示,更新viewDidLoad():

override func viewDidLoad() {
    super.viewDidLoad()

    setSegmentedControlStyle()
    segmentedControl.addTarget(self, action: #selector(updateSegmentedControl), for: .valueChanged)

}

最后一步,创建updateSegmentedControl()函数,您可以在其中设置运动的动画:

每次更改段控件的值时,都会调用此函数

@objc func updateSegmentedControl() {
    let padding = underlineBar.frame.width * CGFloat(self.segmentedControl.selectedSegmentIndex)
    underlineBarLeftAnchor.constant = padding

    UIView.animate(withDuration: 0.3) {
        self.view.layoutIfNeeded()
    }
}

你需要计算你需要多少剩余填充,然后更新ui,layoutIfNeeded(),同时动画更改。

© www.soinside.com 2019 - 2024. All rights reserved.