My app subclasses a UITableViewCell and implements layoutSubviews to modify the cell's contentView's width, like so:
- (void)layoutSubviews {
[super layoutSubviews];
// position subviews...
CGRect frame = [[self contentView] frame];
frame.size.width -= 20;
[[self contentView] setFrame:frame];
}
When running this code with the iOS 8 simulator and Xcode 6 GM seed, this triggers an infinite loop. However, when running on a real iPhone or iPad running iOS 8 GM seed, it does not loop, as in previous versions of iOS.
I first thought the difference was a compiler optimization, but the simulator loops in both debug configuration and release configuration.
Questions
Why the difference between the iOS 8 GM and the simulator?
Is this a critical bug fix? I'm very reluctant to release an app that exhibits a potentially serious hanging bug, even if I can't reproduce it on device.
What in your opinion is the best way to refactor this to eliminate the looping without causing regression on iOS 7 and 6?
This happened to me on one of the previous iOS 8 betas. Occurred on both device and simulator. After some debugging I found out that UITableViewCell probably uses autolayout internally on iOS8. Moreover, any changes to contentView.frame triggered layoutSubviews (which might be a reason of your infinite loop as well).
As a workaround, I added a subview to the cell's contentView and modified its frame instead. Then I used this view like I would use the contentView (as a superview of all the custom cell elements).
Related
In the app I support iOS 7+. But I can't download a simulator to test it on iOS 7, because the latest simulator available is iOS 8. Everything works fine on iOS 8 and iOS 9. But my customer has iPhone 4 with iOS 7 and when he runs the app, it crashes immediately after launch with error:
Auto Layout still required after executing -layoutSubviews. UITableView's implementation of -layoutSubviews needs to call super
I took this error from crashlitics report. May be somebody knows how to correct that?
Check your all layoutSubviews methods where you have write and in that method first call [super layoutSubviews]; .
because before few month I have same problem for ios 7 and then I call [super layoutSubviews]; In custom cell where I have used layoutSubviews method and its working fine for me.
-(void)layoutSubviews
{
[super layoutSubviews];
// do your stuff
}
So basically I am trying to dynamically change the height of a view based on three different labels inside of it. I use _labelName_.frame.size.height to get the height for all three. This works great in iOS 8, however in iOS 7 one returns 17 (should be 33), the other two both return 0, and they should be 22.5 and 16.5.
I'm at a loss as to why iOS 7 and iOS 8 are returning different frame heights, any help would be greatly appreciated!
Edit: Did a little debugging. Turns out, the frame heights are 0 in iOS 7, but not in iOS 8. It seems that layoutSubviews is working differently on iOS 7 than it is on iOS 8. Any reason that layoutSubviews would lay out the subviews differently between the two versions?
Try calling [_labelName_ sizeToFit] after setting the text and before accessing the frame
I have a very strange problem since I updated iPad on iOS 8.1.3.
Anywhere in the app where some label needs to go with multiline (numberOfLines set on 0) it crashes on when drawing rect or on sizeToFit.
This was working just fine on iOS7.
Here is call stack when crash happens: http://s16.postimg.org/txnmngglh/Screen_Shot_2015_02_09_at_11_01_41_AM.png
Just Uncheck Autolayout & try again.
If you don't want to Uncheck Autolayout than simply add this line:
Your_TextView.numberOfLines = 0;
Hope it will work for you.
My root view controller is a tab view controller. My app is landscape mode only. It's set on landscape both in the project settings and in the storyboard for each VC including the root. In viewDidLoad, I have:
NSLog(#"width of view in didappear:%f",self.view.frame.size.width);
and the same code in viewDidAppear. In viewDidLoad in iOS 8, that line prints out 480. In iOs 7, it prints out 320(the width of the screen in portrait mode) but in viewDidAppear, it prints out 480 which is correct. Yes it is the same device for all of you out there who are always in search of 'precise' details.
Why is the view still in portrait in viewDidLoad in ios7 but not in ios8? What can be done? I set up my whole view in viewDidLoad because I only need to do it once and so can't migrate it to viewDidAppear or other places.
It's a curious difference between iOS 7 and 8 if that's the case. I'm guessing it's the same device type but physically different items? Or are you really running iOS 7 & 8 on the same device?
So you could theoretically still have setting differences. I.e. iOS 7 device locked in portrait, etc.
If the setup is really as you say, a boolean property would help you to run in viewDidAppear. I just provided an example of how that could be done here: https://stackoverflow.com/a/27867549/1111233
Basically, viewDidLoad is run before the UIElements are loaded and placed on screen, so that's why you are getting the wrong size. As far as the difference between iOS7 and iOS8, I guess apple slightly changed the internals, but in any case you should definitely move your graphics code to viewWillAppear. viewWillAppear is run when the graphics are loaded and works the same as viewDidLoad
use bounds
CGRect rect = [[UIScreen mainScreen] bounds];
NSLog(#"width of view in didappear:%f",rect.size.width);
The frame is relevant to the parent view. The very top view is UIWindow, which in iOS 8 became rotation dependent. In landscape the frame and the bounds will therefore be different in iOS 7, but the same in iOS 8. If you use bounds instead of frame, it should give the same result for both iOS versions, given that the objects are not rotated some number of degrees.
I have view in my xib file whose height is 44 which contains buttons (like a toolbar).
It's working fine in iOS 7 now but when i open it in iOS 6 , the height of view gets small (24.0f) and so are the buttons in it.
Another thing is that, if i build the app with xcode 5 then the older versions of xcode will not be able to open xib files.
How to fix this issue? Help would be highly appreciated.
This is works for me
- (void)viewDidAppear:(BOOL)animated {
self.view.frame = CGRectMake(0, 0, 320, 00);
NSLog(#"%f", self.view.frame.origin.x);
NSLog(#"%f", self.view.frame.origin.y);
NSLog(#"%f", self.view.frame.size.width);
NSLog(#"%f", self.view.frame.size.height);
[super viewWillAppear:animated];
}
To answer of the second part of your question, the head of your xib file is different with XCode 5. But, with XCode 5 you can keep the old version of your xib using XCode 4.6 and iOS 6.
Go to your xib file and modify :
and use XCode 4.6 and iOS 6 :
With that, you can correct your bug with the 20px less in iOS 6.
You need to keep your xib file in iOS 6 and add a Content View below the view with a delta of 20px in Y and add your UI elements in this content view. like this :