以编程方式为 uiview 设置约束以支持纵向/横向

Posted

技术标签:

【中文标题】以编程方式为 uiview 设置约束以支持纵向/横向【英文标题】:Set programatically constraints for uiview to support both portrait/landscape 【发布时间】:2016-09-19 10:13:30 【问题描述】:

我已将自己的自定义uiview 添加到self.view。由于在这种情况下我们无法在情节提要中设置约束,我尝试以编程方式添加。

关注了这个How to Create layout constraints programmatically。

我正在使用下面的代码。

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration

    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];

    [customView setNeedsUpdateConstraints];


-(void)updateViewConstraints

    UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);

[self.view addConstraints:@[

                            //view1 constraints
                            [NSLayoutConstraint constraintWithItem:customView
                                                         attribute:NSLayoutAttributeTop
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:self.view
                                                         attribute:NSLayoutAttributeTop
                                                        multiplier:1.0
                                                          constant:padding.top],

                            [NSLayoutConstraint constraintWithItem:customView
                                                         attribute:NSLayoutAttributeLeft
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:self.view
                                                         attribute:NSLayoutAttributeLeft
                                                        multiplier:1.0
                                                          constant:padding.left],

                            [NSLayoutConstraint constraintWithItem:customView
                                                         attribute:NSLayoutAttributeBottom
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:self.view
                                                         attribute:NSLayoutAttributeBottom
                                                        multiplier:1.0
                                                          constant:-padding.bottom],

                            [NSLayoutConstraint constraintWithItem:customView
                                                         attribute:NSLayoutAttributeRight
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:self.view
                                                         attribute:NSLayoutAttributeRight
                                                        multiplier:1
                                                          constant:-padding.right],

                            ]];



我从viewDidLoad 打电话给[self updateViewConstraints],但我仍然在风景中看到一半。

对此有任何想法。提前致谢。

【问题讨论】:

如果您不向我们展示您添加的约束,我们如何提供答案? @Lefteris 我添加了使用相同约束的链接。 【参考方案1】:

您可以为此目的使用Masonry。例如:

UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);

[view1 mas_makeConstraints:^(MASConstraintMaker *make) 
make.top.equalTo(superview.mas_top).with.offset(padding.top); //with is an optional semantic filler
make.left.equalTo(superview.mas_left).with.offset(padding.left);
make.bottom.equalTo(superview.mas_bottom).with.offset(-padding.bottom);
make.right.equalTo(superview.mas_right).with.offset(-padding.right);];

这将为您的视图设置顶部、右侧、底部和左侧约束。

【讨论】:

感谢您的回复。我已按照您的建议进行操作,但旋转后我仍然得到半屏。我在 viewDidLoad 中添加了这段代码。我需要添加任何东西吗? @SteveGear 尝试将其添加到 viewDidAppear 中,因为在 viewDidLoad 视图中未设置超级视图【参考方案2】:

尝试在willRotateToInterfaceOrientation:duration:call setNeedsUpdateConstraints 中查看需要更新其约束的内容。

除非未通知视图,否则它不会更新约束

【讨论】:

【参考方案3】:

如果您的约束设置正确,当用户更改方向时,视图将根据它们调整大小。 如果您向我们展示您的代码,我们将更容易为您提供帮助。

一些提示:

务必将translatesAutoresizingMaskIntoConstraints 属性设置为NO 您可以使用视觉格式来设置您的约束,有时更容易不要忘记:Visual Format Language 检查您的日志以查看约束是否未破坏

如果您的约束设置正确,则应根据其父视图框架调整视图的大小。

更新

我看到了两种可能性:要么没有真正设置约束(例如,因为没有准备好视图),要么一个或多个约束被破坏(但在这种情况下你应该看到一些日志)。

我给你一些适合我的代码(我个人尽可能使用Visual Format作为约束):

customView = [UIView new];
customView.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:customView];

UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);

NSDictionary *views = @ @"customView" : customView ;
NSDictionary *metrics = @ @"top" : @(padding.top) , @"bottom" : @(padding.bottom) , @"right" : @(padding.right) , @"left" : @(padding.left) ;
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-left-[customView]-right-|" options:0 metrics:nil views:views]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-top-[customView]-bottom-|" options:0 metrics:nil views:views]];

发生旋转时我不使用方法[customView setNeedsUpdateConstraints];:系统自行更新子视图的约束。

【讨论】:

另一个可能的原因:确保在设置约束之前已经添加了视图。更重要的是,文档告诉我们使用[NSLayoutConstraint activateConstraints:]而不是[view addConstraints:]的方法:Apple doc 两者都是相同的@Olivier 感谢您的代码。但旋转后我仍然得到半屏。:( 我上传了旋转后的图片。使用与您建议的代码相同的代码。 这很奇怪。您应该在某处有一些打破约束的代码?你没有日志吗?您是否使用情节提要来实例化您的控制器?没有看到你所有的代码,很难告诉你问题出在哪里。

以上是关于以编程方式为 uiview 设置约束以支持纵向/横向的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式创建的 UIView 的框架为 0

如何在不制作 IBOutlet 的情况下以编程方式在 Swift 中为 UIView 高度约束设置动画?

如何在显示旋转时以编程方式更改布局约束

在 Swift 中以编程方式更新约束的常量属性?

以编程方式创建的 UIView 约束,未应用锚点

如何以编程方式向以编程方式创建的 UIView 添加约束?