I have a .nib file created in Interface Builder with 1 UIView item, but when I initialize it programmatically, the view doesn't cover up the entire screen, leaving a small portion of the view beneath it visible.
It looks like the Y coordinate is at some negative position instead of at 0. I don't have a Navigation bar configured for the view but if I were to set it, the bar doesn't get shown.
I'm creating the view like this inside the appDelegate class:
MyCustomController *controller = [[MyCustomController alloc] initWithNibName:#"MyCustomView" bundle:nil];
[window addSubview:[controller view]];
Settings in Interface Builder for the view:
Orientation: Portrait
Status Bar: Gray
Top Bar: unspecified
Bottom Bar: unspecified
View mode: "Scale To Fill"
View Size/Position: Set to "Layout" and the X/Y, Width/Height are readonly with 0,0,320,460
I've printed out the view's frame and [[UIScreen mainScreen] bounds] on 'viewWillAppear':
view.frame on viewWillAppear - x: 0.0, 0.0, 320.0, 460.0
bounds - x: 0.0, 0.0, 320.0, 480.0
I'm not sure why the view is getting shifted - what's the best place to read just the frame size once the view is loaded by the 'initWithNibName' method? That seems to be the workaround I can think of.
I wrapped my controller with a UINavigationController and the problem went away.
Related
I want the view of my current UIViewController to take the whole screen (without the status bar) when I hide the UINavigationBar. It doesn't have to be animated. I can't figure out how to change the frames. I should mention also that I am using a nib, so in the Interface Builder I have selected Simulated Metrics : Navigation Bar, I don't know if it makes any difference.
Try this:
// On YourViewController.m
// Call this method when the nav bar gets hidden
- (void)navigationBarDidBecomeHidden {
self.view.frame = CGRectMake(0, 0, 320, 480);
}
I have an iPad application with fixed landscape orientation. Everything works OK until the moment when I programmatically create UIView and add it to my root UIViewController's view - it's orientation is always set to portrait while all other content is displayed in landscape mode. This UIView is a modal view showing some custom form for user.
AlertView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height)];
AlertView.opaque = NO;
AlertView.backgroundColor = [UIColor blackColor];
AlertView.alpha = 0.7;
<...> // some other configuration code
[window addSubview:AlertView];
So the question is: how can I initiate UIView with landscape orientation? All I can think of is using transform like:
modalView.transform = CGAffineTransformMakeRotation( ( 180 * M_PI ) / 360 );
Though it's not too elegant way...
The reason your AlertView gets displayed in portrait orientation while the rest of your app gets displayed in landscape is because you are adding the AlertView as a subview of your window rather than adding it as a subview of a view controller's view. This places it outside of the view hierarchy that gets transformed automatically through autorotation.
The app's window object coordinates autorotation by finding its topmost subview that has a corresponding view controller. Upon device rotation, the window calls shouldAutorotateToInterfaceOrientation: on this view controller and transforms its view as appropriate. If you want your view to autorotate, it must be a part of this view's hierarchy.
So instead of [window addSubview:AlertView];, do something like [self.view addSubview:AlertView];.
You should try setting an autoresizing mask.
When the ViewController rotates, your AlertView's bounds would change, too.
yourView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
To make UIViews in landscape orientation, and provided you want your root view controller to always be in portrait mode, you have 2 options:
Do it the way you are doing it by rotating the UIView using a transform
Change the way you are doing it to allow
your root view controller to rotate (easiest). The view controller will then handle the rotations of your UIViews for you
If I use a UINavigationController to display my UINavigationBar, this bar is much slimmer in landscape mode than in portrait mode.
Everything fine so far, as I want this behavior, but I have one view which isn't handled by an UINavigationController and so I just dragged and dropped a UINavigationBar from Interface Builder into the view but this one has always the same size and I can't see a way to tell the UINavigationBar that it should resize.
Anyone knows how to achieve this?
You can resize the the navigation bar in the layoutSubviews method of your UIView, like so:
- (void)layoutSubviews {
[super layoutSubviews];
// Let navBar tell us what height it would prefer at the current orientation
CGFloat navBarHeight = [navBar sizeThatFits:self.bounds.size].height;
// Resize navBar
navBar.frame = CGRectMake(0, 0, self.bounds.size.width, navBarHeight);
}
I have an issue with a UINavigationBar and its y-offset. The bar is displayed without a UINavigationController as superview, yet that should not matter. In the viewController where the navigation bar appears the setup looks like this:
// Add Basic View
CGRect viewFrame = [[UIScreen mainScreen] applicationFrame];
UIView *myView = [[UIView alloc] initWithFrame:viewFrame];
myView.backgroundColor = [UIColor greenColor];
self.view = myView;
[myView release];
UINavigationBar *myBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 50)];
.... add some Stuff to the bar...
[self.view addSubview:myBar];
[myBar release];
As I add the navigationBar as a chield View to self.view I assumed that origin.y = 0 would mean that the bar should get directly displayed below the status bar. This works as expected if I start the app on my iPad, rotate it once (or more) and then drill down to the view that is described above. In this case the UINavigationBar is displayed properly. Yet if I start my app and directly drill down to the controller described above (without rotating the device before this particular controller appears) the navigation bar slides 20 points below the status bar. But as soon as I rotate the device then, the bar is fine again. I have checked the viewFrame.origin.y value and it is 20 points in both situations, hence I do not understand why in one case the bar just seems to ignore the origin.y value of its superview but does not in the other.
I am really confused about this, has anybody else ever experienced such an issue?
Thanks a lot for your help!
Ps. I have also tried it with a UIToolbar, the problem is the same.
Yes. My solution is to set the "Full screen on launch" flag to on in Interface Builder for the window in the MainWindow-iPad.xib file. Then design your views as if the 20 pixel status bar were always displayed, so in my root view, I have a toolbar that is positioned 20px below the top of the screen in the content view.
Edit 2: When I start the app without the status bar on top everything behaves as planned. With the status bar I couldn't get the views to act as I wanted. It looks as if the UINavigationController keeps resizing the content view by subtracting the 20 pixels of the status bar. I don't know.
I created a simple UINavigationController-based application. The root view in this navigation controller is a UITableView. At a certain time I want to slide in a 80 pixel high view from the bottom. The whole view on the top (the one that is controlled by the UINavigationController) should resize and get 80 pixel smaller to make room for the new bottom view.
This is basically the code I use to repositioning the views:
-(void)showTeaser {
float adHeight = 80;
[adView setFrame:CGRectMake(0.0,self.navigationController.view.bounds.size.height, 320.0, 80.0)];
[[[UIApplication sharedApplication] keyWindow] addSubview:adView];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[adView setAlpha:1.0];
[adView setFrame:CGRectMake(0.0,self.navigationController.view.bounds.size.height-adHeight, 320.0, 80.0)];
[self.navigationController.view setFrame:CGRectMake(0.0,0.0, 320.0, self.navigationController.view.bounds.size.height-adHeight)];
[self.view setFrame:CGRectMake(0.0, 0, 320.0, self.view.bounds.size.height-adHeight)];
[UIView commitAnimations]; }
I lowered the Navigationbar's alpha, set the UITableviewController's view to red. The new view is purple.
This is what happens. First screenshot initial state. Everything is looking normal. Second screenshot shows state after changing the frames. The view of the UITableviewController is always pushed 20 pixel under the Navigationbar. Also, if I try to add more views to the keywindow, they always end up 20 pixel higher than I expect. It almost looks like the keywindow (minus the navigation bar) is pushed up 20 pixel.
Edit 1: No matter to what size I resize the view, it's always 20 pixel.
Do I make a mistake by adding views to the keywindow at all? Shouldn't I do this?
alt text http://www.hans-schneider.de/iphone-seo/1.png alt text http://www.hans-schneider.de/iphone-seo/2.png
To solve this, I made the view of the UINavigationController a subview of a UIView, and manually set the bounds of the view for the `UINavigationController'.
//outerView is a UIView defined in the interface
outerView = [[UIView alloc] initWithFrame:CGRectMake( 0.0, 0.0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);];
//mainNavigationController is a UINavigationController defined in the interface
//rootViewController is a UIViewController (or inherited class) defined in the interface and instanced before this code
mainNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
//set the frame for the view of the navigation controller - 20 is due to the status bar
mainNavigationController.view.frame = CGRectMake( 0.0, 20.0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height - 20);
Then later, when I go to resize, I resize the parent 'UIView' rather than the 'UINavigationController' view.
//change the outer view's frame to resize everything
//adHeight is a float defined earlier
outerView.frame = CGRectMake( 0.0, 20.0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height - 20 - adHeight);
This works well in an animation sequence.
Edit 2011-05-12: I updated the outerView frame to fill the screen. This must be set to allow for touch events.
Have you tried using the transform property of your tableview instead of manually changing it's frame? It may work out better, since the frame depends on the origin, and you only want to change it's size.