UIWebView frame to fill screen when loaded landscape and portrait - iphone

I am adding a UIWebView to my view, which works fine when I am in portrait. But when I load that same UIWebView in landscape it does not fill the screen. I suspect it comes from how I am setting the frame:
CGRect screen = [[UIScreen mainScreen] bounds];
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, screen.size.width, screen.size.height)];
webView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
webView.scalesPageToFit = YES;
Is there a better way to do this so it will load correctly in both landscape and portrait, and fill the screen when rotated?

How sure are you that the parent view is resizing to the full width? UIWebView subview will not go larger than it's parent...

I had same problem.. After i Logged the self.view.frame.size.width i was surprised to find out thats it was 320 instead of 480. The solution to this was :
- (void)viewWillAppear:(BOOL)animated {
[self.view setBounds:CGRectMake(0.f, 0, self.view.frame.size.width, self.view.frame.size.height)];
[self.view setCenter:CGPointMake(self.view.frame.size.width/2, self.view.frame.size.height/2)];
[(UIWebView*)myWebView setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];}
Seems that the correct size of self.frame is returned just before showing the view :)

Related

The frame size of the view is not changing on rotation when the view is created with loadView

I have UIViewController without a xib, and I'm using loadView to build my UI that creates and adds two scroll views. The thing is, the main view frame size is not changing when rotation happens. I mean, I'm setting initial frame size for the main view in loadView (portrait mode: frame size width = 320, height = 480). After rotation to landscape orientation, the view main frame size isn't changing and is the same as in portrait mode. Here's my loadView:
-(void)loadView{
CGRect screenBounds = [[UIScreen mainScreen] bounds];
self.view = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, screenBounds.size.width, screenBounds.size.height)] autorelease];
self.view.autoresizingMask = (UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);
self.scrollView1 = [[[UIScrollView alloc] init] autorelease];
self.scrollView1.frame = CGRectMake...
[self.view addSubview:self.scrollView1];
self.scrollView2 = [[[UIScrollView alloc] init] autorelease];
self.scrollView2.frame = CGRectMake...
[self.view addSubview:self.scrollView2];
I have also set autoresizingMask for the view to expand or shrink to fit the screen. But I'm getting the same width and height values when debugging that in console. I need to get a new size because I need to reposition my two scrollViews when rotation happens, for example to shrink the height and expand the width on the scrollViews on rotation to landscape mode. I could do manually in shouldRotate, just curious about how it should be done in proper way.
I have noticed that self.view.frame size does not change but self.view.bounds does on rotation, and bounds represent correct values with respect to current interface orientation.

Set starting point of content size for UIScrollView

How do I set the starting point of a UIScrollView? I would like to add a UIImageView left of the UIScrollView but changing the contentSize only adds scrolling room to the right of the scrollview. How do I add an ImageView left of the scrollView's (0,0) point and make it part of the scrollview's content size?
Hopefully I've got what you're trying to do here. I think this just takes a few turns with the contentOffset to get right.
Starting off;
Add the scrollView at frame (0,0,320,480) - its a full screen scroller
set contentSize to (320*3, 480) - it now has a content with the width of 3 'pages'
Add your imageView as a subview to the scrollView at frame (320,0,320,480)
set contentOffset of the scrollView to (320, 0) - this will move the content of the scrollView left, in the negative x direction by 320
Now your imageView will be on screen, but it will have a 320px width both on the left and right on the scroller content.
(Note that in the code below, i've simply added a UIView and not an imageView)
UIScrollView *scroller = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
scroller.delegate = self;
scroller.pagingEnabled = YES;
scroller.backgroundColor = [UIColor blueColor];
scroller.contentSize = CGSizeMake(960, 480);
UIView *imgView = [[UIView alloc] initWithFrame:CGRectMake(320, 0, 320, 480)];
[imgView setBackgroundColor:[UIColor redColor]];
[scroller addSubview:imgView];
[scroller setContentOffset:CGPointMake(320, 0)];
[self.view addSubview:scroller];
Does that help?
Actually the best solution to start in the middle of the scroller if you are in a iPhone you should
[scroller setContentOffset:CGPointMake(320, 0)];
[self.view addSubview:scroller];
And for iPad
[scroller setContentOffset:CGPointMake(1024, 0)];
[self.view addSubview:scroller];
Try setting the Content offset.
[scrollView setContentOffset:CGPointMake(320, 0.0)];
If you're simply looking to set where the scroller content should be positioned at the start, you could do so with the - (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated method which will scroll the content to the point specified in the method.
Let me know if this is not what you wanted to know, and I'll get back to ya!
Cheers.
The key to setting the starting point, is to assign bounds with xy coordinates different than zero. Like this
lazy var contentView: UIView = {
let size = CGFloat(5000)
let view = UIView(frame: CGRectZero)
view.frame = CGRectMake(0, 0, size, size)
view.bounds = CGRectMake(-size/2, -size/2, size, size)
return view
}()
func centerContent() {
let frame = UIEdgeInsetsInsetRect(self.scrollView.bounds, self.scrollView.contentInset)
let navigationBarHeight = self.scrollView.contentInset.top
let x = (self.scrollView.contentSize.width/2) - (frame.size.width/2)
let y = (self.scrollView.contentSize.height/2) - (frame.size.height/2) - navigationBarHeight
self.scrollView.contentOffset = CGPointMake(x, y)
}

Hide of tabbar shows whitespace (even if frame is fullscreen)

Trying to make fullscreen view in a tabbarcontroller. It's in landscape. Are able to hide the tabbar with self.tabBarController.tabBar.hidden = YES this leaves a whitespace where the tabbar have been.
Making the tabbarcontroller's view fullscreen with:
self.tabBarController.view.frame = self.view.frame = CGRectMake(0, 0, 480, 320);
[self.tabBarController.view setCenter:CGPointMake(160.0f, 240.0f)];
self.tabBarController.tabBar.hidden = YES;
self.tabBarController.view.backgroundColor = [UIColor redColor];
Then I try to make the viewcontrollers view fullscreen also. But it will not stick, unable to resize view.frame.
self.view.backgroundColor = [UIColor yellowColor];
self.view.frame = CGRectMake(0, 0, 480, 320);
[self.view setCenter:CGPointMake(160.0f, 240.0f)];
Is there anyway to get around this in a nice fashion?!
Image of whitespace (in red) were tabbar is gone
Set hidesBottomBarWhenPushed property to YES before pushing your viewController.
Did you try to play with autoresizingMask property of your view controllers instead of trying to resize manually the view frames ?
self.tabBarController.view.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
self.view.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);

