有没有办法动画更改UILabel的textAlignment?

时间:2013-10-08 15:09:02

标签: ios uiviewanimation

我正在使用iOS 7,我正在尝试移动一个位于视图左侧中心的标签。目前我试图通过改变我的UILabel的对齐方式来做到这一点,并且我正在尝试在此过程中为其设置动画。我现在打电话给以下人员:

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

但这只是将标签跳转到新的对齐方式。有没有办法为此设置动画,或者更好的方法来调整标签以实现这一目标?

5 个答案:

答案 0 :(得分:10)

将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];

答案 1 :(得分:3)

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

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

多行标签

选项1:

尝试UIView过渡,而不是传统的UIView动画。文本不会向左滑动,而是会很好地淡化到新位置。

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

选项2:

您可以手动计算出现新行的位置,然后为每行文本创建一个单独的UILabel,然后为这些帧设置动画。这显然是更多的工作,但会给出所需的幻灯片动画。

单行标签

使用 [self.monthLabel sizeToFit] 使标签与其包含的字符串大小相同,而不是动画textAlignment,然后手动计算框架和居中。然后只需为框架设置动画,与多行标签上的选项2相同。

答案 2 :(得分: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];

答案 3 :(得分:0)

您只需为标签框设置动画即可。 因为这里有完成块,你应该再次更改帧。并使循环继续。

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

}];

答案 4 :(得分: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
})