设置取决于超视图框架的约束

时间:2015-07-27 10:20:15

标签: ios uiview autolayout nslayoutconstraint

我想设置一些宽度约束,这取决于超视图宽度。实际上我想使用自动布局,但我需要访问超视图框来计算我的子视图的宽度。我的所有子视图都添加到UIView而不是视图控制器。

我在构造函数中设置了约束,但我想在updateConstraints中更改它们。

构造

nfloat initialWidth = (nfloat)Math.Round((Bounds.Size.Width / 7) - (nfloat)(Math.Ceiling(Bounds.Size.Width % 7) / 2));
container0WidthConstraint = NSLayoutConstraint.Create (container0, NSLayoutAttribute.Width, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1, initialWidth);
container1WidthConstraint = NSLayoutConstraint.Create (container1, NSLayoutAttribute.Width, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1, initialWidth);

AddConstraints (new NSLayoutConstraint[] { container0WidthConstraint, container1WidthConstraint });

updateConstraints

public override void UpdateConstraints ()
{
    nfloat desiredItemWidth = (nfloat)Math.Round(Bounds.Size.Width / 7);
    nfloat remainingWidth = Bounds.Size.Width - desiredItemWidth * 5;

    if (remainingWidth % 2 == 0) {
        // even
        container0WidthConstraint.Constant = remainingWidth / 2;
        container1WidthConstraint.Constant = remainingWidth / 2;
    } else {
        // odd
        container0WidthConstraint.Constant = (nfloat)Math.Floor(remainingWidth / 2);
        container1WidthConstraint.Constant = (nfloat)Math.Ceiling(remainingWidth / 2);
        }

    base.UpdateConstraints ();
}

代码在C#中,但我仅将其添加为附加信息。基本上,我想在相同大小的视图中划分屏幕。我找到的唯一可行方法是通过计算如上所示。

我需要Bounds.Size.Width,但在调试时它总是空的。如何设置依赖于superview框架的约束?

修改

我认为这对我不起作用的主要原因是这是作为子视图添加的,因此自动布局系统还没有完成。我应该在哪里放置layoutIfNeeded还是应该使用layoutSubviews?尝试后者时,我收到错误“执行-layoutSubviews后仍然需要自动布局”。那么我应该在哪里放置约束,或者我应该如何设置我的视图层次结构?

自动布局错误:

"<NSLayoutConstraint:0x7bd11540 H:|-(0)-[UIView:0x7bd16b90]   (Names: '|':TestSevenEquallySpaced_SevenEquallySpacedViews:0x7bd255e0 )>",
    "<NSLayoutConstraint:0x7bd11660 H:[UIView:0x7bd16b90]-(0)-[UIView:0x7bd166a0]>",
    "<NSLayoutConstraint:0x7bd114f0 H:[UIView:0x7bd166a0]-(0)-[UIView:0x7bd16a10]>",
    "<NSLayoutConstraint:0x7bd114c0 H:[UIView:0x7bd16a10]-(0)-[UIView:0x7bd163f0]>",
    "<NSLayoutConstraint:0x7bd11490 H:[UIView:0x7bd163f0]-(0)-[UIView:0x7bd15f90]>",
    "<NSLayoutConstraint:0x7bd11460 H:[UIView:0x7bd15f90]-(0)-[UIView:0x7bd15d80]>",
    "<NSLayoutConstraint:0x7bd11410 H:[UIView:0x7bd15d80]-(0)-[UIView:0x7bd15ad0]>",
    "<NSLayoutConstraint:0x7bd113e0 H:[UIView:0x7bd15ad0]-(0)-|   (Names: '|':TestSevenEquallySpaced_SevenEquallySpacedViews:0x7bd255e0 )>",
    "<NSLayoutConstraint:0x7bd115c0 UIView:0x7bd16b90.width == 0.142857*TestSevenEquallySpaced_SevenEquallySpacedViews:0x7bd255e0.width>",
    "<NSLayoutConstraint:0x7bd11820 UIView:0x7bd166a0.width == 0.142857*TestSevenEquallySpaced_SevenEquallySpacedViews:0x7bd255e0.width>",
    "<NSLayoutConstraint:0x7bd11850 UIView:0x7bd16a10.width == 0.142857*TestSevenEquallySpaced_SevenEquallySpacedViews:0x7bd255e0.width>",
    "<NSLayoutConstraint:0x7bd11880 UIView:0x7bd163f0.width == 0.142857*TestSevenEquallySpaced_SevenEquallySpacedViews:0x7bd255e0.width>",
    "<NSLayoutConstraint:0x7bd118b0 UIView:0x7bd15f90.width == 0.142857*TestSevenEquallySpaced_SevenEquallySpacedViews:0x7bd255e0.width>",
    "<NSLayoutConstraint:0x7bd11270 UIView:0x7bd15d80.width == 0.142857*TestSevenEquallySpaced_SevenEquallySpacedViews:0x7bd255e0.width>",
    "<NSLayoutConstraint:0x7bd11240 UIView:0x7bd15ad0.width == 0.142857*TestSevenEquallySpaced_SevenEquallySpacedViews:0x7bd255e0.width>",
    "<NSLayoutConstraint:0x7b8d6d60 H:|-(0)-[TestSevenEquallySpaced_SevenEquallySpacedViews:0x7bd255e0]   (Names: '|':UIView:0x7bc3e1e0 )>",
    "<NSLayoutConstraint:0x7b8ce180 H:[TestSevenEquallySpaced_SevenEquallySpacedViews:0x7bd255e0]-(0)-|   (Names: '|':UIView:0x7bc3e1e0 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x7bd018b0 h=-&- v=-&- UIView:0x7bc3e1e0.height == UIWindow:0x7bc3e710.height>",
    "<NSAutoresizingMaskLayoutConstraint:0x7bd00ea0 h=--- v=--- V:[UIWindow:0x7bc3e710(1024)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7bd11410 H:[UIView:0x7bd15d80]-(0)-[UIView:0x7bd15ad0]>

1 个答案:

答案 0 :(得分:0)

您应该将这些视图限制在视图的宽度而不是从中计算出的常量。

在Objective-c中,它看起来像

[NSLayoutConstraint constraintWithItem:container0
                             attribute:NSLayoutAtrributeWidth
                             relatedBy:NSLayoutRelationEqual
                                toItem:self
                             attribute:NSLayoutAttributeWidth
                            multiplier:(1.0f/7.0f)
                              constant:0];

这将为您提供一个始终是其超视图宽度的1/7的视图。

我在C#中猜它会是

NSLayoutConstraint.Create (container0, NSLayoutAttribute.Width, NSLayoutRelation.Equal, this, NSLayoutAttribute.Width, (1/7), 0);