Пользовательский UIView не будет правильно анимироваться, когда текст меняет цвета - PullRequest
0 голосов
/ 08 января 2019

Я создал специальную кнопку-переключатель UIControl, которая предоставляет пользователю две опции: Male или Female. При выборе одного или другого цвет текста должен измениться на соответствующий противоположный цвет. Изменение цвета текста работает правильно, и переключатель переходит к другому выделению, однако при нажатии кнопки переключения анимация, показывающая его перемещение, не работает. Я пробовал несколько разных вариантов кода, но ничего не работает. Есть предложения?

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

1 Ответ

0 голосов
/ 08 января 2019

Что-то не так с вашей функцией updateView(). Эта функция вызывается каждый раз, когда вы нажимаете на кнопку, и кадр вида селектора обновляется здесь:

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

Таким образом, кадр обновляется до вызова анимации. Если положение X уже равно 0, то как анимировать движение селектора.

Итак, вы должны добавить нулевую проверку в функции updateView() и назначить кадр для просмотра только при инициализации

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))
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...