为啥我的约束在我的 xib 文件中不起作用

Posted

技术标签:

【中文标题】为啥我的约束在我的 xib 文件中不起作用【英文标题】:Why my constraints doesn't work in my xib file为什么我的约束在我的 xib 文件中不起作用 【发布时间】:2020-05-21 15:58:30 【问题描述】:

我正在尝试以编程方式向 UIstackview 添加一个按钮。这一切都在 fitxero XIB 中。 按钮创建正确,但添加约束时出现以下错误:

2020-05-21 17:51:08.328369+0200 eWAS[3391:567586] *** 由于未捕获的异常“NSGenericException”而终止应用程序,原因:“无法在视图上安装约束。约束是否引用了视图子树之外的某些内容? 那是违法的。约束:视图: >'

   -(void) configureTabsWithTexts: (NSArray *) tabs
    NSInteger tag = 0;

    UIButton *currentButton = [UIButton buttonWithType:UIButtonTypeSystem];
    [currentButton setTitle:@"Button1" forState:UIControlStateNormal];
    [currentButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [currentButton setTag:tag];
    [currentButton.titleLabel setFont:[UIFont systemFontOfSize:20]];
    [currentButton.titleLabel setTextColor:[UIColor whiteColor]];
    [currentButton setFrame:CGRectMake(0, 0, 30, 150)];
    currentButton.backgroundColor = [UIColor blackColor];

    [self.stackViewForButtons addSubview:currentButton];
    [currentButton setTranslatesAutoresizingMaskIntoConstraints:NO];

    NSMutableArray <NSLayoutConstraint *> *arrayConstraints = [[NSMutableArray alloc] init];

    currentButton.translatesAutoresizingMaskIntoConstraints = false;



    [currentButton addSubview:self.stackViewForButtons];

            [currentButton addConstraint: [NSLayoutConstraint constraintWithItem:currentButton
                                                           attribute:NSLayoutAttributeTop
                                                           relatedBy:NSLayoutRelationEqual
                                                           toItem:self.stackViewForButtons
                                                           attribute:NSLayoutAttributeTop
                                                          multiplier:1
                                                            constant:0]];
    [currentButton addConstraint: [NSLayoutConstraint constraintWithItem:currentButton
                                                           attribute:NSLayoutAttributeBottom
                                                           relatedBy:NSLayoutRelationEqual
                                                           toItem:currentButton.superview
                                                           attribute:NSLayoutAttributeBottom
                                                          multiplier:1
                                                            constant:0]];
    [currentButton addConstraint: [NSLayoutConstraint constraintWithItem:currentButton
                                                           attribute:NSLayoutAttributeWidth
                                                           relatedBy:NSLayoutRelationEqual
                                                           toItem:nil
                                                           attribute:NSLayoutAttributeNotAnAttribute
                                                          multiplier:1
                                                            constant:50]];

        [currentButton addConstraint: [NSLayoutConstraint constraintWithItem:currentButton
                                                               attribute:NSLayoutAttributeLeading
                                                               relatedBy:NSLayoutRelationEqual
                                                               toItem:currentButton.superview
                                                               attribute:NSLayoutAttributeLeading
                                                              multiplier:1
                                                                constant:0]];


【问题讨论】:

【参考方案1】:

你有这行:

[self.stackViewForButtons addSubview:currentButton];

这看起来不错,但后来你正在做:

[currentButton addSubview:self.stackViewForButtons];

这似乎是倒退的,可能是您问题的根源。尝试删除后一行,看看它是否有效。我怀疑您是否希望 UIButton 将堆栈视图作为子视图。两行都到位后,有一个循环引用,UIView 可能会找出并删除 UIButton 的原始超级视图,这意味着当您创建后面的约束时它为零(或者它可能完全删除超级视图/子视图关系)。

顺便说一句,如果您正在使用看起来像您的实际 UIStackView,则不需要手动完成任何这些约束。 UIStackView 的全部意义在于为您生成所有这些约束。在这种情况下,只需调用:

    [self.stackViewForButtons addArrangedSubview:currentButton];
    [currentButton setTranslatesAutoresizingMaskIntoConstraints:NO];

只要您正确配置了堆栈视图,您就应该完成了。也许你需要对每一个进行宽度限制,不确定。虽然您可以将未排列的子视图添加到 UIStackView,但这应该很少见。即使在这种情况下打算这样做,您最好添加另一个 UIStackView 作为子视图,然后向其中添加按钮。

【讨论】:

我更改了这些内容,并更改了 uiview 的堆栈视图,第一个添加子视图,第二个 setTranslatesAutoresizingMaskIntoConstraints 第三个 addconstraint 它不起作用并抛出此错误:“由于未捕获的异常而终止应用程序” NSGenericException', reason: '无法在视图上安装约束。约束是否引用了视图子树之外的东西?" 异常意味着约束上的两个项目不在同一个视图层次结构中。实际上,您需要将约束添加到两者的较高视图中——因此您需要将约束添加到堆栈视图,而不是按钮。添加到视图的约束只能引用该视图及其子视图。调用constraint.active = YES; 通常比自己添加要容易得多——激活会找到正确的视图来安装它们。

以上是关于为啥我的约束在我的 xib 文件中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

为啥捆绑包在我的 asp.net mvc 项目中不起作用?

为啥 jQuery 在我的 rails 5 应用程序中不起作用?

为啥我的 WHERE 子句在我的组合框中不起作用

为啥使用命名空间在我的 C++ 项目中不起作用?

为啥 button.click() 在我的脚本中不起作用?

为啥“发布”方法在我的 django 应用程序中不起作用?