2013-03-25 120 views
2

我處在一個困境,哪個方法用於設置自定義UIViews框架與許多子視圖,並仍然有動畫和自動調整旋轉。我最常做的,當我創建一個新的視圖 - 控制的頁頭中的loadView或viewDidLoad中我的自定義視圖,例如:自定義UIView佈局與方向和動畫的子視圖?

-(void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    detailView = [[DetailView alloc] initWithFrame:CGRectMake(0, 0,  self.view.frame.size.width, self.view.frame.size.height)]; 
    detailView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth; 
    self.view = detailView;  
} 

通常這個寬度&高度不爲iPhone5的屏幕正確的(實際視圖幀不設置,直到viewWillAppear),但由於autoresizingmask它一切運作。

然後在自定義的UIView的DetailView的initWithFrame,我ALLOC所有子視圖與CGRectZero,e.g:

-(id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) 
    { 
     label = [[UILabel alloc] initWithFrame:CGRectZero]; 
     [self addSubview:label]; 
    } 
} 

然後我重寫layoutsubviews設置所有子視圖的所有幀。這完全適用於任何屏幕大小和任何方向,如:

-(void)layoutSubviews 
{ 
    [super layoutSubviews]; 
    label.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height); 
} 

不過,我剛剛發現layoutSubviews不是那麼大,當你使用動畫,因爲當你在animationblock使用動畫,layoutsubviews被稱爲動畫的中間,它徹底打破了動畫,如:

-(void)animateLabel 
{ 
    [UIView animateWithDuration:0.4f animations:^ 
    { 
     label.transform = CGAffineTransformMakeTranslation(100, 100); 
    }]; 
} 

我相信有醜陋的解決方法這通過使用標誌爲每個動畫和layoutsubviews使用這些標誌設置動畫的正確的開始或endframe但我認爲我不應該爲每個我想要做的動畫創建一個標誌。

所以我的問題是現在:我應該如何有一個自定義UIView動畫,也可以自動調整自己旋轉?

我現在可以提出的唯一解決方案(我不喜歡): 不要使用layoutSubviews,而是使用自定義UIView的setFrame/setBounds方法來設置所有子視圖的框架。然後在每次發生旋轉時檢查viewController,然後使用自定義UIView的setFrame/setBounds方法更改所有子視圖的所有幀。我不喜歡這個解決方案,因爲iOS5和iOS6中的旋轉方法是不同的,我不想在每個UIViewController中都使用它自己的自定義UIView。

有什麼建議嗎?

+0

我也遇到了這個問題。你有其他正確的解決方案嗎? – ShengHuaWu 2013-10-27 15:14:34

+1

嗨盛華武,我現在做的是以下。我仍然創建一個不實現layoutsubviews的自定義子視圖。然後我在該視圖中使用自定義的setNewFrame方法,該方法是在加載視圖控制器和任何旋轉更改時設置的。在那個自定義的setNewFrame方法中,我爲那裏的所有子視圖設置了所有的框架。這種方式看起來不錯,在子視圖中的任何旋轉和動畫完美:) – 2013-10-27 17:04:49

+0

感謝您的分享。 – ShengHuaWu 2013-11-12 14:25:46

回答

0

我最近開始在我的UIViewControllers中開始覆蓋viewDidLayoutSubviews(多次代替viewWillAppear)。

是的viewDidLayoutSubviews被稱爲旋轉。 (來自評論)

在所有內部佈局已經完成之後觸發該方法,因此應該設置所有已完成的框架,但仍然會給您在視圖可見之前需要進行調整的時間,並且不應該有任何動畫問題,因爲你不在動畫塊內。

viewcontroller.m

- (void)viewDidLayoutSubViews { 
    // At this point I know if an animation is appropriate or not. 
    if (self.shouldRunAnimation) 
     [self.fuView runPrettyAnimations]; 
} 

fuView.m

- (void)runPrettyAnimations { 
    // My animation blocks for whatever layout I'd like. 
} 

- (void)layoutSubviews { 
    // My animations are not here, but non animated layout changes are. 
    // - Here we have no idea if our view is visible to the user or may appear/disappear 
    // partway through an animation. 
    // - This also might get called far more than we intend since it gets called on 
    // any frame updates. 
} 
+0

嗨DBD,謝謝你的回答。 viewDidLayoutSubviews也被稱爲輪換更改嗎?你如何建議我實施這個?通過在此方法內的自定義視圖上調用setFrame? – 2013-03-25 12:42:13

+0

我會傾向於在自定義的公共方法中對視圖進行動畫調用,這些視圖根據需要從UIViewController調用。我一直猶豫在視圖中添加自動動畫,因爲你永遠不知道視圖是否在屏幕上可見或不可見。您可能只會在動畫中途出現視圖。 – DBD 2013-03-25 14:18:20

+0

DBD,你能解釋一下你最近的評論嗎?你的意思是你不會把調用放到自定義的UIViews中去執行動畫?你能回答我的第一條評論的問題嗎? :) – 2013-03-25 14:40:02