I'm doing a navigation based app. My rootview is a UITableView and from that I'm navigation to a UIView. For some reason the height of the UIView seems bigger than it should, meaning that the bottom of the view is not showing.
I did a really simple test using a UITextView with a button at the bottom, and only the top half of the button shows in the view when i run it in Simulator even though the height is set to 460.
Here's the code I use to navigate:
TestViewController *t = [[TestViewController alloc] initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:t animated:YES];
In my test the .xib is just made in IB dragging a textview and a button to the UIView.
I don't have the same issue when I'm navigating to another UITableView.
What am I missing?
Make sure you have those in the IB
view.autoresizingMask = UIViewAutoresizingFlexibleHeight;
textView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin;
button.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
which means that the viewControllers' view gets resized by the navigationController, the textView gets resized by the main view and the distance from the top stays the same as in your nib, and finally the distance from the bottom of the view stays the same for your button.
If you don't know how to translate these values in your IB UI, arrows is resizing and "I" is fixed distance to that side - left, top, right, bottom.
The height of the view in a navigation based app should be 480 - statusbarHeight (=20) - navigationBarHeight (=44) = 416 pixels
Related
So I am using WEPopover to display a custom view controller pop up. I have a UIView in which inside it has another UIView called containerView. Inside this containerView, I have a UIButton. This is where I wanted to present my popover from. So here's what I did:
[self.popoverDialog presentPopoverFromRect:sender.frame inView:self.containerView permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
The issue is that the arrow and everything is showing from this button, but the popover goes out of self.containerView bounds. How can I make it so that the popover is displayed within the containerView bounds?
EDIT:
A picture is worth a thousand words, so here it is:
The light gray is the containerView I mentioned above. THe popover theoretically should be shown within that light gray bounds not going outside.
For the view that is contained inside the popover, go to it's view controller and set it's property contentSizeForViewInPopover. Here you can set the size so that it fits the bounds of your containerView.
OP wants to position the popover so that it only shows up in his container view. I found this bit of code in the WEPopoverController.m file
- (void)repositionPopoverFromRect:(CGRect)rect
inView:(UIView *)theView
permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections {
CGRect displayArea = [self displayAreaForView:theView];
WEPopoverContainerView *containerView = (WEPopoverContainerView *)self.view;
[containerView updatePositionWithAnchorRect:rect
displayArea:displayArea
permittedArrowDirections:arrowDirections];
popoverArrowDirection = containerView.arrowDirection;
containerView.frame = [theView convertRect:containerView.frame toView:backgroundView];
}
You could possibly call this method and it might reposition your popover so that it is now inside your container viw.
I am trying to add a the UINavigationController UIToolbar to the top of the view, (under the navigation controller.
My view is a UITableViewController... so there is that to deal with. Currently I am just positioning the UIToolbar that appears at the bottom of the view where I want it to display using
[self.navigationController.toolbar setFrame:CGRectMake(0, 60, 320, 30)];
this positions the toolbar in the correct place I would like it to appear, However there is a problem with where its positioned, which I will explain.
When you set a UINavigationController toolbar to be displayed it puts itself at the bottom of the view and pushes the UITableView up so the toolbar does not cover the tableview. However when I change the position of the toolbar the tableview still thinks the toolbar is at the bottom of the screen meaning the toolbar does not meet flush at the bottom of the screen how I would like it too.
So my question is how can I get the toolbar to display directly below the navigation controller bar and push the tableview down abit to accommodate for the toolbar in its new position.
I hope this all makes sense, Any help I would like to than in advance and below is the current code I am using (all be it basic I am still abit perplexed about whats going on behind the scenes for this to happen).
- (void) viewDidLoad
{
//..
[self.navigationController setToolbarHidden:NO animated:YES];
[self.navigationController.toolbar setFrame:CGRectMake(0, 60, 320, 30)];
self.navigationController.toolbar.tintColor = [UIColor lightGrayColor];
//..
}
update
this is currently what the toolbar is doing to my tableview
Call setFrame on your UITableView to move it into positon.
float y = self.navigationController.toolbar.frame.origin.y + self.navigationController.toolbar.frame.size.height;
[myTable setFrame:CGRectMake(0, y, self.view.frame.size.width, self.view.frame.size.height-y)];
I am presenting a modal view controller. If it matters, it is scrolling up from the bottom. How can I control what portion of the screen it occupies?
EDIT: I have the following in the modal view controller. It's not helping.
- (void)viewDidLoad {
TestResultView *trv = [[TestResultView alloc]initWithTest: [Model m].currentTest];
self.view = trv;
trv.frame = CGRectMake(0, 320, 320, 160);
[trv release];
[super viewDidLoad];
}
You can modify the frame of the view controller, but if you're using UIViewController's -presentModalViewController:animated: method, the view behind will be unloaded once your modal view is finished animating onto the screen (This assumes you're on an iPhone) and you'll see a white screen where your background view should be. iOS assumes that your modal view controller will be a full-screen view controller, and dumps the other view to save memory.
If you really want to show a view over part of the screen, you should instead add the UIView (no UIViewController) to your current UIViewController's view as a subview, and then animate it onscreen yourself. I think something like this would work in your UIViewController class that will present the view:
// Add the view as a subview and position it offscreen just below the current view
UIView *myHalfView = [[UIView alloc] initWithFrame:someAppropriateFrame];
[self.view addSubview:myHalfView];
CGRect offScreenFrame = myHalfView.bounds;
offScreenFrame.origin = CGPointMake(0.0, CGRectGetMaxY(self.view.frame));
// Now animate the view upwards
[UIView beginAnimations:nil context:nil];
// Move the view upwards the height of your sliding view so it's entirely onscreen
myHalfView.center = CGPointMake(myHalfView.center.x, myHalfView.center.y - myHalfView.bounds.size.height);
[UIView commitAnimations];
[myHalfView release];
For bonus points, you could fade the view in by setting
myHalfView.alpha = 0.0;
before the UIView animation block, and setting
myHalfView.alpha = 1.0;
inside the block after animating the center property.
When you're done, you can do something similar but in reverse to slide the view offscreen. You can add an animationDidStop selector to the UIView animation block to be notified when the view has slid off screen so that you can remove it from the view hierarchy.
From an aesthetic point of view, you should also be careful how you do this since having a view slide up is a standard behavior, and if your view looks like a normal view but stops halfway, users may feel (even briefly) that the app has frozen. They'll figure it out, but it will leave a bad feeling about your app if not handled carefully. Mainly, I would avoid using standard full-screen cues like including a UINavigationController at the top of your view to help users understand what's going on. Half-sheets tend to be UIActionSheets on the iPhone, so think in that direction.
That is nice, the above accepted answer explains a nice hack to present subViews which feel like ModalViews, but what if it is an iPad, and i can indeed give it a modalViewController which doesnt cover the entire screen.
In case of iPads, I dont think the underneath view will be unloaded. ( because there are options where we can present the modalView on iPads, which dont cover the entire screen )
ModalViewController in the end is a controller itself, and like any other controller has a root view, whose properties can be editted, if we can get hold of it.
Here is what will give you a custom frame of the ModalView :
MyViewController *viewController = [[MyViewController alloc] init];
viewConroller.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:viewController animated:YES];
//superView of viewController's view is modalViewController's view, which we were after
viewController.view.superview.frame = CGRectMake(x,y,w,h);
//x y w h - can have desired values.
I would add to #dsaw's answer that the superview of the modal view does not seem to rotate its coordinate system in landscape mode. Here is the code that I used in my own app:
MyViewController* modalVC = [[MyViewController alloc] init];
modalVC.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:modalVC animated:NO];
CGRect r = CGRectMake(self.view.bounds.size.width/2 - 236,
self.view.bounds.size.height/2 - 130,
472, 260);
r = [self.view convertRect:r toView:modalVC.view.superview.superview];
modalVC.view.superview.frame = r;
While the superview may not rotate itself with the iPad, it does seem to do the right thing and keep the modal view centered if I rotate the iPad after showing the modal view.
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.
I have a scrollview that I had to the view of the view controller pushed to a UINavigationController.
My navigation bar is opaque.
However, the scrollview seems to keep size of the whole parent view. I would like the scrollview to have the size of the space between the toolbar and the navigationbar.
Is this possible or do I have to hardcode some size values?
Thanks in advance
When you initialize your scrollView you can set its contentSize parameter:
[scrollView setContentSize:CGSizeMake(320,392)];
The height of the screen (480) minus the toolbar (44) and navigation bar (44) = 392. Drop that to 372 if you're also displaying the carrier status bar.
or, use the frame geometry properties:
[scrollView setContentSize:CGSizeMake((scrollView.superview.frame.size.width),
(scrollView.superview.frame.size.height -
toolbar.frame.size.height -
navigationController.navigationBar.frame.height))];
When you use autosize, the correct frame size is not known on viewDidLoad.
You should pack this inside viewWillAppear and then everything works fine
scrollView.contentSize = CGSizeMake(scrollView.superview.frame.size.width, scrollView.superview.frame.size.height);