How to display UIWebView with correct zoom scale in landscape

I create UIWebView and set autorotate like this:
- (void)loadView
{
self.view = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)] autorelease];
UIWebView *webview = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
webview.delegate = self;
webview.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"bg_darkgreen_320x312.png"]];
webview.dataDetectorTypes = UIDataDetectorTypeLink;
webview.multipleTouchEnabled = YES;
webview.scalesPageToFit = YES;
webview.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[webview loadHTMLString:#"<meta name=\"viewport\" content=\"width=320\">content ..." baseURL:nil];
[self.view addSubview:webview];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
It works perfectly when I rotate it in landscape without zooming. It will display full screen on both rotation.
The problem is if I zoom-out or a little bit zoom-in in portrait mode and then rotate it in landscape, webview still zoom with the same size of portrait mode and it has black space like in picture > http://cl.ly/1o3c4712053C3T2C2H2z
It's width in landscape is correct, 480px (you can see its scrollbar is on most right of screen). I don't understand why webview don't display full screen.
What I do wrong?
Is there any way to fix this?
Please help.
Thanks in advance.
In order to achieve your effect you need to set the zoomScale to 0 on rotation. See my full answer here: UIWebView content not adjusted to new frame after rotation

How to make UIScrollView respect the layout of the containing UIView?

I'm using a UIView to control the layout of my view (along with a view controller). I want UIScrollView to only use half of the vertical screen. That works fine if I use the upper half of the screen, but not the bottom half.
Here's the relevant code from the UIViewController:
- (void)loadView {
CGRect fullFrame = [[UIScreen mainScreen] applicationFrame];
//trying to put the scroll view on the bottom half of the screen, but does not work.
CGRect halfFrame = CGRectMake(0, fullFrame.size.height / 2 ,
fullFrame.size.width, fullFrame.size.height / 2);
//use this instead for the scroll view to go to the top half of the screen (and work properly)
//CGRect halfFrame = CGRectMake(0, 0 , fullFrame.size.width, fullFrame.size.height / 2);
UIScrollView* sv = [[UIScrollView alloc] initWithFrame:halfFrame];
[sv setContentSize:CGSizeMake(3 * halfFrame.size.width, halfFrame.size.height)];
CGRect stencilFrame = halfFrame;
UIView *leftView = [[UIView alloc] initWithFrame:stencilFrame];
stencilFrame.origin.x += stencilFrame.size.width;
UIView *centerView = [[UIView alloc] initWithFrame:stencilFrame];
stencilFrame.origin.x += stencilFrame.size.width;
UIView *rightView = [[UIView alloc] initWithFrame:stencilFrame];
//mix up the colors
[leftView setBackgroundColor:[UIColor redColor]];
[centerView setBackgroundColor:[UIColor greenColor]];
[rightView setBackgroundColor:[UIColor blueColor]];
//add them to the scroll view
[sv addSubview:leftView];
[sv addSubview:centerView];
[sv addSubview:rightView];
//turn on paging
[sv setPagingEnabled:YES];
UIView *containerView = [[UIView alloc]initWithFrame:fullFrame];
[containerView addSubview:sv];
[self setView:containerView];
}
Thank you in advance for any advice or help.
I figured it out. The crux of the problem is that views within the scroll view are initialized with the same frame as the scroll view itself. When the scrollView is initialized with halfFrame, the origin is (0, half the full screen size), which is ok since that is relative to the application window itself. However, the views that are put inside the scrollView (like leftView) are initialized to halfFrame, but in this case the origin is relative to the scrollView, effectively placing them off the screen. Setting the origin to (0,0) fixes this:
CGRect stencilFrame = CGRectMake(0, 0, fullFrame.size.width , fullFrame.size.height / 2);
contentSize must contain the rectangle of the view inside the scroll view. That is, the total size of all scrollable controls within. The frame of the UIScrollView decides how much scrolling is needed to let the user browse everything.
You don't have the "full frame" available if you have a nav bar or a tab bar. In general, code that uses [UIScreen mainScreen] for layout information is probably wrong.
Additionally, the status bar can change size if (for example) a call is in progress or tethering is enabled.
Instead, use any sane value for full frame and enable autoresizing:
CGRect fullFrame = {{0,0}, {320,480}};
...
sv.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleTopMargin;
EDIT: You also probably need to subclass UIScrollView and implement -setFrame: so that it also sets the content size and -layoutSubviews to do the correct layout.