iOS 7表格视图无法自动调整内容插入

我正在将我的项目转移到iOS7。 我正面临一个与半透明导航栏有关的奇怪问题。

我有一个视图控制器,它有一个tableview作为子视图(我们称之为ControllerA)。 我用controllerA创build一个新的uinavigationcontroller,并使用presentviewcontroller以模态的forms呈现它。 呈现的视图控制器的表视图被导航栏阻止。 我将自动调整滚动视图设置为YES,但结果没有改变。 我知道我可以将edgesForExtendedLayout设置为UIRectEdgeNone ,但它会使导航栏不再透明。

表视图被阻止

之后,我试图创build一个新的视图控制器进行testing。 它包含几乎相同的元素。 但结果大不相同。 表格视图内容不会被阻止。

在这里输入图像说明

结论

  1. 两个视图控制器的自动调整滚动视图集被设置为是
  2. 该项目不使用故事板
  3. 第一个是在Xcode 4.6中创build的,第二个是在Xcode 5上新创build的
  4. 我已经比较了两个类xib和代码,没有太大的不同

我在苹果开发者论坛上find了答案。 有两种不同的情况。

第一个,添加的视图控制器是一个UITableViewController。 这个问题不应该出现,因为苹果会自动填充它。

第二个,视图控制器不是一个UITableViewController。 在视图层次结构中,它包含一个UITableView。 在这种情况下,如果UITableview(或ScrollView)是viewController的mainview或mainview的第一个子视图,它将工作。 否则,视图控制器不知道哪个滚动视图来填充,它会发生的问题。

在我的情况下,视图控制器是第二个。 有一个背景图像视图作为主视图的第一个子视图。 所以,它失败了。

这里是苹果开发者论坛链接(需要开发者账号来访问): https : //devforums.apple.com/message/900138#900138

如果您希望视图在导航栏下方,但也希望将其定位,以便默认情况下,滚动视图的内容的顶部位于导航栏的下方,则可以在布局视图后手动添加顶端embedded。 这实质上是当顶层视图是滚动视图时视图布局系统所做的事情。

 -(void)viewDidLayoutSubviews { if ([self respondsToSelector:@selector(topLayoutGuide)]) { UIEdgeInsets currentInsets = self.scrollView.contentInset; self.scrollView.contentInset = (UIEdgeInsets){ .top = self.topLayoutGuide.length, .bottom = currentInsets.bottom, .left = currentInsets.left, .right = currentInsets.right }; } } 

基于托尼的回答,我能够以编程方式解决这个问题,临时发送表视图到后面,做出调整,然后发送背景视图回到后面。 在我的情况下,这种方法没有闪烁。

在视图控制器中:

 - (void)viewWillLayoutSubviews { [super viewWillLayoutSubviews]; [self.view sendSubviewToBack:self.tableView]; } - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; [self.view sendSubviewToBack:self.backgroundView]; } 

显然,如果在self.view上还有其他子视图,您可能还需要重新sorting这些子视图。

这可能有太多的答案了,但我不得不采取克里斯托弗的解决scheme,稍微修改它以支持视图大小调整, 允许在UIViewController的子类中更改内容插入。

 @interface MyViewController () @property (weak, nonatomic) IBOutlet UIScrollView *scrollView; @property (assign, nonatomic) UIEdgeInsets scrollViewInitialContentInset; @end @implementation MyViewController - (void)viewDidLoad { [super viewDidLoad]; [self setScrollViewInitialContentInset:UIEdgeInsetsZero]; } - (void)viewWillLayoutSubviews { [super viewWillLayoutSubviews]; if (UIEdgeInsetsEqualToEdgeInsets([self scrollViewInitialContentInset], UIEdgeInsetsZero)) { [self setScrollViewInitialContentInset:[self.scrollView contentInset]]; } } - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; UIEdgeInsets scrollViewInset = [self scrollViewInitialContentInset]; if (UIEdgeInsetsEqualToEdgeInsets(scrollViewInset, UIEdgeInsetsZero) { if ([self respondsToSelector:@selector(topLayoutGuide)]) { scrollViewInset.top = [self.topLayoutGuide length]; } if ([self respondsToSelector:@selector(bottomLayoutGuide)]) { scrollViewInset.bottom = [self.bottomLayoutGuide length]; } [self.scrollView setContentInset:scrollViewInset]; } } @end 

为了解释这一点:

MyViewControllercontentInset类现在都可以在viewDidLoad修改contentInsetscrollView ,并且会被尊重。 但是,如果contentInsetscrollViewUIEdgeInsetsZero :它将被扩展到topLayoutGuidebottomLayoutGuide

Swift 2中的 @Christopher Pickslay解决scheme:

 override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() let topInset = topLayoutGuide.length inTableView.contentInset.top = topInset inTableView.contentOffset.y = -topInset inTableView.scrollIndicatorInsets.top = topInset } 

是的 – 有点烦人

我有一个单一的桌面视图在主视图中,不使用自动布局。 有一个标签栏,导航栏和一个状态栏,应用程序需要回到5.0。 在界面生成器中,整齐的“在iOS7和iOS6.1并排看到它”的作品,显示表格整齐(一旦iOS6 / 7的三angular洲设置正确)。

然而,在设备或模拟器上运行,表格顶部有一个很大的空白,这是由于在nib中被设置为零的内容embedded(与iOS6 / 7垂直增量几乎匹配)的结果。

只有我得到的解决scheme是在viewWillAppear放在[_tableView setContentInset:UIEdgeInsetsZero]。

另一个丑陋的黑客与一个漂亮的屏幕上的结果…..

 [self.navigationController setNavigationBarHidden:YES animated:YES]; 

在:

 - (void)viewDidLoad