I'm working on a project that displays a PDF using QLPreviewController from two different views. One view pushes the QLPreviewController onto the base navigation, and the other one is a modal view that brings the QLPreviewController up in modal.
I had issues when I initially set this up with the push including setting the nav bar opacity and the nav bar blocking my PDF. I was able to solve both issues by subclassing the QLPreviewController:
#import "CustomPreviewController.h"
#interface CustomPreviewController ()
#end
#implementation CustomPreviewController
-(id) init {
self = [super init];
if(self){
// init
} return self;
}
- (void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// set translucency of navigation bar
self.navigationController.navigationBar.translucent = NO;
// nav bar does not overlap content
self.edgesForExtendedLayout = UIRectEdgeNone;
self.automaticallyAdjustsScrollViewInsets = YES;
}
#end
However, now I need to view the same PDF from a different flow in the app. For this design I need a modal pop up to a UITableView, then either a push or a modal from that tableview to a PDF in the QLPreviewController. When I use the same push animation I get a delay and fracturing of the animation and a glitchy toolbar at the top. (See this post here). When I use a modal it animates smoothly but my UINavigationBar is hiding the top of the PDF and covering the page number. Similar nav bar symptoms to the push issues in the linked post. I have tried the solution proposed there, as well as attempting to hide the nav bar of the initial modal and the preview controller, to no avail.
This might be an Apple bug/issue but if anyone has discovered a usable workaround any suggestions would be welcome.
I've tried my app on iOS 7.1 and I found that the tab bar background disappears on a few occasions. I was able to track them down; it happens when:
pushing a view controller placed inside navigation controller (that is inside tab bar controller) with hidesBottomBarWhenPushed = YES
presenting a view controller and then dismissing it (i.e. the MFMailComposeViewController)
I've created a sample app (used the tab bar template + added button to display the view controller, and a mapView to be able to tell if the bar disappeared), and the issue is there.
Here is all the code for the sample app that I changed:
#import "FirstViewController.h"
#import MessageUI;
#interface FirstViewController () <MFMailComposeViewControllerDelegate>
#end
#implementation FirstViewController
- (IBAction)presentVCButtonPressed:(id)sender {
if ([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
mailer.mailComposeDelegate = self;
[mailer setSubject:#"Feedback for Routie"];
[mailer setToRecipients:#[#"support#routieapp.com"]];
[self presentViewController:mailer animated:YES completion:nil];
}
}
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
Here you can download the whole sample project.
Now, important thing: this seems not to affect iPhone 5, nor the simulator. The problem is on iPhone 4 and iPod Touch (last generation as of writing this post).
Does any of you have the same problem? Were you able to fix it?
Thanks!
Update: I found a workaround. See my answer below.
Fix found!
So after some investigating (and headache), I found out that there is a simple fix. Just toggle the translucent property, like this:
tabBar.translucent = NO;
tabBar.translucent = YES;
Now as for when to do this, there are several places for each case:
1) pushing viewController with hidesBottomBarWhenPushed = YESThe bar background disappears right after the pop animation finishes, so add the fix to the viewDidAppear: method of the viewController that presented it:
- (void)viewDidAppear:(BOOL)animated {
self.navigationController.tabBarController.tabBar.translucent = NO;
self.navigationController.tabBarController.tabBar.translucent = YES;
...
}
2) Presenting a view controller and then dismissing it:In this case, the tab bar background is already gone during the dismiss animation. You can either do it in each viewController that you present separately, or, if you have subclassed UITabBarController (like I have), you can add it into its viewWillAppear method. Just be aware that calling the fix right away won't help (I've tried); that's why I used the dispatch_after GCD function:
- (void)viewWillAppear:(BOOL)animated {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.tabBar.translucent = NO;
self.tabBar.translucent = YES;
});
...
}
I know this is not the cleanest way, but it's clearly bug on Apple's side, and it's likely to stay with us for a while (I assume there won't be any iOS 7.2, so we'll most likely be stuck with this until iOS 8 comes out).
It's been a while, so I'll re-iterate the issue. iOS 7 (on Device) Tab Bar becomes completely see-through on device, but works fine on Simulator. Appears to happen after hitting Back from a detail page that has hidesBottomBarWhenPushed enabled.
Setting the Tab Bar Controller > Tab Bar > Background to White Color in the Storyboard fixed it for me. This fix keeps the translucency intact.
For some reason, toggling tabBar.translucent off and on again in ViewDidAppear did not work for me.
Using Xcode 6.3.1 with Swift.
Go in your Main.storyboard and select your MKMapView to highlighted it (cf. in Navigator area you can select « Map View »). Then look carefully where is the bottom "white square": move it up the bottom bar!
In the size inspector, you can check where you place the « anchor » or view origin for this view (cf. top-left hand side in your project). This explains why it’s ok for iphone 5 which has a bigger height screen.
i'm implementing a project with XCODE 5 and storyboard. I have added a view that is a UIPageViewController and when i alloc the first page (for this pageviewcontroller) the view appears normally but from second page the view appears under the navigation bar. What is the matter?
If i set this property
self.navigationController.navigationBar.translucent = NO;
for the view displayed the problem is solved but when i go back from Page View Controller to previous View, the buttons on it are shifted down.
Why? What is the solution?
Furthermore if i set translucent = NO the views displayed in storyboard are different from views displayed in my app (the views are not shifted in storyboard).
I can't post images because i'm not authorized.
This is the code of my PageViewController
- (void)viewDidLoad
{
[super viewDidLoad];
variabiliGlobali = [foaGlobalVariable sharedInstance];
variabiliGlobali.giornataCalID = 1;
numeroGiornate = [variabiliGlobali.calendario count];
self.dataSource = self;
foaGiornataViewController *initialView = [[foaGiornataViewController alloc] init];
// Do any additional setup after loading the view.
[self setViewControllers:[NSArray arrayWithObject:initialView]
direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:NULL];
}
The foaGiornataViewController is a view that doesn't exist on storyboard but is only a objective-c class.
Thanks in advances.
I have solved. I have setted opaque navigation bar for my Navigation Controller on storyboard.
I run into a layout problem in iOS 7:
To reproduce create a simple master-detail-app and insert this line in MasterViewController.m :
self.navigationItem.prompt = #"Master";
and this in DetailViewController.m :
self.edgesForExtendedLayout = UIRectEdgeNone;
Both lines in viewDidLoad.
The detail view's frame does not update correctly when the navigation bar shrinks to its normal size.
How should I fix this?
My current solution to this is to remove the prompt in the master view's viewWillDisappear:
- (void) viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
self.navigationItem.prompt = nil;
}
Then just set it again in the viewWillAppear. There should be a better method, however.
I am making an app which has a UITabBar and a UINavigationConroller. When I click around the app, the nav item on top of the screen appears and so does the UITabBar on the bottom of the screen.
But when I click on one of the UITabBar items, it does go to the screen it is supposed to go to, but for some reason the UINavigationItem disappears.
Would anyone know why this happens?
Thanks!
IN all of your ViewController use the following Code.
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:NO];
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[self.navigationController setNavigationBarHidden:YES];
}
When you want to show Navigationcontroller use Hidden:NO