简体   繁体   English

文本更改颜色时,自定义UIView将无法正确制作动画

[英]Custom UIView Will Not Animate Correctly When Text Is Changing Colors

I have created a toggle button that is a custom UIControl which gives the user two options -- Male or Female . 我创建了一个切换按钮,它是一个自定义UIControl ,为用户提供了两个选项MaleFemale When selecting one or the other, the text color is supposed to change to be the appropriate opposite color. 选择一个或另一个时,应将文本颜色更改为适当的相反颜色。 The text color change works correctly and the toggle moves to the other selection, however when the toggle button is clicked, the animation to show it moving doesn't work. 文本颜色更改可以正常工作,并且切换将移动到另一个选择,但是,单击切换按钮时,显示它移动的动画不起作用。 I've tried several different variations of the code but nothing works. 我尝试了几种不同的代码变体,但没有任何效果。 Any suggestions? 有什么建议么?

import UIKit

@IBDesignable
class GenderSelector: UIControl {

    var buttons = [UIButton]()
    var selector: UIView!
    var selectedSegmentIndex = 0
    var activated = false

    @IBInspectable
    var Titles: String = "" {
        didSet {
            updateView()
        }
    }

    @IBInspectable
    var textColor = UIColor(red: 29.0/255.0, green: 151.0/255.0, blue: 94.0/255.0, alpha: 1.0) {
        didSet {
            updateView()
        }
    }

    var selectedTextColor = UIColor(red: 29.0/255.0, green: 151.0/255.0, blue: 94.0/255.0, alpha: 1.0) {
        didSet {
            updateView()
        }
    }

    @IBInspectable
    var unselectedTextColor: UIColor = .white {
        didSet {
            updateView()
        }
    }

    @IBInspectable
    var selectorColor = UIColor(red: 255.0/255.0, green: 255.0/255.0, blue: 255.0/255.0, alpha: 1.0) {
        didSet {
            updateView()
        }
    }

    @IBInspectable
    var selectorTextColor: UIColor = .white {
        didSet {
            updateView()
        }
    }

    func updateView() {

        buttons.removeAll()
        subviews.forEach {
            $0.removeFromSuperview()
        }

        let buttonTitles = Titles.components(separatedBy: ",")
        for buttonTitle in buttonTitles {
            let button = UIButton(type: .system)
            button.titleLabel?.font = UIFont(name: "Avenir-Medium", size: 12)
            button.setTitle(buttonTitle, for: .normal)
            if activated == true {
                button.setTitleColor(selectedTextColor, for: .normal)
                if buttonTitle == "Male" {
                    button.setTitleColor(unselectedTextColor, for: .normal)
                }
            } else if activated == false {
                button.setTitleColor(unselectedTextColor, for: .normal)
                if buttonTitle == "Male" {
                    button.setTitleColor(selectedTextColor, for: .normal)
                }
            }

            button.addTarget(self, action: #selector(buttonTapped(button:)), for: .touchUpInside)

            buttons.append(button)
        }

        let selectorWidth = frame.width / 2
        if activated == true {
            selector = UIView(frame: CGRect(x: 152.0, y: 0, width: selectorWidth, height: frame.height))
        } else if activated == false {
            selector = UIView(frame: CGRect(x: 0.0, y: 0, width: selectorWidth, height: frame.height))
        }
        selector.layer.cornerRadius = 3
        selector.backgroundColor = selectorColor
        addSubview(selector)

        let stackview = UIStackView(arrangedSubviews: buttons)
        stackview.axis = .horizontal
        stackview.alignment = .center
        stackview.distribution = .fillEqually
        addSubview(stackview)
        stackview.translatesAutoresizingMaskIntoConstraints = false
        stackview.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
        stackview.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
        stackview.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
        stackview.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.backgroundColor = UIColor(red: 255.0/255.0, green: 255.0/255.0, blue: 255.0/255.0, alpha: 0.0)
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    override func draw(_ rect: CGRect) {
        layer.cornerRadius = 3
        layer.borderWidth = 1
        layer.borderColor = UIColor.white.cgColor
    }

    @objc func buttonTapped(button: UIButton) {
        for (buttonIndex, btn) in buttons.enumerated() {
            if btn == button {
                selectedSegmentIndex = buttonIndex
                if selectedSegmentIndex == 0 {
                    activated = false
                    updateView()
                } else if selectedSegmentIndex == 1 {
                    activated = true
                    updateView()
                }
                let selectorStartPosition = frame.width / CGFloat(buttons.count) * CGFloat(buttonIndex)
                UIView.animate(withDuration: 0.3, animations: {
                    self.selector.frame.origin.x = selectorStartPosition
                    print(selectorStartPosition)
                })
            }
        }
        sendActions(for: .valueChanged)
    }
}

There's something wrong with your updateView() function. 您的updateView()函数updateView() This function is called every time you tap on button and the frame of selector view gets updated here: 每次您单击按钮时都会调用此函数,并且选择器视图的框架在此处更新:

if activated == true {
            selector = UIView(frame: CGRect(x: 152.0, y: 0, width: selectorWidth, height: frame.height))
        } else if activated == false {
            selector = UIView(frame: CGRect(x: 0.0, y: 0, width: selectorWidth, height: frame.height))
        }

So the frame gets updated before the animation call. 因此,在进行动画调用之前会更新框架。 When X position is already 0 then how is selector movement supposed to animate. 当X位置已经为0时,选择器运动应该如何进行动画处理。

So, you should add a nil check in updateView() function and assign frame to view on initialization only 因此,您应该在updateView()函数中添加nil检查并分配帧以仅在初始化时进行查看

if selector == nil {
        if activated == true {
            selector = UIView(frame: CGRect(x: 152.0, y: 0, width: selectorWidth, height: frame.height))
        } else if activated == false {
            selector = UIView(frame: CGRect(x: 0.0, y: 0, width: selectorWidth, height: frame.height))
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM