2016-07-16 16 views
1

Ich möchte eine UILabel auf die UISlider 's Daumen setzen.UISlider keine Subviews in ViewDidLoad()

Mein Code wird auf dieser Basis: Another SO question

Das Problem ist, dass mit diesem Code, dort auf dem Daumen keinen Text ist, bevor Sie den Wert zu ändern. Also habe ich ein paar Änderungen vorgenommen. Ich habe das Label zu einer globalen Variable gemacht und konfiguriere es in viewDidLoad(). Dann ändere ich einfach den Text, wenn der Schieberegler den Wert ändert.

Das eigentliche Problem ist dies (Code in viewDidLoad()):

let thumbView = mySlider.subviews.last 
label.frame = (thumbView?.bounds)! 

mySlider ‚s subviews Array ist leer. Daher erzeugt es einen Absturz, da ich einen Nullwert entpacke.

Ich verstehe nicht, warum das passiert, da die Ansicht vollständig initialisiert ist.

Warum ist mySlider.subviews leer? Was vermisse ich? Weiß jemand wie ich das beheben kann? Gibt es eine andere Möglichkeit, das Etikett in der Mitte des Daumens zu platzieren?

+0

Ihre Ansicht ist vollständig initialisiert aber Ihr Regler des Subviews nicht unbedingt. Die thumbView wird wahrscheinlich instanziiert, also wurde sie nicht in 'viewDidLoad' erstellt, da sie noch nicht aufgerufen wurde. Sie sollten den @ Zac Kwan-Vorschlag verwenden, um zu vermeiden, dass Sie die Ansichtshierarchie des Schiebereglers direkt bearbeiten müssen. – beyowulf

+0

@beyowulf Gibt es eine Möglichkeit, die Initialisierung zu erzwingen? –

Antwort

2

mySlider.subviews.last ist keine zuverlässige Methode, um die Mitte des DaumensBild zu erhalten. Es wurde nirgends in den Dokumenten erwähnt. Ich persönlich halte das für ziemlich hacky.

jedoch das Zentrum der slider erhalten Sie auf den value der slider berechnen Basis könnten einen Mähdrescher von trackRectForBounds und thumbRectForBounds verwenden.

Dies sollte für Sie arbeiten:

@IBAction func sliderValueChanged(slider: UISlider) { 
    let trackRect = slider.trackRectForBounds(slider.bounds) 
    let thumbRect = slider.thumbRectForBounds(slider.bounds, trackRect: trackRect, value: slider.value) 

    sliderLabel.center = CGPointMake(thumbRect.origin.x + thumbRect.size.width/2 + slider.frame.origin.x, slider.frame.origin.y + thumbRect.size.height/2) 
} 

Im Grunde, was das bedeutet ist, zuerst die rect der Strecke zu berechnen, dann verwenden Sie die thumbRect zu berechnen. Zuletzt stellen Sie die Mitte unter Berücksichtigung der Breite und Höhe des Schiebers und der Daumengröße ein.

Denken Sie daran, Ihre label Textausrichtung zu zentrieren.

+0

Es macht Sinn, aber es funktioniert nicht. Ich habe Ihren Code in 'viewDidLoad()' für den Anfangswert und in einer Funktion für wenn der Wert sich ändert. Die Probleme sind, dass: 1. Das Etikett ist ein bisschen über dem Daumen. 2. Das Etikett bewegt sich nicht, wenn ich den Wert ändere. – Lawrence413

+0

Ich habe ein bisschen damit herumgespielt und es geschafft, dass das Label auf dem Daumen bleibt (ich hatte den Schieberegler vorher geändert, um in Schritten zu arbeiten/auf Werte zu klicken), aber immer noch höher als der Daumen und es ist wirklich komisch. Ich habe einen anderen Schieberegler, wo der Daumen zu 160x30pts geändert wird und die Beschriftung zu dem X-Ursprung des Schiebers verbleibt. – Lawrence413

+0

Das löst die Frage des OP nicht, es ersetzt nur einen Hack, um das Center mit einem anderen zu bekommen. Das Label wird immer noch nicht angezeigt, nachdem der Slider in der 'viewDidLoad()' Methode geladen wurde, nach der das OP (und ich) suchen. –

0

Der Code von your linked question funktioniert gut, keine Notwendigkeit, das zu ändern.

diese Methode hinzufügen und der Anfangswert wird als UILabel auf UISlider erscheinen:

- (void)viewDidLayoutSubviews { 
    [super viewDidLayoutSubviews]; 

    [mySlider sendActionsForControlEvents:UIControlEventValueChanged]; 
}