我已使用此视频(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"
答案 0 :(得分:1)
在我看来,在设置updateView()
属性后未调用commaSeperatedButtonTitles
方法。在设置属性后尝试调用它:
@IBInspectable
var commaSeperatedButtonTitles: String = "" {
didSet {
self.updateView()
}
}
值得一提的另一点是:每次updateView()
都可能无需调用layoutSubviews()
,因为它会重新创建自定义分段控件的所有按钮。