带有UITabBarController的ABPeoplePickerNavigationController在iOS8中无法正确显示

时间:2015-01-05 15:09:35

标签: ios objective-c iphone uitabbarcontroller

我有一个应用程序,其中UITabBarController作为带有两个控制器的rootViewController。一个是空控制器,第二个是Picker控制器,从ABPeoplePickerNavigationController扩展。问题是视图正在标签栏后面,并且由于该视图从底部切断。我刚刚在屏幕截图中突出显示了该区域:

enter image description here

任何帮助都将受到高度赞赏。

3 个答案:

答案 0 :(得分:1)

官方ABPeoplePickerNavigationController不支持子类化:link here

Subclassing Notes
The ABPeoplePickerNavigationController class does not support subclassing.

然而,问题是您的ABPeoplePickerNavigationController子类的视图正在标签栏下展开。 例如,您可以通过这种方式在运行时更改其大小

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

请注意,40只是一个示例,您应该计算标签栏控制器的高度,因为它可以更改其他屏幕尺寸和旋转。

或者,更好的是,您可以搜索基础UITableView实例并设置contentInset属性。

修改 这似乎与状态栏有问题,因为ABPeoplePickerNavigationController如果更改框架,则无法扩展状态栏下的导航栏

但是,在这两种情况下,您的应用可能会被拒绝,因为您正在继承明确禁止它的类。

添加它的更好和“合法”的方法是使用容器视图控制器

查看This Example

创建一个新的视图控制器,添加容器视图,然后以这种方式添加ABPeoplePickerNavigationController

-(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];

}

即使这样ABPeoplePickerNavigationController状态栏也有问题(它在它下面没有正确扩展),所以我将容器视图约束到顶部布局指南并更改了{的主视图的颜色{1}}以适应导航栏的颜色

答案 1 :(得分:1)

viewWillAppear

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

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);
}

答案 2 :(得分:0)

派对有点晚了,但这是我对这个问题的回答,或者至少是一些额外的输入,让你找到一个完整的解决方案。

我的问题似乎是,因为UIPeoplePickerNavigationController不是子类,或者至少不建议由Apple使用,所以无论如何都不能完全使用它。我的意思是UIPeoplePickerNavigationController意味着用作模态视图,应该在iOS上以及在每个其他视图控制器之上全屏显示。您不应该尝试将其用作导航控制器堆栈上的推送视图控制器。

所以我的建议很简单。您应该只使用UITabBarController作为presentViewController:animated:completion:方法的接收者。这将负责在标签栏顶部显示模态。

您可以通过当前视图控制器的UITabBarController属性访问tabBarController

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

注意:我是从内存中写的,所以可能会有一些方法命名错误。