ABPeoplePickerNavigationController with UITabBarController does not display correctly in iOS8

I have an application where UITabBarController is as rootViewController with two controllers. One is an empty controller and the second is a Picker controller coming from ABPeoplePickerNavigationController. The problem is that the view goes behind the tab bar, and because of this, the view is disabled from the bottom. I just highlighted the area in the screenshot:

enter image description here

Any help would be much appreciated.

+3


source to share


3 answers


ABPeoplePickerNavigationController

Doesn't officially support subclasses: link here

Subclassing Notes
The ABPeoplePickerNavigationController class does not support subclassing.

      

However, the problem is that the view of your subclass ABPeoplePickerNavigationController extends below the tab bar. You can, for example, resize it at runtime this way.

- (void) viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    CGRect rect = self.view.bounds;
    rect.size.height = rect.size.height - 40;
    self.view.frame = rect;
}

      

Note that 40 is just an example, you have to calculate the height of your tab bar controller because it might change for other screen sizes and rotations.

Or, better, you can find the underlying UITableView instance and set the property contentInset

.

EDIT This looks like status bar issues as ABPeoplePickerNavigationController

it cannot expand the navigation bar in the status bar if you change its frame



In both cases, however, your application is likely to be rejected because you subclass a class that explicitly disallows it.

The best and "legal" way to add it is using the container view controller

Take a look This example

Create a new view controller, add the container view, then add ABPeoplePickerNavigationController

like this:

-(void)viewDidLoad
{
    [super viewDidLoad];

    // create the ABPeoplePickerNavigationController instance
    ABPeoplePickerNavigationController *controller = [[ABPeoplePickerNavigationController alloc] init];

    // add a new child view controller to self
    [self addChildViewController:controller];

    // alert the child that it has been added to the father
    [controller didMoveToParentViewController:self];

    // update the child view frame to fit into the containerView
    controller.view.frame = self.containerView.bounds;

    // translate autoresizing mask into constraints, this is not needed but I usually do because is more pratical
    [controller.view setTranslatesAutoresizingMaskIntoConstraints:YES];

    // add the `ABPeoplePickerNavigationController` view to the container
    [self.containerView addSubview:controller.view];

}

      

Even so, ABPeoplePickerNavigationController

has problems with the status bar (it doesn't go right underneath it), so I limited the container view in the Top Layout Guide and changed the color of the main view ContainerViewController

to match the color of the navigation bar

+1


source


In viewWillAppear

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    self.topViewController.extendedLayoutIncludesOpaqueBars = YES;
}

      



In viewDidAppear

- (void)viewDidAppear:(BOOL)animated
{
    CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
    CGRect tabBarFrame = self.tabBarController.tabBar.frame;        
    self.view.frame = CGRectMake(0, statusBarFrame.size.height, self.view.frame.size.width, CGRectGetMinY(tabBarFrame) - statusBarFrame.size.height);
}

      

+1


source


A bit late to the party, but here is my answer to the problem, or at least some additional input for you to work out a complete solution.

The problem for me seems to be that since UIPeoplePickerNavigationController

it is not a subclass, or at least not recommended by Apple, you cannot use it completely the way you like. I mean, this is UIPeoplePickerNavigationController

intended to be used as a modal view that needs to be presented full screen on iOS and on top of all other controllers. You shouldn't try to use it as a push view controller on the navigation controller stack.

So my proposal is pretty straight forward. You just have to use yours UITabBarController

as the method receiver presentViewController:animated:completion:

. This will take care of presenting the modality on top of the tab bar.

You can access UITabBarController

via a property of tabBarController

your current controller:

ABPeoplePickerNavigationController *peoplePickerController = [ABPeoplePickerNavigationController new];
[peoplePickerController setPeoplePickerDelegate:self];
[self.tabBarController presentViewController:peoplePickerController animated:YES completion:^{}]

      

Note. I am writing this from memory, so there might be some errors in the method names.

0


source







All Articles