Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/122.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 是否有一种方法可以设置更改UILabel';文本对齐?_Ios_Uiviewanimation - Fatal编程技术网

Ios 是否有一种方法可以设置更改UILabel';文本对齐?

Ios 是否有一种方法可以设置更改UILabel';文本对齐?,ios,uiviewanimation,Ios,Uiviewanimation,我正在使用iOS 7,我正在尝试将一个标签移到视图左侧的中心位置。目前,我正试图通过改变UILabel的对齐方式来实现这一点,并试图在这个过程中设置它的动画。我目前正在拨打以下电话: [UIView animateWithDuration:0.5 animations:^{ self.monthLabel.textAlignment = NSTextAlignmentLeft; } c

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

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

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

您可以设置帧动画,而不是文本对齐

如果要消除帧上的任何“填充”,请在标签上执行[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];

您只需要设置标签帧的动画。 因为这里有一个完成块,所以你应该再次更改帧。让循环继续

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

}];

将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:

尝试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相同。

这对我很有用

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

我无法将框架设置为标签的确切大小,因为文本将发生变化,特别是不同月份的名称。请在设置文本的同时更新标签框架。我更新了答案以说明如何执行此操作。@bbarnhart如果标签中有两行文本怎么办?这是行不通的…我会的,但我在标签的两边都有填充,因为我的文本会根据用户选择的月份而变化。我喜欢这种方法!我确实需要让我的标签居中(现在它在日历集合视图上方显示一个月的名称),因此我将使用它并首先设置标签的中心,而不是尝试使用TextAlignment如果要在块动画中设置变量“frameLabel”,则需要使用access前缀设置变量“_block CGRect frameLabel”…,因为您将更改块中的值变量frameLabel。有趣的是,您如何决定要拆分哪些行?所有行都是非拆分的,因此我事先就知道我可以这样声明。更聪明的解决方案是使用属性字符串并自动正确设置拆分行的动画。