Strange behaviour when updated to Xcode 8 - ios

The above contents are placed in a scrollview but the output in the app is as below
If i place these contents outside the scrollview it is working fine, it was working fine before update to xcode 8

Try adding these constraints for UIScrollView

Don't change anything layout (Autoresizing/Autolayout). I think the issue is scrollview content size. So, you update the view frame in viewDidLoad method. And after then update scrollview content size.
- (void)viewDidLoad {
[super viewDidLoad];
//set view frame
self.view.frame = [UIScreen mainScreen].bounds;
}

Related

iOS UIView Not Resizing Subviews?

I'm loading a view from a storyboard programatically, but there's an issue with my subview heights (I'm using Autoresize Subviews etc).
When the view loads, the main UIView appears to be the correct size, but the subviews that depend on the constraints to dynamically calculate their final height don't seem to be resizing from the sizes they were set at in interface builder.
Loading the view like so:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ApplicationRecordingViewController* recordingController = (ApplicationRecordingViewController*)[storyboard instantiateViewControllerWithIdentifier:#"recordView2"];
[self presentViewController:recordingController animated:NO completion:nil];
Orange area's height is from top of main view to top of grey area. Grey area is fixed height
The strange thing is, if I set the simulated size in interface builder as the correct view for my phone, the sizes work out. I guess the initial heights for subviews are 'baked' into the view, but then (usually) resized when the view actually loads?
Note: The orange area should be completely filled by the camera view I'm loading into it.
Incorrect height
Correct height if I change simulated layout
Would love to know what I'm doing wrong!
Edit 1: Constraints
Camera is the orange bit. The Camera bottom constraint is currently set as the bottom of the view + enough room for the gray bar. Have also tried setting the bottom to match the top of the gray bar!
Link to Storyboard with Scene
I know you're all better than me, but I experienced the same in my last project. My Camera View inside a UIView is not in full screen or resizing and fitting the whole UIView, and I also posted it on my daily blog.
Implement viewDidLayoutSubviews -- Inside that method, layout again your video preview layer.Do not alloc init anything inside that method, just re-layout your views. After that, your video preview will fill the height and width of its parent, or whatever you've been targetting.
The issue also has something to do with the hierarchy of the constraints and views.
You already got the answer.
'if I set the simulated size in interface builder as the correct view for my phone, the sizes work out.'
You may call some functions to get height in viewDidLoad or viewWillAppear.
Change Code like this
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
CGFloat height = [self getHeight];
}
or
- (void) viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
CGFloat height = [self getHeight];
}
As i can see in your storyboard constrain you have set bottom space to bottom layout guide 150 . i think this is the issue . if you give fixed height to bottom view then no need to set constant as from bottom layout guide --> 150 .
Your old constrain :- >
Just set bottom space of orangeview from greenview = 0.
Check new constrain ,
Here is your storyboard link ,
Storyboard Download link
Here is your output,
After investigating the layout a little more, I found the camera view (orange) seemed to be the correct size, but the live camera preview wasn't.
Solution was to move the camera library (SCRecorder)'s init method into viewDidAppear (was in viewDidLoad before).
My thinking is iOS doesn't autolayout the camera preview view in the same way as normal UIViews, etc.
#interface ApplicationRecordingViewController () {
SCRecorder *_recorder;
}
#end
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
_recorder.previewView = _previewView;
}
Perhaps you can try to get rid of these two hook.

UIScrollview: What is setting the contentSize back to 0?

I have a UIScrollView, and in viewDidAppear I set the contentSize:
- (void)viewDidAppear:(BOOL)animated{
CGSize scrollContentSize = CGSizeMake(320, 9200);
self.scrollView.contentSize = scrollContentSize;
}
This code is definitely running.
However, the view doesn't scroll. I wired up a button to log the contentSize, and it returns 0,0. If I get the button to set contentSize again it works fine.
I'm not referencing scrollView anywhere else in my code, what could be setting the contentSize back to 0, and is there any way I can stop it from doing so, or run my setup later in the process of setting up the view?
if you used the Autolayout then you have to make constraints for subviews in it. Then Autolayout will calculate its content size automatically.
But when I set contentsize through button action it works? How?
When the view relayout the scrollview again it will be calculated based on the constraints. So it won't work when u rotate the device/relayout the view.
I don't want to use the autolayout?Now what?
Then you are good to set contentsize.
One more thing, it is best practice to call super implementation on few lifecyle methods.
so do it so.
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
// Your code here
}
Here is the Good starting point
Excellent tutorial

