I added 1 view in XIB, it is set autolayout. But when run, i want to to change frame of that view. I know if using autolayout, need to set translatesAutoresizingMaskIntoConstraints = YES in my code. I have done that, I create new frame for that view but it shows the warning message in console:
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)
(
"<NSIBPrototypingLayoutConstraint:0x16e4b750 'IB auto generated at build time for view with fixed frame' V:|-(0)-[UIView:0x16ed3c30] (Names: '|':UIView:0x16ee06b0 )>",
"<NSAutoresizingMaskLayoutConstraint:0x16e19e30 h=-&- v=-&- UIView:0x16ed3c30.midY == UIView:0x16ee06b0.midY + 44>",
"<NSAutoresizingMaskLayoutConstraint:0x16e19e60 h=-&- v=-&- UIView:0x16ed3c30.height == UIView:0x16ee06b0.height>"
)
Will attempt to recover by breaking constraint
<NSIBPrototypingLayoutConstraint:0x16e4b750 'IB auto generated at build time for view with fixed frame' V:|-(0)-[UIView:0x16ed3c30] (Names: '|':UIView:0x16ee06b0 )>
Break on objc_exception_throw to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
This is the code for create new frame, i just want the origin of Y is equal to 0.
self.leftView.frame= CGRectMake(0, 0, 40, self.view.frame.size.height);
How can i fix that bug? Please give some advice. Thanks much.
If I understand you correctly, I think you need to use a stored NSLayoutConstraint variable in your class, then update the constraint's constant value to 0 to make your UIView slide to the top.
Also, when you're using autolayout, you usually set:
myView.translateAutoResizingMaskIntoConstraint = NO;
That's NO instead of YES.
So an example would be something like:
#interface MyViewController()
{
NSLayoutConstraint *myViewTopConstraint;
}
#end
#implementation MyViewController
-(void)setupMyConstraintsMethod
{
...
// ---------------------------------------------------------------
// This constraint here says "myView" top edge should be pinned
// to the top edge of the view controller's view but with an offset
// of 50 pixels.
// ---------------------------------------------------------------
NSLayoutConstraint *myViewTopConstraint = [NSLayoutConstraint constraintWithItem:self.myView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:50.0];
[self.view addConstraint:myViewTopConstraint];
}
-(void)buttonPressed:(id)sender
{
// ------------------------------------------------------------
// now you want myView's top edge to be at the top of your
// view controller's view, so you set the constant to 0
// ------------------------------------------------------------
myViewTopConstraint.constant = 0;
// animates the sliding up of "myView"
[UIView animateWithDuration:0.5 animations:^{
[self.view layoutIfNeeded];
}];
}
#end
Related
How is it possible to change AutoLayout Constraints during run time.
I need to change the coordinate of view during run time so i did following:
if ([OfferText length] != 0) {
cell.topContentView.translatesAutoresizingMaskIntoConstraints = YES;
CGRect newFrame = CGRectMake( 71, 4, [Util window_width]-71,50);
cell.topContentView.frame = newFrame;
}
While doing that I get following warning. Is it possible to change the auto layout constraints during run time.
(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:0x7fca729606a0 UIView:0x7fca7296c6e0.top == UITableViewCellContentView:0x7fca729712b0.topMargin + 2>",
"<NSAutoresizingMaskLayoutConstraint:0x7fca7286f620 h=--& v=--& UIView:0x7fca7296c6e0.midY == + 29>",
"<NSAutoresizingMaskLayoutConstraint:0x7fca7286f670 h=--& v=--& V:[UIView:0x7fca7296c6e0(50)]>",
"<NSAutoresizingMaskLayoutConstraint:0x7fca705c9770 h=--& v=--& 'UIView-Encapsulated-Layout-Top' V:|-(0)-[UITableViewCellContentView:0x7fca729712b0] (Names: '|':CollectionBrandCell:0x7fca72968820 )>"
)
I find my solution using following code:
in .h of tableviewcell In my case
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *constraintsTopContentView;
and in .m
if ([OfferText length] != 0) {
cell.constraintsTopContentView.constant=-4;
}
If you are setting up constraints from Storyboard, then make the outlet's of the constraints that are required to change the view's co-ordinates.
For Example:
If you want to change the top space of some view XYZ, then please do the following:
Select that view's top constraint and make outlet in .h file. This will
look like this.
#property (strong, nonatomic) NSLayoutConstraint *XYZ'stopConstraint;
Now, change this constraints constant, when you required by the following
code.
self.XYZ'stopConstraints.constant = youValue;
Also, please remove this line from your code as it is not necessary as per my view.
cell.topContentView.translatesAutoresizingMaskIntoConstraints = YES;
Create outlets for constraints you want to change (similar to UI controls); then change constant property of them.
Your warning caused because you use cell.topContentView.translatesAutoresizingMaskIntoConstraints = YES;. This will creates some new constraints (NSAutoresizingMaskLayoutConstraint) and cause conflict with olds.
Say, in the xib file I add a UIView and its width and height is fixed. No LayoutConstraint added in the xib file.I connect the UIView with an IBOutlet property "contentView", then in the viewDidLoad method I do :
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
contentView.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:contentView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0f constant:-20.0f];
[self.view addConstraint:constraint];
}
When I ran the program , it seems that constraint conflict happened, but I don not know how to solve this problem:
2014-10-14 09:37:57.436 TestAutoLayout[651:53850] Unable to simultaneously satisfy constraints.
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)
(
"<NSIBPrototypingLayoutConstraint:0x7a028de0 'IB auto generated at build time for view with fixed frame' H:|-(0)-[UIView:0x7a029380](LTR) (Names: '|':UIView:0x7a029470 )>",
"<NSIBPrototypingLayoutConstraint:0x7a028ed0 'IB auto generated at build time for view with fixed frame' H:[UIView:0x7a029380(320)]>",
"<NSLayoutConstraint:0x7a028620 UIView:0x7a029380.right == UIView:0x7a029470.right - 20>",
"<NSLayoutConstraint:0x7a02f600 'UIView-Encapsulated-Layout-Width' H:[UIView:0x7a029470(320)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7a028620 UIView:0x7a029380.right == UIView:0x7a029470.right - 20>
For some reason I have to set the constraint in program. Thanks.
So guys,
I have a profile view that contains several informations. Some of them don't have to be set e.g. Biografie. So depending if its set, I would like to hide the Biografie View (checkout screenshot) and reposition the UserData View and the ActivityData View AND change the Size of their superview to fill the space made by the Biografie View.
Here is my actual structure of my TableViewHeader:
The other point that i have to care about is that, the UILabel have to be mutliline and fit its content.
So my questions:
How do I reposition the UserData & ActivityData View to fill the
space made by the hidden BiografieView?
How do I make the Biografie
View height fit the UILabels text?
Please keep in mind that I'm using Autolayout. So I have to use constraints to modify the positions right?
To be honest.. Basically it should be like Instagram, when adding a Biografie. I hope I made it clear what I want..
Edit 1
I have tried your suggestion Damien, but nothing is changing:
NSLog(#"Height %f, Width %f", self.labelBiografie.frame.size.height, self.labelBiografie.frame.size.width);
if ([self.profileUser objectForKey:kGSUserBiografieKey]) {
self.labelBiografie.text = [self.profileUser objectForKey:kGSUserBiografieKey];
[self.labelBiografie sizeToFit];
}else{
[self.labelBiografie setHidden:YES];
[self.countContainer setConstraintConstant:-self.labelBiografie.frame.size.height forAttribute:NSLayoutAttributeCenterY];
[self.tableHeaderViewChildVIew setConstraintConstant:-self.labelBiografie.frame.size.height forAttribute:NSLayoutAttributeHeight];
self.tableView.tableHeaderView = self.tableHeaderViewChildVIew;
}
EDIT 2:
Using this Project (UIView-UpdateAutoLayoutConstraints
) I'm getting following error on the methods:
Line 56: [self hideView:hidden byAttribute:NSLayoutAttributeHeight];
Line 85: [self setConstraintConstant:0 forAttribute:attribute];
Line 23:
[self.superview addConstraint: [NSLayoutConstraint constraintWithItem:self attribute:attribute relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:constant]];
ERROR:
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:0x8c1b8e0 V:|-(0)-[UIButton:0x8c6fb40] (Names: '|':UIView:0x8c6f630 )>",
"<NSLayoutConstraint:0x8c19dc0 V:[UIButton:0x8c6fb40(100)]>",
"<NSLayoutConstraint:0x8c1d740 V:[UIButton:0x8c6fb40]-(NSSpace(8))-[UILabel:0x8c70900]>",
"<NSLayoutConstraint:0x8c20df0 V:[UILabel:0x8c70900]-(NSSpace(8))-[UIView:0x8c16a00]>",
"<NSLayoutConstraint:0x8c20fa0 V:[UIView:0x8c16a00(40)]>",
"<NSLayoutConstraint:0x8c23790 V:[UIView:0x8c16a00]-(0)-| (Names: '|':UIView:0x8c6f630 )>",
"<NSAutoresizingMaskLayoutConstraint:0x8c78e60 h=--& v=--& V:[UIView:0x8c6f630(217)]>",
"<NSLayoutConstraint:0x8c5d000 V:[UILabel:0x8c70900(0)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x8c20df0 V:[UILabel:0x8c70900]-(NSSpace(8))-[UIView:0x8c16a00]>
Break on objc_exception_throw to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
This error shows up on the Demo-Project out of the box, on my on Project it also get returned when i hide the view..
I built a category to answer to this problem I also already encountered :
Hide autolayout UIView : How to get existing NSLayoutConstraint to update this one
EDIT:
If you use autolayout, do not use view.frame any more and don't forget to set all you autolayout view like this:
myView.translatesAutoresizingMaskIntoConstraints = NO;
Using this category https://github.com/damienromito/UIView-UpdateAutoLayoutConstraints
if(!user.biografie && user.biografie.lenght == 0)
{
[biografieLabel setConstraintConstant:0 forAttribute:NSLayoutAttributeHeight];
}else
{
biografieLabel.text = user.biografie;
}
For your question two , the first solution would be to had a height constraint between the uilabel and its container's height(BiografieView) .
NSLayoutConstraint *constraint = [NSLayoutConstraint
constraintWithItem:biografieView /// change here
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:biografieLabel /// change here
attribute:NSLayoutAttributeHeight
multiplier:1
constant:0];
[view addConstraint:constraint];
Don't forget to set uilabel.numberOfLine = 0 ,
the height of this one will be automatically updated
BUT, BUT, BUT...* (better solution for your case)
If you have only one uilabel in your biografie view, remove this container. The uilabel is also a uiview, and you will not have this problem any more.
My goal is to add a logo to the bottom left corner of a UINavigationBar, and to add constraints so that it stays there upon rotation.
Here's what I've tried:
UIView* navBarView = [[self navigationController] navigationBar];
UIImageView* logoImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"asdf"]];
[navBarView addSubview:logoImageView];
NSLayoutConstraint *logoConstraintLeftAlign =
[NSLayoutConstraint constraintWithItem:logoImageView
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:navBarView
attribute:NSLayoutAttributeLeft
multiplier:1.0f
constant:0.0f];
NSLayoutConstraint *logoConstraintBottomAlign =
[NSLayoutConstraint constraintWithItem:logoImageView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:navBarView
attribute:NSLayoutAttributeBottom
multiplier:1.0f
constant:0.0f];
[navBarView addConstraint:logoConstraintLeftAlign];
[navBarView addConstraint:logoConstraintBottomAlign];
But that produces errors regarding some conflicting constraints:
2013-10-17 13:34:07.202 WTTest6[6551:a0b] Unable to simultaneously satisfy constraints.
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:0x13196350 UIImageView:0x13198280.bottom == UINavigationBar:0x9d98970.bottom>",
"<NSAutoresizingMaskLayoutConstraint:0x1318a6c0 h=--& v=--& UIImageView:0x13198280.midY == + 12>",
"<NSAutoresizingMaskLayoutConstraint:0x1318a6f0 h=--& v=--& V:[UIImageView:0x13198280(24)]>",
"<NSAutoresizingMaskLayoutConstraint:0x131aa0e0 h=-&- v=--& V:[UINavigationBar:0x9d98970(44)]>"
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x13196350 UIImageView:0x13198280.bottom == UINavigationBar:0x9d98970.bottom>
I looked at the refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints, but was a bit overwhelmed by it, as I am just working with constraints for the first time.
I tried setting the frame of the logoImageView, which worked for the default orientation. I suppose I'd have to change the frame each time the orientation changes. But that seems contrary to the point of using AutoLayout and constraints.
So my question is, Can I use constraints to anchor the view like I want, and if so, how do I avoid the NSAutoresizingMaskLayoutConstraint "problem"?
Note that I looked at Putting a custom UIView at the bottom of a UINavigationBar but that suggested using the titleView of the UINavigationBarItem, which is centered, and thus does not help with the left alignment.
Well first off, what I found is that basically ANY time I add a constraint to something and I get conflicts, it's because I did NOT add this to the object I am adding the constraint to:
[someUIView setTranslatesAutoresizingMaskIntoConstraints:NO];
DO NOT put this on the container view, just the subViews.
Set 'autoresizingMask' on 'navigationBar' subviews for your layout.
keep setTranslatesAutoresizingMaskIntoConstraints = YES on all subviews.
It works for me.
I am programatically setting the following constraints on three views inside a UIView:
UIView *view1 = ((UIViewController *)[self.viewControllers objectAtIndex:0]).view;
UIView *view2 = ((UIViewController *)[self.viewControllers objectAtIndex:1]).view;
UIView *view3 = ((UIViewController *)[self.viewControllers objectAtIndex:2]).view;
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(view1, view2, view3);
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-0-[view1(==320)]-0-[view2(==320)]-0-[view3(==320)]|" options:0 metrics:0 views:viewsDictionary]];
My intention is that each view is 320px wide, sitting flush against one-another with no gap, and view one up against the left edge of the containing UIView.
However, when compiled, the views are laid out on-top of one-another and I get the following in the console:
Unable to simultaneously satisfy constraints.
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:0x211811c0 H:|-(0)-[UIView:0xc683790] (Names: '|':UIView:0xc683320 )>",
"<NSAutoresizingMaskLayoutConstraint:0x21179820 h=-&- v=-&- UIView:0xc683790.midX == UIView:0xc683320.midX - 340>",
"<NSLayoutConstraint:0x211793d0 H:[UIView:0xc6a50c0]-(0)-| (Names: '|':UIView:0xc683320 )>",
"<NSLayoutConstraint:0x21179390 H:[UIView:0xc6a50c0(320)]>",
"<NSLayoutConstraint:0x21179350 H:[UIView:0xc6a05f0]-(0)-[UIView:0xc6a50c0]>",
"<NSLayoutConstraint:0x211563d0 H:[UIView:0xc6a05f0(320)]>",
"<NSLayoutConstraint:0x21156390 H:[UIView:0xc683790]-(0)-[UIView:0xc6a05f0]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x21179350 H:[UIView:0xc6a05f0]-(0)-[UIView:0xc6a50c0]>
Try setting
[view setTranslatesAutoresizingMaskIntoConstraints:NO];
for all of your views, it usually is enough to solve this kind of problem.