I have a image view with following constraints
height constraint = 250,
width constraint = 250,
leadingSpace constraint = 159 (on iPhone long screen)
and
topSpace constraint = 10
View is in landscape mode.
attached the leading space constraint in .h via the following code
IBOutlet (retain, nonatomic) NSLayoutConstraint *leadingSpaceConstraint;
Now, when I run the following code in viewDidLoad or viewDidAppear, the constraint doesn't update
self.leadingSpaceConstraint.constant = 100; //new value;
[self.view layoutIfNeeded]; //I also tried the iboutlet for the imageView and running this line on it, but no updates.
How to update? What am I missing?
You need to put autolayout code in viewDidLayoutSubviews
Related
So I'm new to the constraints.
I've a nib file which contains multiple Views as siblings. The ViewController's view contains a tableView and I've another view which is going to be added to the tableHeaderView (let's call it self.tableHeaderView).
The problem i'm facing is that I want to resize the self.tableHeaderView based on certain conditions. I've added constraints to all of my UI elements and I can't, for whatever reason, add a height constraint to the self.tableHeaderView via the nib.
I tried changing the frame of the self.tableHeaderView programmatically but that has no effect when i run the code in simulator, which makes sense because if I use Auto-layout, it should ignore the frame changes.
I tried adding a height constraint programmatically but it crashes.
This is the piece of code I've to add the height constraint.
[self.tableHeaderView addConstraint:[NSLayoutConstraint constraintWithItem:self.tableHeaderView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:107.0f]];
The exception i got:
*** Assertion failure in -[UITableView layoutSublayersOfLayer:], /SourceCache/UIKit_Sim/UIKit-2903.2/UIView.m:8536
* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Auto Layout still required after executing -layoutSubviews. UITableView's implementation of -layoutSubviews needs to call super.'*
Worst case scenario I'll add another sibling view with the second height and duplicate the UI elements but i want to avoid this.
Edit 1: I get that exception when i've this
self.topicHeaderView.translatesAutoresizingMaskIntoConstraints = NO;
If i don't have it, i get this
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)
(
"",
""
)
Will attempt to recover by breaking constraint
Break on objc_exception_throw to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in may also be helpful.
Edit: 2
On a 4" screen, it looks fine (The red background covers the entire tableHeaderView as i would expect)
On a 3.5" screen, the red background (which is applied on the nib, extends to a certain height even though i set the height to be 117.0f. The UI elements that are inside the tableHeaderView shows up correctly)
The blue line at the bottom is the separator line and the blue border is around the tableHeaderView.
When you are adding a view as a header or footer to the table view, you cannot use constraints on this view, but only inside it. Also the view must be on the top of the hierarchy (as you have), if you move it as a subview to another view, it will give the same error.
You can change view's height directly in code by setting the same frame with changed height. This is working fine.
Also remember that this changes will not apply until you reassign the header:
tableView.tableHeaderView.frame = ...;
tableView.tableHeaderView = tableView.tableHeaderView;
I had the same issue, I couldn't use constraints on the tableHeaderView.
Then I created another subView to create the constraints into.
// 1 - create a header view and a subHeaderView
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, bounds.size.width, bounds.size.height - 64.f)];
headerView.backgroundColor = [UIColor blackColor];
tableView.tableHeaderView = headerView;
UIView *subHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, bounds.size.width, bounds.size.height - 64.f)];
[headerView addSubview:subHeaderView];
// 2 - add constrainedView to subHeaderView (E.g.)
UIView *constrainedView = [UIView new];
[constrainedView setTranslatesAutoresizingMaskIntoConstraints:NO];
[subHeaderView addSubView:constrainedView];
// 3 - addConstraints of subviews into subHeaderView (E.g.)
[subHeaderView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[constrainedView]|" options:0 metrics:metrics views:views]];
[subHeaderView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[constrainedView]|" options:0 metrics:metrics views:views]];
This is working on my project, iOS 7.0 / Xcode 5.0.2
I have a subclassed UIView which I can get to scroll but not to zoom. I'm using autolayout so wondered if anything had changed in IOS6. In particular when are the scrollViewWillBeginZooming and scrollViewDidEndZooming methods implemented. My code looks like
- (void)viewDidLoad
{
[super viewDidLoad];
self.ringSet2 = [[RingView alloc] initWithFrame:CGRectMake(0, 0, 800, 800)];
[self.ringSet2 setDefaults];
/// ... more setup for other views but only ringSet2 is scrolled.
self.scrollview1.delegate=self;
self.scrollview1.scrollEnabled=YES;
self.scrollview1.contentSize=self.ringSet2.bounds.size
self.scrollview1.minimumZoomScale=0.2;
self.scrollview1.maximumZoomScale=5.0;
self.ringSet2.userInteractionEnabled=YES;
// ... needed elsewhere so other views can pick up their dimensionts
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
/// ... code for additional views
[self.scrollview1 zoomToRect:CGRectMake(0, 0, 200, 200) animated:YES];
[self.scrollview1 addSubview:self.ringSet2];
}
with
-(UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView{
return self.ringSet2;
}
and scrollViewWillBeginZooming etc. implemented just to trace what is happening. Interesting,
viewForZoomingInScrollView appears to get called only once, as is scrollViewDidEndZooming with a scale value just under one but scrollViewWillBeginZooming is never called. The property ringSet2 is defined
#property (strong, nonatomic) IBOutlet RingView *ringSet2;
as the view does not appear if it's defined as weak.
Apologises for this. The answer is really stupid. I'm currently developing under IOS 6.0 on the simulator whilst my phone is still on IOS 5. The simulator allows you to simulate pinches but only centred on the centre of the screen. The scrollview however only receives this signal if it too is in the centre which was not the case in my initial build. Moving the scroll view's rectangle into the centre fixed the problem. You would not make this mistake testing on a real device. The code is thus OK. Lost 3 or 4 evenings pulling my hair over this one.
I have a UIView that I have dropped inside of another UIView in IB (iPad version), I am doing this so I can control the background color of the region.
Odd thing is that if I set the background color of the UIView to GroupTableViewBackgroundColor, either in IB or code, the color is always white, it does not respect the color change, nor is it reflected in IB.
Has anyone seen this behavior and found a fix?
Thanks in advance.
I think I know what you are saying. You want the view to be the same as a group table view even though it isn't a group table view. This is what I did:
UITableView *tv = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStyleGrouped];
UIView *backgroundView = tv.backgroundView;
[self.view addSubview:backgroundView];
[tv release];
CGRect backgroundFrame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
[backgroundView setFrame:backgroundFrame];
[self.view sendSubviewToBack:backgroundView];
I am not sure if it is related to your problem but Apple introduced some changes to UITableView for iOS 3.2. They introduced a new property to UITableView defined as follows:
#property (nonatomic, readwrite, retain) UIView *backgroundView;
This new view sits behind the table cells, header and footer which can be confusing if you set the table view background color. As a quick workaround, if you just want to change the color, you can remove the new view:
tableView.backgroundView = nil;
You should then get the same behavior as on the iPhone when you set tableView.backgroundColor. (Of course this may all change with iOS 4.2).
I have a UIScrollview with an IBOutlet mapped to ganttScroller. This UIScrollView has a UIView in it. I made the UIView in IB and its width is 100.
I then start to add buttons to that UIView (mapped via an IBOutlet scrollContent)
float test = [scrollContent frame].size.width;
for (int i=0; i<15; i++) {
UIButton *showButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
showButton.frame = CGRectMake(55.0 * i,
50.0,
50.0,
20.0);
[showButton setTitle:NSLocalizedString(#"test", #"") forStates:UIControlStateNormal];
[scrollContent addSubview:showButton];
}
test = [scrollContent frame].size.width;
[scrollContent sizeToFit];
test =[scrollContent frame].size.width;
At the beginning I check the size of my scrollContent and it is indeed 100 (checked 'test' in the debugger), after adding the buttons it is again 100, and after sizeToFit it is still 100 (I would expect a lot larger since all those buttons were added... The buttons are shown correctly!
I need the correct size for my gantScroller (UIScrollView)
What is wrong ?
I don't think -[UIView sizeToFit] actually takes in to account its subviews. You'll need to simply calculate the correct width and assign that to the view's frame. You'll then also need to set the scroll view's contentSize property so that it scrolls correctly.
Probably the reason you see all the buttons despite the container being too small is that UIViews do not clip their subviews by default.
I'm having kind of a dumb problem.
I am using the below code to create/modify a UILabel via code. The reason I am creating it via code is because I need it to be rotated 90 degrees and Im not aware of a way to do that in IB.
What's happening - A user hits a button that makes the text they selected to appear in the UILabel. Then when they select the button again, with different text, the new text appears in place of the old text.
The first time I hit the button, it works perfectly, but the second time I hit the button, the new label appears over the old label and the old label never disappears. I have tried removing the first label, making it nil, just removing the text, but I cannot access any part of the label once it has been created.
ViewController.h
...
UIView *viewForLabels;
UILabel *tab1Label;
}
#property (nonatomic, retain) IBOutlet UIView *viewForLabels;
#property (nonatomic, retain) IBOutlet UILabel *tab1Label
...
#end
ViewController.m
...
#synthesize tab1Label;
...
UILabel *tab1Label = [[UILabel alloc]init];
tab1Label.text = [theText];
tab1Label.backgroundColor = [UIColor clearColor];
tab1Label.textColor = [UIColor blackColor];
tab1Label.opaque = NO;
tab1Label.font = [UIFont systemFontOfSize:14];
tab1Label.numberOfLines = 2;
tab1Label.adjustsFontSizeToFitWidth=YES;
tab1Label.transform = CGAffineTransformMakeRotation (90*3.1459565) / 180);
tab1Label.frame = CGRectMake(2,87,45,119);
[viewForLabels: addSubview: tab1Label];
...
First in your code example you alloc tabLabel1 and then run a bunch of property updates against a different named object tab1Label.
Sorry if I am misunderstanding the question but why are you creating a second label? Per this part of your description:
What's happening - A user hits a
button that makes the text they
selected to appear in the UILabel.
Then when they select the button
again, with different text, the new
text appears in place of the old text.
Just update the .text property and any sizing needed why use a whole separate object?