我需要根据可用磁盘空间更改子视图的宽度。所以我有一个选择器,它被调用视图控制器的viewWillLayoutSubviews:
CGRect rect = self.usageView.bounds;
rect.size.width = self.someCalculatedwidth;
[self.usageView setFrame:rect];
[self.usageView setNeedsDisplay];
真的,我只是想改变子视图的宽度。如果视图控制器是初始控制器,它可以工作;但是,如果它从Push Segue转变而停止工作。发生的事情是我看到我想要的宽度暂时渲染,然后根据故事板上的蓝图将其更改为原始宽度。
行为感觉就像iOS在推送segue动画期间缓存块中的原始(故事板)视图一样,并且在完成时它执行上面没有我的计算的块;从而超越了理想的观点。有什么想法吗?
答案 0 :(得分:2)
有两种方法。
第一种方法是为了避免这个问题,并带来酷炫动画的附带好处。由于我不知道iOS何时或多少次或确切地如何强制执行自动约束,我只是简单地延迟我的UIView修改并使用动画来平滑它。所以我在我的选择器中围绕代码包装视图动画:
[UIView animateWithDuration:.25 animations:^{
CGRect rect = self.usageView.bounds;
rect.size.width = self.someCalculatedwidth;
[self.usageView setFrame:rect];
[self.usageView setNeedsDisplay];
}];
然后我会在我的控制器的viewDidAppear:animated:
中调用我的选择器[self performSelector:@selector(resetUsageView) withObject:self afterDelay:0.0];
现在大多数人会说这是一个警察或者一个垃圾。这很公平。
在第二种方法中,我攻击了问题的根源 - 自动布局/约束。我在故事板中为usageView添加了Width约束,并将其IBOutlet连接到我的代码。
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *usageViewWidthConstraint;
然后我根据控制器viewWillAppear中的计算宽度修改约束:animated:
[self.usageViewWidthConstraint setConstant:self.someCalculatedWidth];
瞧!一个班轮。
现在如果我想要动画,我从第一种方法中尝到了它怎么样?那么,约束变化不在动画领域之内,所以基本上我需要第一种和第二种方法的组合。我更改了动画的UIView框架,并修改约束以“直接设置记录”:
[UIView animateWithDuration:.25 animations:^{
CGRect rect = self.usageView.bounds;
rect.size.width = self.someCalculatedwidth;
[self.usageView setFrame:rect];
[self.usageViewWidthConstraint setConstant:self.someCalculatedWidth]; // <<<<
[self.usageView setNeedsDisplay];
}];