2013-10-08 17 views
9

Ich benutze iOS 7 und ich versuche, ein Label zu verschieben, das links von meiner Ansicht zentriert ist. Momentan versuche ich dies zu tun, indem ich verändere, wie mein UILabel ausgerichtet ist, und ich versuche es dabei zu animieren. Ich rufe zur Zeit Folgendes an:Gibt es eine Möglichkeit, die textAlignment von UILabel zu animieren?

Aber das springt nur das Etikett auf die neue Ausrichtung. Gibt es eine Möglichkeit, dies zu animieren, oder eine bessere Möglichkeit, das Label anzupassen, um dies zu ermöglichen?

Antwort

9

Stellen Sie die UILabel-Rahmengröße so ein, dass sie genau den Text enthält, und zentrieren Sie das UILabel in Ihrer Ansicht.

Legen Sie dann die Ausrichtung fest, die sich nicht auf das Layout auswirken soll, da kein zusätzlicher Platz vorhanden ist.

self.monthLabel.textAlignment = NSTextAlignmentLeft; 

Als nächstes animieren die Größe UILabel Rahmen, so dass es über gleitet, wo Sie es wollen.

[UIView animateWithDuration:0.5 
      animations:^{ 
        CGRect frame = self.monthLabel.frame; 
        frame.origin.x = 10; 
        self.monthLabel.frame = frame; 
      } completion:nil]; 
+0

Ich kann meinen Rahmen nicht auf die exakte Größe meines Etiketts einstellen, da sich der Text ändert, speziell mit dem Namen verschiedener Monate. – lehn0058

+0

Aktualisieren Sie Ihren Etikettenrahmen gleichzeitig mit dem Text. Ich habe die Antwort aktualisiert, um zu zeigen, wie das geht. – bbarnhart

+0

@bbarnhart Was passiert, wenn 2 Zeilen Text im Etikett vorhanden sind? Als das funktioniert nicht ... –

1

Sie können den FRAME animieren, nicht die textAlignment.

Führen Sie eine [UILabel sizeToFit] auf dem Etikett, wenn Sie irgend „padding“ auf dem Rahmen loswerden wollen, dann können Sie den Rahmen in der Animation Block animieren sie zu bewegen, wie Sie

CGRect frameLabel = self.monthLabel.frame; 

[UIView animateWithDuration:0.5 
       animations:^{ 
         frameLabel.origin.x -= 100;   // e.g. move it left by 100 
         self.monthLabel.frame = frameLabel; 
       } completion:nil]; 
wünschen
+0

Ich mag diesen Ansatz können! Ich muss mein Label zentriert haben (momentan zeigt es den Namen eines Monats über einer Kalendersammlungsansicht an), also spiele ich damit und setze anfänglich die Mitte des Labels, anstatt zu versuchen, textAlignment – lehn0058

+0

zu verwenden, wenn du willst Setzen Sie die Variable "frameLabel" in der Blockanimation, die Sie mit dem Zugriffspräfix "__block CGRect frameLabel" einstellen müssen, weil Sie die Wertvariable frameLabel im Block ändern. – horkavlna

0

Sie müssen nur Ihren Etikettenrahmen animieren. Da hier der Completion Block drin ist solltest du den Frame nochmal ändern. und mache die Schleife los.

+0

Ich würde, aber ich habe Padding auf beiden Seiten des Etiketts, wie mein Text wird sich abhängig von dem Monat, den ein Benutzer ausgewählt hat. – lehn0058

2

Ist Ihr Etikett mehrzeilig? Eine Animation wie diese: http://img62.imageshack.us/img62/9693/t7hx.png?

Wenn ja, dann gibt es ein paar Alternativen.

mehrzeilige Label

Option 1:

Statt einer traditionellen UIView Animation, versuchen, eine UIView Übergang. Der Text wird nicht nach links verschoben, sondern stattdessen wird er an der neuen Position angezeigt.

[UIView transitionWithView:self.monthLabel 
         duration:0.5 
         options:UIViewAnimationOptionTransitionCrossDissolve 
        animations:^{ 
     self.monthLabel.textAlignment = NSTextAlignmentLeft; 
    } completion:NO]; 

Option 2:

Sie können manuell arbeiten, wo die neuen Linien erscheinen werden, dann erstellen Sie eine separate UILabel für jede Textzeile dann den Rahmen animiert. Dies ist offensichtlich mehr Arbeit, aber wird die gewünschte Folie Animation geben.

Einzeiliger Etikett

Statt die Textalignment von Animieren machen das Etikett die gleiche Größe der Zeichenfolge enthält mit [self.monthLabel sizeToFit], dann arbeiten manuell die Gestaltung und die Zentrierung aus. Dann animiere einfach den Rahmen, genauso wie Option 2 auf einem mehrzeiligen Etikett.

0

Das hat mir gut

serviert
import Foundation 
import UIKit 


class AnimatableMultilineLabel: UIView { 

    enum Alignment { 
     case left 
     case right 
    } 

    public var textAlignment: Alignment = .left { 
     didSet { 
      layout() 
     } 
    } 

    public var font: UIFont? = nil { 
     didSet { 
      setNeedsLayout() 
     } 
    } 

    public var textColor: UIColor? = nil { 
     didSet { 
      setNeedsLayout() 
     } 
    } 

    public var lines: [String] = [] { 
     didSet { 
      for label in labels { 
       label.removeFromSuperview() 
      } 
      labels = [] 
      setNeedsLayout() 
     } 
    } 

    private var labels: [UILabel] = [] 

    override init(frame: CGRect) { 
     super.init(frame: frame) 
     setup() 
    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
     setup() 
    } 

    private func setup() { 
     isUserInteractionEnabled = false 
    } 

    override func layoutSubviews() { 
     super.layoutSubviews() 

     layout() 
    } 

    private func layout() { 

     autocreateLabels() 

     var yPosition: CGFloat = 0.0 
     for label in labels { 
      let size = label.sizeThatFits(bounds.size) 
      let minX = textAlignment == .left ? 0.0 : bounds.width - size.width 
      let frame = CGRect(x: minX, y: yPosition, width: size.width, height: size.height) 
      label.frame = frame 
      yPosition = frame.maxY 
     } 
    } 

    private func autocreateLabels() { 
     if labels.count != lines.count { 
      for text in lines { 
       let label = UILabel() 
       label.font = font 
       label.textColor = textColor 
       label.text = text 
       addSubview(label) 
       labels.append(label) 
      } 
     } 
    } 

    override func sizeThatFits(_ size: CGSize) -> CGSize { 
     autocreateLabels() 

     var height: CGFloat = 0.0 
     for label in labels { 
      height = label.sizeThatFits(size).height 
     } 
     return CGSize(width: size.width, height: height) 
    } 
} 

Dann sollten Sie auf

UIView.animate(withDuration: 0.5, animations: { 
    multilineLabel.textAlignment = .right 
}) 
+0

Interessant. Wie entscheidest du, welche Zeilen du aufteilen willst? – agibson007

+0

Alle Linien waren nicht brechend, also wusste ich im Voraus, ich könnte es so erklären. Eine intelligentere Lösung würde eine attributierte Zeichenfolge verwenden und die Zeilenumbrüche ordnungsgemäß animieren. – hfossli

Verwandte Themen