Issue with Auto Layout on iOS 8 (code works perfectly on iOS 7)
This is definitely an iOS 8 bug. I was able to work around it by sending setNeedsLayout
to the container view (the superview of the image view).
I see that you're sending setNeedsLayout
to self.view
. If that code is in your view controller, then I guess self.view
is not the container view. Try sending setNeedsLayout
to the container view directly.
Demo project is here.
Auto-Layout Issues: iOS 7 vs iOS8
The issue was solved with answers from Stack-overflow. Basically, the right answer is this, but it was nicely summarized in this answer. The difference between iOS7 and iOS8 is not in the way the constraints are interpreted, but in the way that update commands are trickled down through the view hierarchy. When I implemented the behavior first in iOS 7, I noticed that the animation would only work properly if I called layoutIfNeeded
on the parent view of the sizing view
(i.e. on centering view
). In iOS 7 this apparently trickled down the view hierarchy automatically. In iOS 8, this is not the case: You have to manually invalidate the view whose constraints have changed with setNeedsLayout
, and then update the layout with layoutIfNeeded
. My solution in the updated code looks like this:
- (IBAction)showLess:(id)sender {
self.widthConstraint.constant = 50;
[self.sizingView setNeedsLayout]; // *** THIS LINE IS NECESSARY TO MAKE THINGS WORK IN iOS 8
[UIView animateWithDuration:0.3 animations:^{
[self.sizingView layoutIfNeeded]; // trigger animation
}];
}
I've updated the question to include the answer, but in response to @unmircea I am posting a separate answer, as well.
iOS 8 Auto Layout issue
It's not a problem of Auto Layout, but must be a bug in iOS 8 about handling sliced image assets.
With your sample project:
UIImage *img = [UIImage imageNamed:@"pointer-dark-left"];
NSLog(@"alignmentRect: %@", NSStringFromUIEdgeInsets(img.alignmentRectInsets));
NSLog(@"capInsets: %@", NSStringFromUIEdgeInsets(img.capInsets));
This code prints
// iOS 7
alignmentRect: {0, 0, 0, 0}
capInsets: {0, 5.5, 0, 134}
// iOS 8
alignmentRect: {0, 0, 0, 65.5}
capInsets: {0, 5.5, 0, 134}
alignmentRectInsets.right
is 65.5
!
As documented, Autolayout works with alignment rectangles, and UIImageView
uses its images alignmentRectInsets
. So, your self.line
has 65.5
pt extra right width.
Of course, you didn't set the Alignment Insets in xcassets
editor, I believe it's a bug.
Here is a ugly, but working, workaround :(
- (void)viewDidLoad {
[super viewDidLoad];
self.line.image = [self.line.image imageWithAlignmentRectInsets:UIEdgeInsetsZero];
}
iOS 7 vs iOS 8 autoloayout issues
Your constraints are overdetermined. I don't know why this issue doesn't emerge on iOS 8, but it is plain to see in the list of constraints in your screen shot what the problem is. In order, we have (I'll use the last two digits of the memory address of the views to identify them):
The top of view 80 -
V:|-(0)-[UIView:0x7b099c80]
The height of view 80 -
UIView:0x7b099c80.height == ...
The space between the bottom of view 80 and the top of view 60 -
V:[UIView:0x7b099c80]-(0)-[UIView:0x7b099260]>
The height of view 60 -
UIView:0x7b099260.height == ...
The bottom of view 60 -
V:[UIView:0x7b099260]-(0)-[_UILayoutGuide:0x7b09a220]>
That's too many constraints. You can set the top and the height or the top and the bottom of something, but you must not set the top and the height and the bottom - because if the resulting arithmetic is off by even a tiny bit, those demands cannot be satisfied simultaneously.
Related Topics
Can an iOS App Switch to Safari Without Opening a Page
What Does Inherit! :Search_Paths Do
Uialertcontroller Text Alignment
Expand and Collapse Tableview Cells
Prepareforsegue Called Before Didselectrowatindexpath Only When Third Segue Is Added
How to Create Entitlement.Plist File in Xcode
Dynamic Uitableview Cell Height Based on Contents
iOS Alamofire Stop All Requests
iOS Unable to Find Plugins, Android Fine
How to Fill a Bezier Path with Gradient Color
iOS 5 Sdk Is Gone After Upgrade to Xcode 4.5
Install iOS App Directly from Website - No Password, No Itunes, No Udid
Change the Uitextview Text Direction
Avqueueplayer Playback Without Gap and Freeze
Location Update Even When App Is Killed/Terminated