我尝试实现侧边栏菜单。我已经用标准UIView
动画完成了它,但现在我想给它添加一些感觉。我决定使用UIViewDynamics
. 我注意到,在主视图框架更改后,有必要重新创建UIViewAnimator
和所有行为。
我通常使用layoutSubviews
视图的方法。但在那种情况下,我的控制器继承了UINavigationController
它,我无法覆盖它的视图,所以我使用了控制器生命周期方法。
为避免意外结果,首先我删除方法中的所有动画师行为viewWillLayoutSubviews
。之后,最后viewDidLayoutSubviews
我创建了一个动画师和行为(重力、项目、推动、碰撞)。
效果很好,但是当layoutSubviews
触发时,它会有些滞后(看起来像低 fps)。
一些代码:
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
if (_animator) {
[_animator removeAllBehaviors];
_animator = nil;
}
}
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
[self configSubviewFrames];
[self configAnimator];
}
- (void)configSubviewFrames
{
CGFloat offset = [UIApplication sharedApplication].isStatusBarHidden ? 0 : _statusBarHeight;
CGRect drawerFrame, protectionFrame, unusedFrame;
CGRectDivide(self.view.frame, &drawerFrame, &unusedFrame, _drawerWidth, CGRectMinXEdge);
protectionFrame= self.view.frame;
if (!_isMenuShown) {
drawerFrame.origin.x -= _drawerWidth;
}
drawerFrame.origin.y += offset;
drawerFrame.size.height -= offset;
protectionFrame.origin.y += offset;
protectionFrame.size.height -= offset;
_drawerView.frame = drawerFrame;
_protectionView.frame = protectionFrame;
}
- (void)configAnimator
{
_animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
_collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[_drawerView]];
_itemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[_drawerView]];
_gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[_drawerView]];
_pushBehavior = [[UIPushBehavior alloc] initWithItems:@[_drawerView] mode:UIPushBehaviorModeInstantaneous];
_itemBehavior.allowsRotation = NO;
_itemBehavior.elasticity = kDrawerElacity;
_gravityBehavior.gravityDirection = CGVectorMake(_isMenuShown ? 1.0f : -1.0f, 0.0f);
_pushBehavior.magnitude = 0.0f;
_pushBehavior.angle = 0.0f;
_collisionBehavior.collisionDelegate = self;
[_collisionBehavior setTranslatesReferenceBoundsIntoBoundaryWithInsets:UIEdgeInsetsMake(0, - _drawerWidth, 0, self.view.frame.size.width - _drawerWidth)];
[self addInititalBihaviors];
}
- (void)addInititalBihaviors
{
[_animator addBehavior:_collisionBehavior];
[_animator addBehavior:_pushBehavior];
[_animator addBehavior:_gravityBehavior];
[_animator addBehavior:_itemBehavior];
}
希望您能提供帮助,并随时提出任何相关问题。谢谢。
应用程序在屏幕旋转时消耗 9-12 % cpu。
PS:我已经尝试将动画师和行为创建移动到单独的线程中,但是:
- 在后台线程中使用视图 - 坏主意
- 它只是没有帮助