UIView子视图不能平滑地动画

ste*_*ris 2 iphone objective-c uiview ios swift

我试图动画一个标签栏从屏幕底部下方移动到顶部,同时调整视图的高度以缩小标签栏的高度.基本上,我有一个"隐藏"标签栏,当它取消隐藏时应该动画到视图中,并且displayView应该调整标签栏现在占用的空间.

但是,动画对于显示视图是跳跃的.看起来显示视图动画很好,但是子视图会自动调整它们的高度而不需要任何动画.任何解决这个问题的方向都将受到赞赏.

我会接受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)
        }
Run Code Online (Sandbox Code Playgroud)

rob*_*off 6

修改视图的大小时,它不会立即显示其子视图.相反,它设置一个标志,表明它需要布局.稍后,在系统完成调度最终调用的事件后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()
    }
}
Run Code Online (Sandbox Code Playgroud)