5

所以我有一个非常基本的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]; 
}

立即被调用 containerViewWillLayoutSubviews 并且框架在没有动画的情况下被更改。

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

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

4

2 回答 2

1

而不是从内部设置框架preferredContentSizeDidChangeForChildContentContainer,您只需要在容器视图上调用setNeedsLayout和。layoutIfNeeded这会导致containerViewWillLayoutSubviews被调用,这将使用您的动画配置更新帧。

目标-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()
    })
}

替代方法

或者,您不能将 animate 块放在 中preferredContentSizeDidChange...,而是将 的分配preferredContentSize放在 animate 块中。

通过这种方式,您可以更好地控制各个过渡的动画速度。

目标-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)
}
于 2020-07-03T17:55:06.263 回答
1

您必须使用自动布局。从您的容器高度约束中创建一个出口:

@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];
                     }];
}
于 2016-05-30T10:19:32.870 回答