2014-09-18 162 views
2

我試圖將選項卡欄從屏幕底部的下方移動到頂部,同時調整視圖的高度以縮小標籤欄的高度。實質上,我有一個「隱藏」標籤欄,當它被取消隱藏時,應該在視圖中進行動畫處理,並且displayView應該調整標籤欄現在佔用的空間。UIView子視圖不平滑地動畫

但是,動畫對於顯示視圖來說是跳動的。看起來顯示視圖動畫很好,但子視圖自動調整它們的高度而沒有任何動畫。任何方向修復這一點將不勝感激。

我會接受援助在objective-c或swift中,因爲翻譯相當簡單。

//Displays tab bar with slide up animation. If animated is false, all other params are unused 
     func displayTabBar(animated:Bool, duration:NSTimeInterval = 0.5, delay:NSTimeInterval = 0, options:UIViewAnimationOptions = UIViewAnimationOptions.CurveLinear, completion:((Bool) -> Void)? = nil){ 
      if(animated){ 
       UIView.animateWithDuration(duration, delay: delay, options: options, animations: { 
         self.adjustTabBarDisplayed() 
        }, completion: completion) 
       UIView.animateWithDuration(duration, delay: delay, options: options, animations: { 
         self.adjustDisplayViewTabDisplayed() 
        }, completion: nil) 
      } 
      else{ 
       self.adjustTabBarDisplayed() 
       self.adjustDisplayViewTabDisplayed() 
      } 

     } 

     //Adjusts frame of tab bar to display tab bar 
     private func adjustTabBarDisplayed(){ 
      self.tabBar.frame = CGRectMake(0,UIScreen.mainScreen().bounds.height - self.tabBar.bounds.height, self.tabBar.bounds.width, self.tabBar.bounds.height) 
     } 

     //Adjusts frame of display view to match displayed tab bar 
     private func adjustDisplayViewTabDisplayed(){ 
      self.displayView.frame = CGRectMake(0,0,self.displayView.bounds.width, UIScreen.mainScreen().bounds.height - self.tabBar.bounds.height) 
     } 

回答

5

當您修改視圖的大小時,它不會立即佈局它的子視圖。相反,它會設置一個標誌,指示它需要佈局。稍後,在系統完成調度事件後,系統會調用displayTabBar,它將運行顯示刷新代碼。顯示刷新代碼查找具有需要佈局標誌的視圖,並告訴它們放置(通過發送layoutSubviews)。

在這裏,您正在更改顯示視圖的大小裏面的動畫塊。因此,更改爲您的顯示視圖的框架將變爲動畫。但其子視圖的框架正在改變以外的動畫塊;他們在佈局階段後期會改變。你需要讓他們改變裏面的動畫塊。

幸運的是,這很容易。只需在動畫塊內調用self.displayView.layoutIfNeeded()即可。另外,由於所有動畫參數都相同,因此您只需要一個動畫塊:

func displayTabBar(animated:Bool, duration:NSTimeInterval = 0.5, delay:NSTimeInterval = 0, options:UIViewAnimationOptions = UIViewAnimationOptions.CurveLinear, completion:((Bool) -> Void)? = nil){ 
    if(animated){ 
     UIView.animateWithDuration(duration, delay: delay, options: options, animations: { 
       self.adjustTabBarDisplayed() 
       self.adjustDisplayViewTabDisplayed() 

       // ADD THIS LINE 
       self.displayView.layoutIfNeeded() 
      }, completion: completion) 
    } 
    else{ 
     self.adjustTabBarDisplayed() 
     self.adjustDisplayViewTabDisplayed() 
    } 
}