IOS - UIScrollView Refusing to scroll

I have built a large IOS app and whilst testing noticed that a uiScrollview within a static page has stopped scrolling - to explain the setup of the page - the structure is as follows -
the scrollview is connected to the header file as scwollMa (as in above doc).
it has the following properties in storyboard -
I have applied the following into the .m page -
- (void)viewDidLoad
{
[super viewDidLoad];
//Set Scroller
[_scwollMa setScrollEnabled:YES];
self.scwollMa.contentSize = CGSizeMake(320, 1100);
Yet it does nothing! no error either - big head scratcher! Any advice at all?
You have set the height of the scrollview at the same height as the content size. To scroll set the height of the scroll view to fit into the visible screen area (like self.view.frame.size.height).
If the scroll view and the content view have the same height, there's nothing to scroll for.
contentSize.Height must be greater to actual.height:
Change the following line of code to
self.scwollMa.contentSize = CGSizeMake(320, 1500);
will work for you.
and in interface builder keep height which is visible inside your view.

ScrollView doesn't work in landscape orientation

I am developing in Objective-C. I am using the following code for scrollView, and it works fine in Portrait orientation.
- (void)viewDidLayoutSubviews
{
UIScrollView *scrollView = self.scrollview;
[scrollView setContentSize:CGSizeMake(320.0,3100.0)];
}
But the view does not slide down when I change to landscape orientation.
Am i missing something?
[scrollView setContentSize:CGSizeMake(320.0,3100.0)];
In this, 320 used for Width.. When you are trying for landscape orientation. Then please increase size for width..
Please check it with more than 320 (Minimum Screeen Width).
3.5 inch - 480 & 4 inch - 568
[scrollView setContentSize:CGSizeMake(SCREEN_WIDTH + YOUR_EXTRA_SIZE,3100.0)];
Hopefully, it will help you.
Thanks.
- (void)viewWillAppear:(BOOL)animated
{
UIScrollView *scrollView = self.scrollview;
[scrollView setContentSize:CGSizeMake(320.0,3100.0)];
}
Scrollview always loaded in portrait mode in viewDidLoad/loadView method, so what ever adjustment you like to made you have to do those changes in viewWillAppear/viewDidAppear methods.
When Device get rotate didRotateFromInterfaceOrientation method get called, so I would suggest to change the ScrollView Contant size this way
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
self.scrollView.contentSize = self.contentView.bounds.size;
}
Note : Make sure your have UIScrollView and UIView in your layout
UIScrollView is scrollView and
UIView is contentView

Incorrect size of label on viewWillAppear

I have following setup
XIB file which has only landscape view. This view is connection to my controller
There is a label on this view which is connected to IBOutlet UILabel* label
This label is configured like this (it occupies the whole width of screen).
I overrided viewWillAppear and do this (to get the size of label).
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
CGRect rect = _labelTitleLand.frame;
}
The strange thing (which I don't understand). That it returns size = (width 768, height 21) when it launched in portrait (on iPad), which is correct.
And it returns size = (width 741 height 21) when it's launched in landscape. Which is weird. I anticipated that it will return width 1024, height 21 for landscape.
I was under impression that at the moment of viewWillAppear, all controls sizes are calculated already.
Update 1
If I check labelTitleLand.frame on viewDidAppear then it returns correct results. However, I don't like this, because I want to do some actions (based on this size) which influence how view will be drawn. In the case, if I will do it on viewDidAppear, as I understand there will be visible redrawing.
The layout of the view hierarchy has to be complete before you will get the actual final frames.
So you should check the frame in viewDidLayoutSubviews, which will still be before the view hierarchy is actually drawn. If you need to make changes here you can without causing any redrawing to occur.
viewWillAppear is too early because this is before your autoresizing masks (and/or autolayout constraints) have had their effect.
This seems a problem related to when a method is actually called at runtime.
I solved similar situation using
[self performSelector:#selector(checkMethod) withObject:nil afterDelay:0.1];
in viewWillAppear, and then:
- (void)checkMethod
{
rect = _labelTitleLand.frame;
}
This gives your app the time needed to set its own frame.
It is not so elegant and it looks like a workaround, but it is very effective.
You can also try to force the frame of the UIView that is container of the UILabel in viewWillAppear like this:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.view.frame = CGRectMake(0.0f, 0.0f, 1024.0f, 768.0f);
CGRect rect = _labelTitleLand.frame;
}
But the first solution is more reliable and usually no lag is experienced.

Resources