1

我尝试实现侧边栏菜单。我已经用标准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:我已经尝试将动画师和行为创建移动到单独的线程中,但是:

  1. 在后台线程中使用视图 - 坏主意
  2. 它只是没有帮助
4

0 回答 0