I want to set up some width constraints, which depends on the superview width. In fact I want to use auto layout but I need to access the superviews frame to calculate the width of my subviews. All my subviews are added to a UIView
not a view controller.
I set up the constraints in the constructor, but I want to change them in updateConstraints
.
Constructor:
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 ();
}
The code is in C# but I added this only as additional information. Basically, I want to divide the screen in equally sized views. The only way I found which can work is through calculating as seen above.
I need the Bounds.Size.Width
but it is always empty when I debug. How can I add constraints which depends on the frame of the superview once it is set?
Edit:
I think the main reason why this doesn't work for me is that this is added as subview and therefore the auto layout system has not finished yet. Where should I place layoutIfNeeded
or should I use layoutSubviews
? When trying the latter one I get the error "Auto Layout still required after executing -layoutSubviews". So where should I place my constraints or how should I set up my view hierarchy?
Auto layout error:
"<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]>
You should just constrain these views to your view's width rather than a constant calculated from it.
in Objective-c it would look like
[NSLayoutConstraint constraintWithItem:container0
attribute:NSLayoutAtrributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeWidth
multiplier:(1.0f/7.0f)
constant:0];
This would get you a view which is always 1/7 of the width of its superview.
I am guessing in C# it would be
NSLayoutConstraint.Create (container0, NSLayoutAttribute.Width, NSLayoutRelation.Equal, this, NSLayoutAttribute.Width, (1/7), 0);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.