2014-09-18 130 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() 
    } 
}