Is there a way to animate changing a UILabel's textAlignment?

后端 未结 5 555
傲寒
傲寒 2020-12-06 11:25

I am using iOS 7 and I am trying to move a label that is centered off to the left of my view. Currently I am trying to do this by changing how my UILabel is aligned, and I a

相关标签:
5条回答
  • 2020-12-06 11:42

    you just need to animate your label frame. As here completion block is there in it you should change the frame again. and make the loop going.

    [UIView animateWithDuration:0.5
                     animations:^{
                          // Change the frame
                     } completion:^{[UIView animateWithDuration:0.5
                     animations:^{
                          // Change the frame
                     } completion:^{
                         // repeat the proccess
    }]
    
    }];
    
    0 讨论(0)
  • 2020-12-06 11:48

    This has served me well

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

    Then you should be able to

    UIView.animate(withDuration: 0.5, animations: {
        multilineLabel.textAlignment = .right
    })
    
    0 讨论(0)
  • 2020-12-06 11:54

    you can animate the FRAME, not the textAlignment.

    Do a [UILabel sizeToFit] on your label if you want to get rid of any "padding" on the frame, then you can animate the frame in your animation block to move it around as you desire

    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 讨论(0)
  • 2020-12-06 12:03

    Set the UILabel frame size to exactly contain the text and center the UILabel in your view.

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

    Then set the alignment which should not affect the layout since there will be no extra space.

    self.monthLabel.textAlignment = NSTextAlignmentLeft;
    

    Next, animate the UILabel frame size so it slides over where you want it.

    [UIView animateWithDuration:0.5
                 animations:^{
                      CGRect frame = self.monthLabel.frame;
                      frame.origin.x = 10;
                      self.monthLabel.frame = frame;
                 } completion:nil];
    
    0 讨论(0)
  • 2020-12-06 12:06

    Is your label multiline? An animation like this: http://img62.imageshack.us/img62/9693/t7hx.png?

    If so, then there's a couple of alternatives.

    Multiline label

    Option 1:

    Instead of a traditional UIView animation, try a UIView transition. The text wont slide to the left, but instead it will fade nicely to the new position.

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

    Option 2:

    You can manually work out where the new lines will appear, then create a separate UILabel for each line of text then animate the frames. This is obviously more work, but will give that desired slide animation.

    Single line label

    Instead of animating the textAlignment, make the label the same size of the string it contains with [self.monthLabel sizeToFit], then manually work out the framing and the centering. Then just animate the frame, the same as option 2 on a multiline label.

    0 讨论(0)
提交回复
热议问题