2017-08-19 58 views
0

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

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


} 

守则 - 视图 - 控制器的动作事件中:

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

回答

1

在我看来,经过您设置commaSeperatedButtonTitles属性updateView()方法不会被调用。尝试调用它的属性被设置后:

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

还有一点值得一提:它可能不需要调用每次updateView()layoutSubviews(),因为它重新创建您的自定义分段控制的所有按钮。

+0

谢谢,这是一个奇怪的是,它没有被调用。从layoutSubviews删除updateView不会影响自定义细分的功能吗?感谢您的建议 –

+0

只有在您的自定义分段控件初始化后没有设置'commaSeparatedButtonTitles',删除'updateView()'调用才可能影响行为。所以这取决于你如何使用它。为了使它更健壮一些,我会在初始化程序或'awakeFromNib()'方法中为默认值赋予'commaSeparatedButtonTitles'。 –

+0

是有道理的,谢谢你的帮助! –