带有 UITabBarController 的 ABPeoplePickerNavigationController 在 iOS8 中未正确显示
ABPeoplePickerNavigationController with UITabBarController is not showing correctly in iOS8
我有一个应用程序,其中 UITabBarController 作为具有两个控制器的 rootViewController。一个是空控制器,第二个是从 ABPeoplePickerNavigationController 扩展的 Picker 控制器。问题是视图在选项卡栏后面,并且由于该视图从底部被切断。我刚刚在屏幕截图中突出显示了该区域:
非常感谢任何帮助。
官方ABPeoplePickerNavigationController
不支持subclassing:link here
Subclassing Notes
The ABPeoplePickerNavigationController class does not support subclassing.
但是,问题在于您的 ABPeoplePickerNavigationController subclass 的视图在选项卡栏下扩展。
例如,您可以通过这种方式在运行时更改它的大小
- (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
无法扩展状态栏下的导航栏,如果您更改它的框架
然而,在这两种情况下,您的应用程序可能会被拒绝,因为您正在提交 class 明确禁止它的 class。
更好的 "legal" 添加它的方法是使用容器视图控制器
创建一个新的视图控制器,添加一个容器视图,然后按此方式添加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
状态栏也有问题(它不能在其下正确延伸),所以我将容器视图限制在顶部布局指南并更改了主视图的颜色ContainerViewController
以适应导航栏的颜色
在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);
}
聚会有点晚了,但这是我对问题的回答,或者至少是一些额外的输入,以便您制定出完整的解决方案。
对我来说问题似乎是因为 UIPeoplePickerNavigationController
不是可子类化的或者至少 Apple 不推荐这样子类化,所以您不能随心所欲地完全使用它。我的意思是 UIPeoplePickerNavigationController
旨在用作模态视图,它应该在 iOS 上全屏显示并位于所有其他视图控制器之上。您不应尝试将其用作导航控制器堆栈上的推送视图控制器。
所以我的建议很直接。您应该简单地使用 UITabBarController
作为 presentViewController:animated:completion:
方法的接收者。这将负责在选项卡栏顶部呈现模式。
您可以通过当前视图控制器的 tabBarController
属性 访问 UITabBarController
:
ABPeoplePickerNavigationController *peoplePickerController = [ABPeoplePickerNavigationController new];
[peoplePickerController setPeoplePickerDelegate:self];
[self.tabBarController presentViewController:peoplePickerController animated:YES completion:^{}]
注意:我是凭记忆写的,所以可能有一些方法命名错误。
我有一个应用程序,其中 UITabBarController 作为具有两个控制器的 rootViewController。一个是空控制器,第二个是从 ABPeoplePickerNavigationController 扩展的 Picker 控制器。问题是视图在选项卡栏后面,并且由于该视图从底部被切断。我刚刚在屏幕截图中突出显示了该区域:
非常感谢任何帮助。
官方ABPeoplePickerNavigationController
不支持subclassing:link here
Subclassing Notes
The ABPeoplePickerNavigationController class does not support subclassing.
但是,问题在于您的 ABPeoplePickerNavigationController subclass 的视图在选项卡栏下扩展。 例如,您可以通过这种方式在运行时更改它的大小
- (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
无法扩展状态栏下的导航栏,如果您更改它的框架
然而,在这两种情况下,您的应用程序可能会被拒绝,因为您正在提交 class 明确禁止它的 class。
更好的 "legal" 添加它的方法是使用容器视图控制器
创建一个新的视图控制器,添加一个容器视图,然后按此方式添加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
状态栏也有问题(它不能在其下正确延伸),所以我将容器视图限制在顶部布局指南并更改了主视图的颜色ContainerViewController
以适应导航栏的颜色
在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);
}
聚会有点晚了,但这是我对问题的回答,或者至少是一些额外的输入,以便您制定出完整的解决方案。
对我来说问题似乎是因为 UIPeoplePickerNavigationController
不是可子类化的或者至少 Apple 不推荐这样子类化,所以您不能随心所欲地完全使用它。我的意思是 UIPeoplePickerNavigationController
旨在用作模态视图,它应该在 iOS 上全屏显示并位于所有其他视图控制器之上。您不应尝试将其用作导航控制器堆栈上的推送视图控制器。
所以我的建议很直接。您应该简单地使用 UITabBarController
作为 presentViewController:animated:completion:
方法的接收者。这将负责在选项卡栏顶部呈现模式。
您可以通过当前视图控制器的 tabBarController
属性 访问 UITabBarController
:
ABPeoplePickerNavigationController *peoplePickerController = [ABPeoplePickerNavigationController new];
[peoplePickerController setPeoplePickerDelegate:self];
[self.tabBarController presentViewController:peoplePickerController animated:YES completion:^{}]
注意:我是凭记忆写的,所以可能有一些方法命名错误。