Custom UIView covering UITabBar on iPhone but not iPad - iphone

I'm creating a custom uiView that covers the window. It acts kinda like a decoy uiview in a navigation controller. So I had to do it this way to cover the navigation bar.... long story...
Here is how it gets setup.
self.searchPopDown.frame = CGRectMake(0, 20, self.navigationController.view.frame.size.width, self.navigationController.view.frame.size.height-20);
self.searchPopDown.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
The 20 is to compensate for the status bar.
Then I simply add the view as a subview to the app window.
//this will add the view ontop of a modalViewController and support rotation!
UIWindow* window = [UIApplication sharedApplication].keyWindow;
if (!window) {
window = [[UIApplication sharedApplication].windows objectAtIndex:0];
}
if ([[[window subviews] objectAtIndex:0] isKindOfClass:[SVProgressHUD class]]){
//There is a chance that the window will be the SVProgressHUD in this case we need to get the main window.
window = [[UIApplication sharedApplication].windows objectAtIndex:0];
}
[[[window subviews] objectAtIndex:0] addSubview:self.searchPopDown];
All of this works great and dandy. However I've noticed something strange. On the iPhone this view will end up being resized to cover the UITabBar at the bottom of my app. But on an iPad it gets resized correctly to compensate for the UITabBar. Any ideas why?
Thanks
=================
Here are some screenshots describing the issue. This is what it looks like when the view loads with the fake view onto of everything. The view shows up (as far as the user is concerned just the view and the buttons on the navbar have changed slightly. When you have searched this fake view disappears revealing the real view below with the search results. ON the ipad the fake view doesn't cover the tab bar. Why doesn't it do this on the iphone also?
==========
edit 2
Another weird thing. I'm generating log messages to get what the height of the navigation controller is. It changing by 49 depending on if I display normally or present as a modal view and there is no tab bar.
So the log says 431 should be the correct height. I go into interface builder and setup a simple pink view that's measured at 431 and it looks great :) However when I manually set the size to 431 it doesn't work. I have to set the size to 298 to get this to work correctly ... weird...
See the pink bar? It is literally 431 tall... and the log says that's what my view is.. but it's not :/
============
edit:3
I have traced this to the imagebackground with the bubble logo resizing incorrectly...

I had to check "clip subview" on the parent view that the imageview was in... fixed the problem...

Related

How to make a view have a semi-transparent border and show the view below

Probably a bit of a newbie question, but .... I am writing an iPhone app which uses UITabBarController.
In Interface Builder I've setup the tab bar in MainWindow.xib. I have 4 tabs, and each one is set to load the xib for the appropriate UIViewController subclass. I have created the views in the xib files for each UIViewController subclass in Interface Builder.
All is working well in that I can tap each tab and it shows the view for the correct UIViewController
But what I really want is for the view for one of the UIViewController subclasses to have a semi-transparent border of approx 30px on all 4 edges, so that it shows the edges of the view behind, kind of greyed out.
IE. the first tab is the main application, and that takes up the whole screen (minus the status and tab bar areas).Tab 2 is to save, and I want it to look like a small modal window over the top of the main app.
(If I were doing this as a html web app, the terminology and technology I'd be using would be a jQuery overlay)
Does this make sense?
I've tried playing with presentModalViewController but this makes it worse in that it takes up the entire screen including the status and tab bar areas.
Any help or pointers very much appreciated
Cheers
Nathan
Your UIViewController cannot be transparent to the view below it because the iphone may unload the view below it that is not currently being shown (to save memory).
The best solution I have used is to take a picture of the current view before you push your new view controller and then use that as the background image (fake the transparency). Here's how I implemented this:
NewViewController *newView = [[NewViewController alloc] init];
shareVC.imageBackground = [Utilities getScreenshot:self.view];
[self presentModalViewController:newView animated:YES];
[newView release];
then on your newViewController do this (on viewDidLoad, viewWillAppear, etc):
[imageView setImage:imageBackground];
and here's the screenshot function
+(UIImage *)getScreenshot:(UIView *)_view {
//take a screenshow of the parent view so we can add it as a background to the modal view
if ([[UIScreen mainScreen] respondsToSelector:#selector(scale)])
UIGraphicsBeginImageContextWithOptions(_view.window.bounds.size, NO, [UIScreen mainScreen].scale);
else
UIGraphicsBeginImageContext(_view.window.bounds.size);
[_view.window.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
You then need to setup your new view with a UIImageView as the background and pick the right Alpha value for that imageView to make it appear like it's transparent.

Non Selected Tab Bar View Controllers aren't resized when device rotated

I'm having problems making my app iPad compatible.
I have an implementation of a custom Tab Bar, based on the post here http://www.wiredbob.com/blog/2009/4/20/iphone-tweetie-style-navigation-framework.html
That all works fine apart from when the device is rotated. The currently selected view rotates and resizes perfectly. Every other view rotates but does not resize to fill the space. There is a large white column down the right hand side.
I've tried adding
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.view.autoresizesSubviews = YES;
to the tab controller view.
I've added similar code to the tab's views viewDidLoad methods.
I've tried to make the willRotateToInterfaceOrientation call all the subviews rotation methods but still no luck.
Any suggestions would be more than welcome at this stage. I'm hoping i'm not overlooking something obvious but i might be. I've been at it for a few hours now
Screenshot 1 -
Screenshot
Ok I Solved this problem.
What I had to do was manually call a resize on all the sub views. - i added a changeFrameSize function to each sub view (just so it made the code look a little nicer)
Oh and when adding views as sub views always use belowSubView method -
[self.view insertSubview:viewController.view belowSubview:tabBar];
-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
[(ViewControllerClass *)[viewControllers objectAtIndex:0] changeFrameSize:[NSNumber numberWithFloat:self.selectedViewController.view.bounds.size.width] height:[NSNumber numberWithFloat:self.selectedViewController.view.bounds.size.height]];
[(ViewControllerClass *)[viewControllers objectAtIndex:1] changeFrameSize:[NSNumber numberWithFloat:self.selectedViewController.view.bounds.size.width] height:[NSNumber numberWithFloat:self.selectedViewController.view.bounds.size.height]];
[(ViewControllerClass *)[viewControllers objectAtIndex:2] changeFrameSize:[NSNumber numberWithFloat:self.selectedViewController.view.bounds.size.width] height:[NSNumber numberWithFloat:self.selectedViewController.view.bounds.size.height]];
}
So because the selected view controller was always rotated and resized to the correct size, once it had rotated and adjusted i simply passed the same parameters to the sub views so they would resize too.

Why are Views loaded from nibs being placed 20 pixels down from the status bar?

I am trying to set up a layout as such in an iPad application. It will have three major views, which make up the whole screen. The views will be stacked one on top of the other, each taking up the full width. I have one major nib file which accounts for the entire screen space. In that nib file, I am instantiating the three view controllers with outlets. Then I have this code:
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:controllerOne.view];
[self.view addSubview:controllerTwo.view];
[self.view addSubview:controllerThree.view];
}
This adds the views on top of one another and 20 pixels lower. However, after rotating to landscape and back they are right under the status bar. Do you know what would be causing this?
I figured out the cause of this. When you are editing the View Controller in Interface Builder, I needed to uncheck "Resize View from Nib." Then it comes in at the frame I set and stays in the right place.

iPhone: calling UIImagePickerController 'moves' the view that calls it

I recently encountered very strange behaviour with the UIImagePickerController. On our main view we have a button that calls the image picker controller. If you hit cancel on the image picker, I simply dismiss the controller, and for some reason or another my main view moves down roughly about the height of the status bar (which is not turned off on the main view, left at default gray). Anyone else encounter this?
Yeah I saw that post, and it didn't fix my issue. What I ended up doing was adding this in my app delegate before adding my first view to the window:
CGRect theRect = mainMenuController.view.frame;
float statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
theRect = CGRectOffset(theRect, 0.0,statusBarHeight);
mainMenuController.view.frame = theRect;
This fixed it completely.
This problem is annoying, its been discussed before, check it out Contents of UIScrollView shifted after dismissing ModalViewController

UIView Clipped By Statusbar until Autorotate

Ive created a multiview application that uses multiple controllers to display and control views. The problem Im having is, when the simulator initially loads the view the header is partially covered by the bar at top of screen and the tool bar at the base is not touching the base of the screen. I used the Interface builder size attributes to control the view when the iphone rotates and it works perfectly. All smaps into place perfectly both in landscape and portrait mode AFTER a rotation but the problem is with the initial load before a rotation occurs.
Your thoughts a much appreciated.
Tony
I grappled with this issue for days and days--no amount of fiddling in IB worked.
Ultimately I got it to work by adding this line:
mainViewController.view.frame = window.screen.applicationFrame;
to the application:didFinishLaunchingWithOptions: method. (Where mainViewController is the primary UIViewController).
I've had issues with views being clipped by status, nav, and tab bars. I've fixed most of them by using the Simulated Metrics feature in Interface Builder. That way what your laying out in IB is a lot more accurate to what your actually going to get.
I ran into this issue too. Specifically, when displaying an ADBannerView, my whole view would shift and be under the status bar and leave a little empty space just the size of the status bar at the bottom of the iPhone screen. Here's how I solved it : (Adam's answer here helped me figure this out):
// In the function that displays an iAD Banner
CGRect contentFrame = self.view.bounds;
CGRect myStatusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
CGFloat statusHeight = myStatusBarFrame.size.height;
// Set the view's origin to be under the status bar.
contentFrame.origin.y = statusHeight;
I needed to set the origin of my view to be below the Status bar, and that solved the issue for me.
The problem is that you're adding your controller "incorrectly" according to Apple docs (although IMHO Apple designed it badly - the default should be that you don't need to shift!)
if you're going to have a status bar, Apple requires that you "manually" shift all your controllers down by 20 pixels (more accurately, by the height of the statusbar - although that's always 20 pixels today, Apple lets you request the height at runtime, from the "statusBarFrame" property in UIApplication)
Apple's classes - e.g. UINavigationController / UITabBarController - automatically shift themselves down by 20 pixels when they're added to the screen. Both classes have a bug where they will do this shift even if they are not the main controller - so your app suddenly shifts down an extra 20 pixels, leaving 20 pixels of white space at top.
But, when they rotate, those classes often "get it right" and move back into place. Or vice versa.
c.f. this link for a much more detailed explanation of what's going on, and how to write your code the way Apple wants you to:
http://blog.red-glasses.com/index.php/tutorials/iphone-auto-rotation-for-intermediate-developers-tutorial-1/