I have a webView inside a scrollView (scrollView > mainView > webView and a view2 containing other components). In order to have only one scroll (the scrollView one) I calculate the height of the webView when it finish loading then I set the height of the mainView (its height is equal to the the webView + the view2 heights). My application supports the portrait and the landscape modes. To check when the rotation has changed I use:
- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
Inside this function I call another one in order to reset the content of my webView (set the html content) so that the
(void)webViewDidFinishLoad:(UIWebView *)webView.
can be recalled:
- (void)webViewDidFinishLoad:(UIWebView *)webView {
//set the main view height
[self.loader stopAnimating];
CGSize contentSize = webView.scrollView.contentSize;
float scrollHeight = contentSize.height + 270;
NSLog(#"webViewDidFinishLoad scrollHeight %f", scrollHeight);
self.mainViewHeight.constant = scrollHeight;
}
My problem: when the application is at first in the portrait mode, the scrollView height is correct and works perfectly. When after that I change the rotation to the landscape mode, also the height is correct, but when I return the device to the portrait, the scrollView keep the height of the landscape mode even if I set the height in the webViewDidFinishLoad. When I put a breakpoint in self.mainViewHeight.constant = scrollHeight; I found that the contentSize height doesn't change when I go from the landscape to the portrait mode
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
// change the frame for both portrait and landscape
// check the orientation
if(toInterfaceOrientation == UIDeviceOrientationPortrait){
webView.frame = self.view.frame;
}else {
//
}
}
Related
When I change viewcontroller orientation while it's loading on particular orientation, part of the screen goes blank at the bottom.
Steps to reproduce:
Have tableview(Not necessary I think. could be any view) in a view controller
Push a new viewcontroller which also has a tableview(Not necessary I think. could be any view) during
an action
Rotate the screen from one orientation to Another(Portrait to landscape or landscape to portrait).now you will be able to see the dark part.
Press back button to pop the current viewcontroller
Now rotate from one orientation to Another(Portrait to landscape or landscape to portrait).now you will be able to see the dark part here as well.
The bottom part of viewcontroller goes black.
I am able to reproduce 7 out of 10 times.
FYI:
My Viewcontroller has only tableview that's all and all cells has autolayout constraints.
Trying to understand why it happened and I would like to fix it.
More details on reproducing the issue:
Basically you can reproduce this issue only if you hold your device in slanting position and either push or pop a view controller and while the page is trying to load , you have to change the orientation then the issue happens.
(Pun intended.... lol )
In other words ,you have to tilt you device as if you are steering the wheel :).
This issue can only happen if you use your device like a steering wheel :)
In your viewWillTransition method call layoutIfNeeded()
Try to reset the layout of TableView after rotation by using this method,
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
tableView.layoutIfNeeded()
}
or
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
tableView.layoutIfNeeded()
}
I also experienced the same issue.
My view controller had just one tableview and when we tilt , I mean change the orientation during a navigational push or pop this used to happen.
Try setting the frame
in viewDidLayoutSubviews
-(void)viewDidLayoutSubviews{
CGRect screen = [[UIScreen mainScreen] bounds];
CGFloat width = CGRectGetWidth(screen);
CGFloat height = CGRectGetHeight(screen);
CGRect frame = self.tableView.frame;
// To check if there's any mismatch between the sizes of screen and tableview then set the tableview frame same as screen frame.
if (CGRectGetHeight(frame) != height && CGRectGetWidth(frame) != width) {
self.tableView.frame = CGRectMake(0, 0, width, height);
}
}
or try setting the frame in viewWillTransitionToSize
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator{
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
CGRect screen = [[UIScreen mainScreen] bounds];
CGFloat width = CGRectGetWidth(screen);
CGFloat height = CGRectGetHeight(screen);
CGRect frame = self.tableView.frame;
if (CGRectGetHeight(frame) != height && CGRectGetWidth(frame) != width) {
self.tableView.frame = CGRectMake(0, 0, width, height);
}
}
FYI:
if setting the frame self.tableView.frame = CGRectMake(0, 0, width, height); doesn't work then you could try [self.tableView layoutIfNeeded]
Set frame again in
viewDidLayoutSubviews
In one view controller(Parent the one that pushes new view controller) setting the frame at viewDidLayoutSubviews solves the issue in another view controller(The child view controller , one that's getting pushed) setting the frame at viewWillTransition fixes the problem :) But still I don't know why there's no universal solution to this problem.
I have a UIView,
UIView *topBarView
I am deciding the size i.e. the width and height of topBarView as
CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height*.05);
Now I am setting the frame of topBarView as
topBarView.frame = (CGRect){0, 0,topBarSize};
Im my view controller I have set this condition for rotation
- (BOOL)shouldAutorotate
{
return YES;
}
-(UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
When my view controller opens in portrait mode it is all good and as expected the topBarView is placed at the top
But when my view opens in Landscape Left mode the topBarView instead of being on top in Landscape is on the left of the screen i.e same frame as it was in case of portrait
How can I fix this?
As you have set frame your view's origin is (0,0) so it will definitely set in top - left corner in any orientation.
If you want to manage width and height according to orientation then you should use autolayout.
You should set top,leading,trailing and fixed height constraint to that view. so, it will will manage height,width and position with orientation.
Update:(as asked in comment)
Write below code in viewdidload and comment yours
UIView *topBarView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height * 0.5)];
topBarView.backgroundColor = [UIColor orangeColor];
[self.view addSubview: topBarView];
Hope this will help :)
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
I have a UIScrollView to display a longer listing of textviews, fields and images. In the viewDidAppear I set the contentSize appropriately and I also add this code to didRotateFromInterfaceOrientation so that the UIScrollView contentSize resizes based on the orientation.
Problem is that when the view first appears the UIScrollView doesn't respond (I can't scroll) but after rotating the device the code in didRotateFromInterfaceOrientation is called and everything works perfectly. (If I start the app in landscape orientation I can only scroll a little bit to see what is normally displayed in portrait mode and not the extended content - ignores the scrollView I've defined)
The code is the same in viewDidAppear and didRotateFromInterfaceOrientation so why does the scrollView only respond after rotation? Any help appreciated.
The output from the NSLog messages in both methods is the same.
#property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
- (void) viewDidAppear:(BOOL)animated{
//If not an iPad set the scrollview to allow scrolling of view
if (!([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)) {
self.scrollView.contentSize= CGSizeMake(self.view.frame.size.width,1000);
[self.scrollView setUserInteractionEnabled:YES];
}
if(self.scrollView.userInteractionEnabled){
NSLog(#"DEBUG scrollview height : %f",self.scrollView.contentSize.height);
NSLog(#"DEBUG scrollview width : %f",self.scrollView.contentSize.width);
}
}
-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
//If not an iPad set the scrollview
if (!([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)) {
self.scrollView.contentSize= CGSizeMake(self.view.frame.size.width,1000);
}
if(self.scrollView.userInteractionEnabled){
NSLog(#"DEBUG scrollview height : %f",self.scrollView.contentSize.height);
NSLog(#"DEBUG scrollview width : %f",self.scrollView.contentSize.width);
}
}
You'd better change the contentSize in viewDidLayoutSubviews, which is called when appearing and when changing the orientation.
But don’t forget to call super first!
Hey Please Try this code I think your problem is solve using this code.
Try didRotate method in fetch your device orientation is Landscape or portrait. and set frame based on that.
- (void)viewDidAppear:(BOOL)animated {
if (!([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)) {
self.scrollView.contentSize= CGSizeMake(self.view.frame.size.width,1000);
[self.scrollView setUserInteractionEnabled:YES];
} else {
[_scrollView setScrollEnabled:YES];
_scrollView.contentSize = CGSizeMake(_scrollView.frame.size.width, 2320);
}
if(self.scrollView.userInteractionEnabled){
NSLog(#"DEBUG scrollview height : %f",self.scrollView.contentSize.height);
NSLog(#"DEBUG scrollview width : %f",self.scrollView.contentSize.width);
} }
-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
if (fromInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || fromInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
[_scrollView setContentSize:CGSizeMake(736, 1000)];
} else {
[_scrollView setContentSize:CGSizeMake(414 , 1200)];
}
}
Happy Coding.
I want to have an UIView with width=480 and height=640, centered in the middle of my master view.
I want this to happen both in landscape orientation and portrait orientation, but now if I design it for portrait orientation, when I'm turning the device to landscape, my UIView has width=640 and height=480.
Any solutions for my UIView to keep it's sizes in both orientation types?
you can implement viewDidLayoutSubviews (in UIViewController) or layoutSubviews (in UIView) to reposition the view.
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
self.myCustomView.bounds = CGRectMake(0, 0, 480, 640); // update size
self.myCustomView.center = self.view.center; // update center
}