更改父(UIView)大小时布局不更改

Posted

技术标签:

【中文标题】更改父(UIView)大小时布局不更改【英文标题】:Layout not changing when parent (UIView) size is changed 【发布时间】:2016-07-14 06:38:22 【问题描述】:

我有一个UIView,在这个UIView 里面我还有另一个UIView,比如说父母和孩子UIView。我在storyboard 中将父UIView 的高度和宽度设置为400,并将子视图constraint 设置为从其父视图的顶部、左右和底部获取8px 的边距。

但是当我将父视图的大小更改为 200 时,子视图的大小保持不变。我在viewdidloadviewdidappear 都试过这个

CGRect frm = self.mainTimerView.frame;
frm.size.width = size;
frm.size.height = size;
self.mainTimerView.frame = frm;

当我将父视图更改为 200 子视图时,应根据约束将其自身设置为 200-16 高度和宽度。

【问题讨论】:

您正在从“mainTimerView”获取大小,然后再次将“mainTimerView”设置为相同大小。那怎么改呢。 调用[父layoutIfNeeded] Wasim 我在第 2 行和第 3 行更改它的宽度和高度,然后再次将其分配给 mainTimerView arshadkc 我正在尝试 @Yawar 您需要为约束采取出口然后更改约束值。 【参考方案1】:

使用uiconstraint和using frame不能混用。如果想在使用uiconstraint的时候改变大小,需要先做约束的outlet,然后改变约束的constant属性。调用layoutIfNeeded,就可以得到正确的框架。

@interface ViewController ()

@property (weak, nonatomic) IBOutlet UIButton *mainTimerView;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *mainTimerViewHeightConstraint;

@end

@implementation ViewController

- (void)viewDidLoad 
    [super viewDidLoad];

    [self.view layoutIfNeeded];
    NSLog(@"%@",@(self.mainTimerView.frame.size.width));

    self.mainTimerViewHeightConstraint.constant = 100;

    [self.view layoutIfNeeded];
    NSLog(@"%@",@(self.mainTimerView.frame.size.height));


@end

调用layoutIfNeeded的目的是在绘制之前强制子视图的布局,然后viewDidLayoutSubviews会被调用。请注意,您可以在viewDidLayoutSubviews 中获得正确的帧。换句话说,你可以在调用viewDidLayoutSubviews 之后得到正确的帧。

- (void)viewDidLayoutSubviews 
    [super viewDidLayoutSubviews];
    NSLog(@"%@",NSStringFromCGRect(self.mainTimerView.frame));

【讨论】:

【参考方案2】:

1) 更改mainviewheight 约束。

2) 调用layoutIfNeeded 方法。

3) 在viewDidAppear 上做。

【讨论】:

【参考方案3】:

您是否尝试过在父视图上调用setNeedsLayout?此调用用于要求视图布局其子视图。来自setNeedsLayout's 讨论部分:

当您想要调整视图子视图的布局时,请在应用程序的主线程上调用此方法。此方法记录请求并立即返回。由于此方法不会强制立即更新,而是等待下一个更新周期,因此您可以使用它在更新这些视图中的任何一个之前使多个视图的布局无效。此行为允许您将所有布局更新合并到一个更新周期,这通常会提高性能。

致电layoutIfNeeded 可能是另一种选择。但根据文档,它强制立即布局,因此不提供使用 setNeedsLayout 获得的整合优势。

layoutIfNeeded文档:

立即布置子视图。

【讨论】:

【参考方案4】:

请创建父视图的高度约束的IBOutlet。

IBOutlet NSLayoutConstraint *RedViewHeightconstraint;

- (void)viewWillAppear:(BOOL)animated

     RedViewHeightconstraint.constant = 500;

它会为你工作

【讨论】:

【参考方案5】:

您只需要创建mainTimerView 的高度和宽度约束的IBOutlets。一旦你这样做,添加这些代码行:

constraintOuterViewHt.constant = 200 constraintOuterViewWidth.constant = 200

您无需执行任何其他操作。 Check screen shot here

【讨论】:

以上是关于更改父(UIView)大小时布局不更改的主要内容,如果未能解决你的问题,请参考以下文章

UIScrollView 不使用自动布局滚动(内容视图框架大小以编程方式更改)

当父容器视图约束以编程方式更改时,UINavigationController 子视图不调整大小

在关闭自动布局的情况下更改 UIView 的高度

如何使用自动调整大小和自动布局并更改其默认行为? [关闭]

程序化自动布局更改 UIView 的行为

如何在滚动时更改 UIView 大小并延迟