IBDesignable属性在运行时期间不更新

时间:2017-08-19 17:50:46

标签: ios swift

我已使用此视频(https://www.youtube.com/watch?v=xGdRCUrSu94&t=2502s)创建了自定义分段控件。我希望能够在运行时期间将自定义分段控件(commaSeperatedButtonTitles)中显示的字符串值从1,2,3,4更改为5,6,7,8,但由于某种原因,视图不会更新值。这些值似乎可以在viewDidLoad中更改,但不能在我需要的内部动作事件中更改。

import UIKit
@IBDesignable
class CustomSegmentedControl: UIControl {

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

@IBInspectable
var borderWidth: CGFloat = 0 {
    didSet{
        layer.borderWidth = borderWidth
    }
}

@IBInspectable
var borderColor: UIColor = UIColor.gray {
    didSet{
        layer.borderColor = borderColor.cgColor
    }
}
@IBInspectable
var commaSeperatedButtonTitles: String = "" {
    didSet{

    }
}

@IBInspectable
var textColor: UIColor = .lightGray {
    didSet{
    }
}

@IBInspectable
var selectorColor: UIColor = .blue {
    didSet{

    }
}

@IBInspectable
var selectorTextColor: UIColor = .white {
    didSet{

    }
}

func updateView(){

    buttons.removeAll()
    subviews.forEach { (view) in
        view.removeFromSuperview()
    }

    var buttonTitles = commaSeperatedButtonTitles.components(separatedBy: ",")

    for buttonTitle in buttonTitles {
        let button = UIButton(type: .system)
        button.setTitle(buttonTitle, for: .normal)
        button.setTitleColor(textColor, for: .normal)
        button.addTarget(self, action: #selector(buttonTapped(button:)), for: .touchUpInside)
        buttons.append(button)
    }

    buttons[0].setTitleColor(selectorTextColor, for: .normal)

    let selectorWidth = (frame.width / CGFloat(buttonTitles.count))
    selector = UIView(frame: CGRect(x: 0, y: 0, width: selectorWidth, height: frame.height))
    selector.layer.cornerRadius = (frame.height / 2)
    selector.backgroundColor = selectorColor
    addSubview(selector)


    let sv = UIStackView(arrangedSubviews: buttons)
    sv.axis = .horizontal
    sv.alignment = .fill
    sv.distribution = .fillEqually
    addSubview(sv)

    sv.translatesAutoresizingMaskIntoConstraints = false
    sv.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
    sv.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
    sv.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
    sv.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
    self.setNeedsDisplay()
}

override func draw(_ rect: CGRect) {
    // Drawing code
    layer.cornerRadius = (frame.height / 2)
    //updateView()
}

override func layoutSubviews() {
    updateView()
}

func buttonTapped(button: UIButton){
    for (buttonIndex, btn) in buttons.enumerated() {
        btn.setTitleColor(textColor, for: .normal)
        if btn == button{
            selectedSegmentIndex = buttonIndex
            let selectorStartPosition = (frame.width / CGFloat(buttons.count) * CGFloat(buttonIndex))
            UIView.animate(withDuration: 0.3, animations: { 
                self.selector.frame.origin.x = selectorStartPosition
            })
            btn.setTitleColor(selectorTextColor, for: .normal)
        }
    }
    sendActions(for: .valueChanged)
}


}

View Controller内部动作事件中的代码:

 customSegment.commaSeperatedButtonTitles = "5,6,7,8"

1 个答案:

答案 0 :(得分:1)

在我看来,在设置updateView()属性后未调用commaSeperatedButtonTitles方法。在设置属性后尝试调用它:

@IBInspectable
var commaSeperatedButtonTitles: String = "" {
    didSet {
        self.updateView()
    }
}

值得一提的另一点是:每次updateView()都可能无需调用layoutSubviews(),因为它会重新创建自定义分段控件的所有按钮。