ios - 可能至少以下列表中的约束之一是您不想要的

标签 ios autolayout

我是自动布局编程的新手。我正在尝试制作一个在单击按钮时显示/隐藏的 View (按钮)。我能够实现我的目标,但它引发了异常。

这是我的代码:

@interface RootViewController ()
{
    NSArray *hiddenState;
    NSArray *visibleState;
    NSArray *verticalState;
    UIButton *btnLeft;
}

- (void)viewDidLoad 
{
    [super viewDidLoad];
    btnLeft = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    btnLeft.backgroundColor = [UIColor greenColor];
    btnLeft.translatesAutoresizingMaskIntoConstraints = NO;
    btnLeft.selected = NO;
    [self.view addSubview:btnLeft];
    NSString *verticalConstraint = @"V:|[v]|";
    NSMutableDictionary *views = [NSMutableDictionary new];
    views[@"v"] = btnLeft;
    views[@"superview"] = self.view;
    if ([self respondsToSelector:@selector(topLayoutGuide)]) {
        views[@"topLayoutGuide"] = self.topLayoutGuide;
        verticalConstraint = @"V:|[topLayoutGuide][v]|";
    }

    verticalState = [NSLayoutConstraint constraintsWithVisualFormat:verticalConstraint options:0 metrics:nil views:views];
    hiddenState = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[v(==0)]|" options:0 metrics:nil views:views];
    visibleState = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[v]-50-|" options:0 metrics:nil views:views];
    [self.view addConstraints:verticalState];
    [self.view addConstraints:hiddenState];
}

- (IBAction)leftButtonAction:(id)sender
{
    UIButton *btn = (UIButton *)sender;
    if (btn.selected)
    {
        [self.view removeConstraints:visibleState];
        [self.view addConstraints:hiddenState];
        [UIView animateWithDuration:0.5 animations:^{

            [self.view layoutIfNeeded];

        } completion:^(BOOL finished) {
            btn.selected = NO;
        }];
    }
    else
    {
        [self.view removeConstraints:hiddenState];
        [self.view addConstraints:visibleState];
        [UIView animateWithDuration:0.5 animations:^{

            [self.view layoutIfNeeded];

        } completion:^(BOOL finished) {
            btn.selected = YES;
        }];
    }
}

这会引发以下异常:

Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)

(
    "<NSLayoutConstraint:0x7d24d380 H:|-(0)-[UIButton:0x7bf58f70]   (Names: '|':UIView:0x7bf4c080 )>",
    "<NSLayoutConstraint:0x7d245de0 H:[UIButton:0x7bf58f70(0)]>",
    "<NSLayoutConstraint:0x7d245e10 H:[UIButton:0x7bf58f70]-(0)-|   (Names: '|':UIView:0x7bf4c080 )>",
    "<NSLayoutConstraint:0x7d2ad6f0 'UIView-Encapsulated-Layout-Width' H:[UIView:0x7bf4c080(320)]>"
)

Will attempt to recover by breaking constraint

<NSLayoutConstraint:0x7d245e10 H:[UIButton:0x7bf58f70]-(0)-|   (Names: '|':UIView:0x7bf4c080 )>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in may also be helpful.

当我试图使按钮宽度等于零时它抛出异常。

最佳答案

考虑错误消息中的前三个约束:

H:|-(0)-[UIButton:0x7bf58f70]   (Names: '|':UIView:0x7bf4c080 )
H:[UIButton:0x7bf58f70(0)]
H:[UIButton:0x7bf58f70]-(0)-|   (Names: '|':UIView:0x7bf4c080 )

您的 H:|[v(==0)]| 格式字符串创建了这三个约束。我们可以将它们写成这样的等式:

(1) superview.leading == button.leading
(2) button.leading == button.trailing
(3) button.trailing == superview.trailing

将 (2) 代入 (1) 得到:

(4) superview.leading == button.trailing

然后将 (3) 代入 (4) 得到:

(5) superview.leading == superview.trailing

这意味着父 View 的宽度必须为 0。

现在考虑错误消息中的最后一个约束:

 H:[UIView:0x7bf4c080(320)]

系统添加了这个约束,大概是因为这是 Root View Controller 的 View ,因此调整大小以填充屏幕。此约束表示父 View 的宽度必须为 320。这与等式 (5) 冲突。这就是您收到错误的原因。

我假设您希望按钮固定在父 View 的左边缘,因为您已将其命名为 btnLeft。所以试试这些约束:

hiddenState = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[v(==0)]" options:0 metrics:nil views:views];
visibleState = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[v]" options:0 metrics:nil views:views];

关于ios - 可能至少以下列表中的约束之一是您不想要的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26236893/

相关文章:

ios - 第一个单元格顶部的 tableHeaderView

ios - 我怎样才能从 NSUrlSession 返回一个 NSHttpUrlResponse 状态码

iphone - cocos2dx ios Sprite 坐标和大小错误

ios - 使用 firebase 时 iOS 中的权利问题

ios - 更改 UITableView 框架时奇怪的 UITableViewCell 动画

cocoa - 使用自动布局扩展 NSTextView

ios - Storyboard和可扩展的 textView

ios - 例如,如何制作一个保持按钮来录制音频? (快速)

iOS - 将 subview 宽度设置为与父 View 相同(objective-c)

ios - UICollectionViewFlowLayout 的行为未定义