2013-10-08 58 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

相關問題