12

我正在使用 iOS 7,我正在尝试将一个居中的标签移动到我的视图左侧。目前,我正在尝试通过更改 UILabel 的对齐方式来做到这一点,并且我正在尝试在此过程中对其进行动画处理。我目前正在调用以下内容:

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

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

4

5 回答 5

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];
于 2013-10-08T15:18:08.467 回答
5

你的标签是多行的吗?像这样的动画: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,然后为框架设置动画。这显然是更多的工作,但会提供所需的幻灯片动画。

单行标签

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

于 2013-10-09T00:01:49.157 回答
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];
于 2013-10-08T15:14:19.327 回答
0

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

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

}];
于 2013-10-08T15:16:07.667 回答
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
})
于 2017-12-18T14:53:16.970 回答