2013-10-08 55 views
9

我正在使用iOS 7,我试图移动一个标签,该标签位于我的视图左侧。目前我正在尝试通过更改UILabel的对齐方式来实现这一点,并且我正在尝试在此过程中对其进行设置。我目前正在呼吁以下内容:有没有办法改变一个UILabel的textAlignment动画?

[UIView animateWithDuration:0.5 
       animations:^{ 
         self.monthLabel.textAlignment = NSTextAlignmentLeft; 
       } completion:nil]; 

但是,这只是跳转到新的对齐标签。有没有一种方法来实现这个动画,或者更好的方式来调整标签以实现这一点?

回答

9

将UILabel帧大小设置为精确包含文本并将UILabel居中在您的视图中。

self.monthLabel.text = @"February"; 
[self.monthLabel sizeToFit]; 
self.monthLabel.center = parentView.center; // You may need to adjust the y position 

然后设置不应该影响布局的对齐,因为不会有额外的空间。

self.monthLabel.textAlignment = NSTextAlignmentLeft; 

接下来,将UILabel帧大小设置为动画,以便滑过您想要的位置。

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

我无法将我的框架设置为我的标签的确切尺寸,因为文字将会更改,具体以不同月份的名称为准 – lehn0058

+0

在设置文字的同时更新您的标签框。我更新了答案,以说明如何做到这一点。 – bbarnhart

+0

@bbarnhart如果标签中有两行文字,该怎么办?比这是不工作... –

1

您可以为FRAME制作动画,而不是textAlignment。

做一个[的UILabel sizeToFit]在标签上,如果你想摆脱在框架上的任何“填充”的,那么你就可以激活你的动画块框架来移动它,你的愿望

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]; 
+0

我喜欢这种方式!我确实需要让我的标签居中(现在它显示的是日历集合视图上方一个月的名称),所以我会玩这个并最初设置标签的中心,而不是尝试使用textAlignment – lehn0058

+0

如果您想要在块动画中设置变量“frameLabel”,您需要设置带有访问前缀“__block CGRect frameLabel”的变量...,因为您将在块中更改值变量frameLabel。 – horkavlna

0

你只需要动画你的标签框架。 由于此处有完成块,因此您应该再次更改帧。并使循环继续。

[UIView animateWithDuration:0.5 
       animations:^{ 
         // Change the frame 
       } completion:^{[UIView animateWithDuration:0.5 
       animations:^{ 
         // Change the frame 
       } completion:^{ 
        // repeat the proccess 
}] 

}]; 
+0

我会的,但是我在标签的两边都有填充,因为我的文本将根据用户选择的月份而改变。 – lehn0058

2

是你的标签多行吗?像这样的动画:http://img62.imageshack.us/img62/9693/t7hx.png

如果是这样,那么有几个选择。

多行Label

选项1:

取而代之的是传统的UIView动画,尝试一个UIView过渡。文字不会滑动到左侧,但它会很好地淡入新的位置。

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

选项2:

您可以手动在哪里工作的新线将出现,然后为每行文本,然后动画帧单独的UILabel。这显然是更多的工作,但会给出所需的幻灯片动画。

单行标签

相反动画的textAlignment的,使标签字符串的大小相同它包含[self.monthLabel sizeToFit],然后手动制定出框架和定心。然后对框架进行动画制作,与多行标签上的选项2相同。

0

这使我受益匪浅

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

那么你应该能够

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

有趣。你如何决定分手哪一行? – agibson007

+0

所有的行都没有突破,所以我知道前面我可以这样宣布它。更智能的解决方案将采用属性字符串并自动适当地设置换行符的动画效果。 – hfossli

相关问题