UIView的框架在初始加载时被Storyboard覆盖

时间:2013-12-10 16:57:58

标签: uiview ios7 xcode5

我需要根据可用磁盘空间更改子视图的宽度。所以我有一个选择器,它被调用视图控制器的viewWillLayoutSubviews:

CGRect rect = self.usageView.bounds;
rect.size.width = self.someCalculatedwidth;
[self.usageView setFrame:rect];
[self.usageView setNeedsDisplay];

真的,我只是想改变子视图的宽度。如果视图控制器是初始控制器,它可以工作;但是,如果它从Push Segue转变而停止工作。发生的事情是我看到我想要的宽度暂时渲染,然后根据故事板上的蓝图将其更改为原始宽度。

行为感觉就像iOS在推送segue动画期间缓存块中的原始(故事板)视图一样,并且在完成时它执行上面没有我的计算的块;从而超越了理想的观点。有什么想法吗?

1 个答案:

答案 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];
}];