UIPresentationController preferredContenteSize更新动画

时间:2015-11-27 16:00:21

标签: ios animation uikit uipresentationcontroller

所以我有一个非常基本的UIPresentationController,它基本上以屏幕为中心显示contentView,它的大小由视图控制器preferredContentSize决定。 (它非常类似于常规模态视图控制器,以FormSheet形式呈现)。

我想要实现的是,只需更改它的preferredContentSize,即可动态更新此视图控制器视图的大小。

当我设置preferredContentSize时,我的UIPresentationController子类在以下位置接收有关它的信息:

-(void)preferredContentSizeDidChangeForChildContentContainer:(id<UIContentContainer>)container

但是我怎么能从这里用动画调整视图框架的大小呢?如果我打电话:

-(void)preferredContentSizeDidChangeForChildContentContainer:(id<UIContentContainer>)container
{
    [UIView animateWithDuration:1.0 animations:^{
        self.presentedView.frame = [self frameOfPresentedViewInContainerView];
    } completion:nil]; 
}

Immidiately被称为containerViewWillLayoutSubviews,框架在没有动画的情况下被更改。

-(void)containerViewWillLayoutSubviews
{
    self.presentedView.frame = [self frameOfPresentedViewInContainerView];
}

请帮助我找到一种方法,用动画调整大小。它必须是可能的,因为它会在动画时调整大小,例如旋转发生时。

2 个答案:

答案 0 :(得分:2)

您必须使用自动布局。根据容器高度约束建立一个出口:

@property (nonatomic, strong, readwrite) IBOutlet NSLayoutConstraint *drawerViewHeightConstraint;

然后添加以下代码:

- (void)preferredContentSizeDidChangeForChildContentContainer:(id<UIContentContainer>)container
{
    [super preferredContentSizeDidChangeForChildContentContainer:container];
    self.drawerViewHeightConstraint.constant = container.preferredContentSize.height;

    [UIView animateWithDuration:0.25
                     animations:^{
                       [self.view layoutIfNeeded];
                     }];
}

答案 1 :(得分:0)

您无需在preferredContentSizeDidChangeForChildContentContainer内设置框架,只需在容器视图上调用setNeedsLayoutlayoutIfNeeded。 这将导致containerViewWillLayoutSubviews被调用,这将使用您的动画配置来更新帧。

Objective-C:

- (void)preferredContentSizeDidChangeForChildContentContainer:(id<UIContentContainer>)container
{
    [UIView animateWithDuration:1.0 animations:^{
        [self.containerView setNeedsLayout];
        [self.containerView layoutIfNeeded];
    } completion:nil]; 
}

快捷键:

override func preferredContentSizeDidChange(forChildContentContainer container: UIContentContainer) {
    super.preferredContentSizeDidChange(forChildContentContainer: container)
    
    guard let containerView = containerView else {
        return
    }
    
    UIView.animate(withDuration: 1.0, animations: {
        containerView.setNeedsLayout()
        containerView.layoutIfNeeded()
    })
}

替代方法

或者,您无法在preferredContentSizeDidChange...中设置动画块,而将preferredContentSize的分配放在动画块中。

这样,您可以更好地控制各个转场的动画速度。

Objective-C:

- (void)preferredContentSizeDidChangeForChildContentContainer:(id<UIContentContainer>)container
{
    [self.containerView setNeedsLayout];
    [self.containerView layoutIfNeeded];
}

// In view controller:

[UIView animateWithDuration:0.25 animations:^{
    self.preferredContentSize = CGSizeMake(self.view.bounds.width, 500.f);
}];

快捷键:

override func preferredContentSizeDidChange(forChildContentContainer container: UIContentContainer) {
    super.preferredContentSizeDidChange(forChildContentContainer: container)
    
    guard let containerView = containerView else {
        return
    }
    
    containerView.setNeedsLayout()
    containerView.layoutIfNeeded()
}

// In view controller

UIView.animate(withDuration: 0.25) {
    self.preferredContentSize = CGSize(width: self.view.width, height: 500)
}