两个相同的标签视图中的UITableView表现不同

时间:2014-10-31 08:01:37

标签: objective-c xcode uitableview debugging uisearchbar

我创建了一个简单的项目来演示这种奇怪的行为。我在界面构建器中创建了所有这些,而没有触及代码,因此您可以轻松地重现。 StoryBoard


起始页面嵌入在仅包含一个按钮的导航控制器中,单击该按钮时,屏幕将定向到选项卡视图(顶部带有导航栏)。
运行程序时发生了两件奇怪的事情。

1)标签item2的表格视图位于导航栏下方,正确显示item1。
correctincorrect的对比
如您所见,尽管两个表视图位于完全相同的位置,但程序运行时,第二个甚至会因为对齐不正确而隐藏搜索栏。


2)单击选项卡项1中的搜索栏时,导航栏不会隐藏作为默认行为(导航栏隐藏,搜索栏显示)。
由于导航栏是半透明的,我可以看到导航栏下面的“取消”按钮。(任何一个有良好眼睛的人都可以看到屏幕截图右上角的蓝色色调)。这意味着搜索栏会转到正确的位置,但导航栏不会消失。
incorrct again
另请注意,当搜索栏处于活动状态时,表格视图不会随搜索栏向上移动(同样,默认行为)。

PS:我正在使用XCode 6.此外,我尝试向tableviewcontrollers添加约束,但没有骰子。
有什么想法吗?提前谢谢。

2 个答案:

答案 0 :(得分:0)

正如逻辑学家建议的那样,您可以为每个选项卡添加导航控制器作为选项卡的第一个控制器。如果您不想这样做,可以在第二个项目视图控制器的viewDidLoad中添加以下代码。

CGFloat shiftDist = CGRectGetHeight(self.navigationController.navigationBar.frame) + CGRectGetHeight([UIApplication sharedApplication].statusBarFrame);
self.tableView.contentInset = UIEdgeInsetsMake(shiftDist,0, 0, 0.0f);
self.tableView.contentOffset = CGPointMake(0, -shiftDist);

之后,存在旋转问题。你会注意到如果你旋转到横向,搜索栏不会粘在导航栏下面。以下是如何修复它。

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator NS_AVAILABLE_IOS(8_0);{

    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];

    CGFloat heightBeforeRotation = CGRectGetHeight(self.navigationController.navigationBar.frame) + CGRectGetHeight([UIApplication sharedApplication].statusBarFrame);
    CGFloat offsetY = self.tableView.contentOffset.y;

    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context)
     {

     } completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
     {
         CGFloat heightAfterRotation = CGRectGetHeight(self.navigationController.navigationBar.frame) + CGRectGetHeight([UIApplication sharedApplication].statusBarFrame);
         self.tableView.contentInset = UIEdgeInsetsMake(heightAfterRotation,0, 0, 0.0f);
         self.tableView.contentOffset = CGPointMake(0, heightBeforeRotation + offsetY - heightAfterRotation);
     }];
}

答案 1 :(得分:0)

问题是如何显示标签栏控制器。选项卡栏控制器很特殊,通常应该是故事板中的初始视图控制器。 如果标签栏控制器不是初始视图控制器,那么它应该以模态方式呈现。在我的测试应用程序中,我将segue更改为“Present Modally”。 然后为每个标签栏表视图控制器添加了一个导航控制器,其中有一个完成按钮,用于取消模态标签栏控制器。

enter image description here

- (IBAction)DoneButton:(id)sender {
    [self.parentViewController dismissViewControllerAnimated:YES completion:nil];
}

根据Apple的文档“查看iOS控制器目录”

https://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/ViewControllerCatalog/Chapters/CombiningViewControllers.html

  

将导航控制器添加到标签栏界面

     

使用标签栏控制器的应用也可以使用导航   一个或多个选项卡中的控制器。当结合这两种类型时   在同一用户界面中查看控制器,标签栏控制器   始终充当导航控制器的包装器

     

使用标签栏控制器的最常用方法是嵌入其视图   在你的应用程序的主窗口中。以下部分将向您展示如何操作   配置您的应用程序的主窗口以包括标签栏控制器和   一个或多个导航控制器。有这样做的例子   以编程方式和使用Interface Builder。

     

标签栏视图不支持半透明和标签栏控制器   永远不会在相关标签栏下方显示内容。因此,   如果您的导航界面嵌入在选项卡栏的选项卡中   控制器,如果采用,您的内容可能会低于导航栏   采用全屏布局的全屏布局   导航视图,但它没有重叠标签栏。

     

在标签栏界面中嵌入导航控制器时,您   应该只嵌入UINavigationController类的实例,和   不是作为子类的系统视图控制器   UINavigationController类。虽然系统提供自定义   导航控制器,用于选择联系人,选择图像和   实现其他行为,这些视图控制器通常是   旨在以模态呈现。有关如何使用的信息   特定的视图控制器,请参阅参考文档   类。

     

以模式方式显示标签栏控制器

     

可以(虽然不常见)在您的应用中以模态方式显示标签栏控制器。标签栏接口通常安装在   您应用的主窗口,仅在需要时更新。但是,你可以   如果您的界面设计,则以模态方式显示标签栏控制器   似乎值得保证。例如,要从应用的主要内容切换   操作模式到使用标签栏的完全不同的模式   界面,您可以模态呈现辅助标签栏控制器   使用交叉渐变过渡。

     

以模态方式显示标签栏控制器时,您始终会传递标签   bar控制器对象作为第一个参数   presentModalViewController:animated:方法。标签栏控制器   必须在呈现之前配置。因此,你必须   创建根视图控制器,配置它们,并将它们添加到   标签栏控制器,就像您正在安装标签栏一样   主窗口中的界面。

     

与所有其他模态呈现的视图控制器一样,父视图   控制员负责解雇其模态呈现的孩子   查看控制器以响应适当的用户操作。什么时候   虽然解雇标签栏控制器,但请记住这样做会删除   不仅是标签栏控制器对象,还有视图控制器   与每个标签相关联。视图控制器不可见   只是删除,但视图控制器显示在当前   visible tab也会收到通常的viewWillDisappear:message。

     

有关如何呈现视图控制器的信息(包括   导航控制器)模态,请参阅演示视图控制器   适用于iOS的View Controller编程指南中的其他视图控制器。   有关如何配置标签栏控制器以供使用的信息   您的应用,请参阅标签栏控制器。