且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

以编程方式设置约束

更新时间:2022-04-18 22:06:36

根据对您的代码的评论,一些评论:

Based upon a review of your code, a few comments:


  1. 您通常不会当视图出现时,需要调整约束。如果您发现自己这样做,通常意味着您没有正确配置故事板(或者至少没有高效配置)。你真正需要设置/创建约束的唯一时间是(a)你是以编程方式添加视图(我建议的是更多的工作而不是它的价值);或者(b)您需要对约束进行一些运行时调整(参见下面第3点下的第三个项目符号)。

  1. You generally don't need to adjust constraints when a view appears. If you find yourself doing this, it often means that you haven't configured your storyboard correctly (or at least, not efficiently). The only time you really need to set/create constraints is either (a) you're adding views programmatically (which I'm suggesting is more work than it's worth); or (b) you need to do some runtime adjustment of constraints (see third bullet under point 3, below).

我不是故意要对它进行处理,但你的项目有一堆冗余代码。例如

I don't mean to belabor it, but your project had a bunch of redundant code. E.g.


  • 您正在设置滚动视图的框架,但这受到约束的约束,因此不执行任何操作(即,应用约束后,将替换任何手动设置的 frame 设置。通常,在自动布局中,不要尝试直接更改 frame :编辑约束。但是,无论如何都不需要改变约束,所以关键是没有实际意义。

  • You were setting the frame for the scroll view, but that is governed by constraints, so that does nothing (i.e. when the constraints are applied, any manually set frame settings will be replaced). In general, in auto layout, don't try changing frame directly: Edit the constraints. But, no changing of constraints is needed at all anyway, so the point is moot.

您正在设置滚动视图的内容大小,但在auto中布局,也受到(子视图)约束的约束,因此这是不必要的。

You were setting the content size for the scroll view, but in auto layout, that, too, is governed by constraints (of the subviews), so that was unnecessary.

您正在设置scrollview的约束(已经为零),但是您没有将NIB中的视图添加到scrollview中,从而击败了任何意图也在那里。最初的问题是如何更改滚动视图的底部约束。但是它的底部约束已经为零,所以我认为没有理由再将其设置为零。

You were setting constraints for the scrollview (which were already zero), but then you weren't adding the view from the NIB into the scrollview, defeating any intent there, too. The original question was how to change the bottom constraint of the scroll view. But the bottom constraint for that is already zero, so I see no reason to set it to zero again.

我建议对你的项目进行更彻底的简化:

I'd suggest a more radical simplification of your project:


  • 你通过存储使自己的生活变得更加困难您对NIB的看法。如果你留在故事板世界里会更容易。如果你真的需要,我们可以帮助你做NIB的事情,但是为什么要让自己的生活变得如此艰难?

  • You're making life much harder on yourself by storing your views in NIBs. It's much easier if you stay within the the storyboard world. We can help you do the NIB stuff if you really need to, but why make life so hard on yourself?

使用细胞原型来促进设计你桌子上的细胞。您还可以定义从单元格到下一个场景的segue。这消除了编写任何 didSelectRowAtIndexPath prepareForSegue 代码的任何需要。显然,如果你有什么需要传递到下一个场景,一定要使用 prepareForSegue ,但到目前为止你所提出的并不需要,所以我评论过在我的示例中。

Use cell prototypes to facilitate the design of the cells in your table. You can also define the segues to go from the cells to the next scene. This eliminates any need to write any didSelectRowAtIndexPath or prepareForSegue code. Clearly, if you have something you need to pass to the next scene, by all means use prepareForSegue, but nothing you've presented thus far requires that, so I've commented it out in my examples.

假设您正在寻找以编程方式更改约束的实际示例,我已设置场景以便文本视图将根据文本视图中的文本以编程方式更改其高度。与往常一样,在改变IB为我创建的现有约束时,不是迭代约束来找到有问题的约束,我认为设置 IBOutlet 更有效率>对于约束,并直接编辑约束的常量属性,这就是我所做的。所以我将视图控制器设置为文本视图的委托,并编写了一个 textViewDidChange ,它更新了文本视图的高度约束:

Assuming you were looking for a practical example of programmatically changing constraints, I've set up the scene so that the text view will change its height programmatically, based upon the text in the text view. As always, rather than iterating through the constraints to find the one in question, when altering an existing constraint that IB created for me, I think it's far more efficient to set up an IBOutlet for the constraint, and edit the constant property for the constraint directly, so that's what I've done. So I set up the view controller to be the delegate of the text view, and wrote a textViewDidChange that updated the text view's height constraint:

#pragma mark - UITextViewDelegate

- (void)textViewDidChange:(UITextView *)textView
{
    self.textViewHeightConstraint.constant = textView.contentSize.height;
    [self.scrollView layoutIfNeeded];
}

注意,我的文本视图有两个高度限制,一个强制性的最小高度约束,以及我根据文本数量改变的中等优先级约束。重点是它说明了以编程方式更改约束的实际示例。您根本不应该使用scrollview的底部约束,但这显示了您可能想要调整约束的实际示例。

Note, my text view has two height constraints, a mandatory minimum height constraint, and a medium priority constraint that I change above based upon the amount of text. The main point is that it illustrates a practical example of changing constraints programmatically. You shouldn't have to muck around with the scrollview's bottom constraint at all, but this is shows a real-world example of when you might want to adjust a constraint.






在IB中添加滚动视图时,它会自动获取所有约束你需要。您可能不希望以编程方式添加约束(至少在没有删除现有底部约束的情况下)。


When you add a scrollview in IB, it will automatically get all the constraints you need. You probably don't want to be adding a constraint programmatically (at least not without removing the existing bottom constraint).

两种方法可能更简单:


  1. 为现有的底部约束创建 IBOutlet ,例如 scrollViewBottomConstraint 。然后你可以做到

  1. Create an IBOutlet for your existing bottom constraint, say scrollViewBottomConstraint. Then you can just do

self.scrollViewBottomConstraint.constant = 0.0;


  • 或者最初在IB中创建您的视图,其中底部约束为0.0然后您不要必须以编程方式执行任何操作。如果要布置长滚动视图及其子视图,请选择控制器,将其模拟指标从推断设置为***形式。然后,您可以更改视图的大小,将scrollview的顶部和底部约束设置为零,在滚动视图中布置所需的所有内容,然后在运行时显示视图时,视图将适当调整大小,并且因为您已经将scrollview的顶部和底部约束定义为0.0,它将被正确调整大小。在IB中看起来有点奇怪,但它在应用程序运行时就像魅力一样。

  • Or create your view initially in IB where the bottom constraint is 0.0 and then you don't have to do anything programmatically at all. If you want to layout a long scrollview and it's subviews, select the controller, set it's simulated metrics from "inferred" to "free form". Then you can change the size of the view, set the scrollview's top and bottom constraints to be zero, layout everything you want inside the scroll view, and then when the view is presented at runtime, the view will be resized appropriately, and because you've defined the scrollview's top and bottom constraints to be 0.0, it will be resized properly. It looks a bit odd in IB, but it works like a charm when the app runs.

    如果您决定添加新约束,则可以以编程方式删除旧的底部约束,或者将旧的底部约束的优先级设置为尽可能低,这样您的新约束(具有更高优先级)将优先,并且旧的,低优先级底部约束将优雅地不是应用。

    If you're determined to add a new constraint, you could either programmatically remove the old bottom constraint, or set the old bottom constraints' priority down as low as possible, and that way your new constraint (with higher priority) will take precedence, and the old, low-priority bottom constraint will gracefully not be applied.

    但你绝对不想只添加新的约束。

    But you definitely don't want to just add a new constraint.