2017-08-19 4 views
0

Ich habe ein benutzerdefiniertes segmentiertes Steuerelement mit diesem Video erstellt (https://www.youtube.com/watch?v=xGdRCUrSu94&t=2502s). Ich möchte in der Lage sein, die Zeichenfolgenwerte, die innerhalb des benutzerdefinierten segmentierten Steuerelements (commaSeperatedButtonTitles) angezeigt werden, während der Laufzeit von 1,2,3,4 auf 5,6,7,8 zu ändern, aber aus irgendeinem Grund aktualisiert die Ansicht die Werte nicht. Die Werte scheinen in viewDidLoad geändert zu werden, aber nicht in Aktionsereignissen, was ich brauche.IBDesignbare Eigenschaften, die während der Laufzeit nicht aktualisiert werden

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


} 

-Code in-View-Controller innerhalb Aktionsereignis:

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

Antwort

1

Es scheint mir, dass updateView() Methode nicht aufgerufen wird, nachdem Sie die commaSeperatedButtonTitles Eigenschaft festgelegt. Versuchen Sie es fordern, nachdem die Eigenschaft festgelegt ist:

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

Ein weiterer erwähnenswerter Punkt: es wahrscheinlich nicht notwendig ist updateView() jedes Mal auf layoutSubviews() zu nennen, da es alle Tasten neu erstellt für die benutzerdefinierte Steuerung segmentiert.

+0

Danke, das ist seltsam, dass es nicht aufgerufen wurde. Wird das Entfernen von updateView aus layoutSubviews die Funktionalität des benutzerdefinierten Segments nicht beeinträchtigen? Vielen Dank für den Hinweis –

+0

Das Entfernen dieses 'updateView()' -Aufrufs wirkt sich wahrscheinlich nur auf das Verhalten aus, wenn Sie die 'commaSeparatedButtonTitles' nicht festlegen, nachdem das benutzerdefinierte segmentierte Steuerelement initialisiert wurde. Es hängt also davon ab, wie Sie es verwenden. Um es etwas robuster zu machen, würde ich 'commaSeparatedButtonTitles' im Initialisierer oder in der 'watchFromNib()' Methode einen Standardwert zuweisen. –

+0

macht Sinn, danke für Ihre Hilfe! –

Verwandte Themen