【问题标题】:Set programatically constraints for uiview to support both portrait/landscape以编程方式为 uiview 设置约束以支持纵向/横向
【发布时间】: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 我添加了使用相同约束的链接。

标签: ios objective-c uiinterfaceorientation landscape-portrait autolayout


【解决方案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
    • 感谢您的代码。但旋转后我仍然得到半屏。:(
    • 我上传了旋转后的图片。使用与您建议的代码相同的代码。
    • 这很奇怪。您应该在某处有一些打破约束的代码?你没有日志吗?您是否使用情节提要来实例化您的控制器?没有看到你所有的代码,很难告诉你问题出在哪里。
    猜你喜欢
    • 2017-07-10
    • 1970-01-01
    • 2015-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多