我正在将我的项目转移到iOS7。我正面临着与半透明导航栏相关的奇怪问题。
我有一个视图控制器,它有一个tableview作为子视图(让我们称之为ControllerA)。我使用controllerA初始化一个新的uinavigationcontroller并使用presentviewcontroller以模态方式呈现它。导航栏会阻止显示的视图控制器的表视图。我将 automaticAdjustsScrollViewInsets 设置为 YES ,但结果没有改变。 我知道我可以将 edgesForExtendedLayout 设置为 UIRectEdgeNone ,但它会使导航栏不再是半透明的。
之后,我尝试创建一个新的视图控制器进行测试。它包含几乎相同的元素。但结果却大相径庭。表视图内容不会被阻止。
结论
答案 0 :(得分:55)
我在苹果开发者论坛上找到了答案。 有两种不同的情况。
第一个,添加的视图控制器是UITableViewController。 并且问题不应该出现,因为苹果会自动填充它。
第二个,视图控制器不是UITableViewController。 在视图层次结构中,它包含一个UITableView。在这种情况下,如果UITableview(或ScrollView)是viewController的主视图或主视图的第一个子视图,它将起作用。否则,视图控制器不知道要填充哪个滚动视图,它将发生问题。
在我的例子中,视图控制器是第二个。并且有一个背景图像视图作为主视图的第一个子视图。所以,它失败了。
以下是Apple开发者论坛链接(需要开发者帐户才能访问): https://devforums.apple.com/message/900138#900138
答案 1 :(得分:47)
如果您希望视图低于导航栏,但也希望它定位,以便默认情况下滚动视图内容的顶部位于导航栏下方,您可以在布局视图后手动添加顶部插入。这实际上是顶层视图是滚动视图时视图布局系统的作用。
-(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
};
}
}
答案 2 :(得分:3)
根据Tony的回答,我能够以编程方式解决此问题,暂时将表格视图发送到后面,进行调整,然后将背景视图发送回后面。在我的情况下,这种方法没有闪烁。
在视图控制器中:
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
[self.view sendSubviewToBack:self.tableView];
}
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
[self.view sendSubviewToBack:self.backgroundView];
}
显然,如果self.view
上还有其他子视图,您可能还需要对其进行重新排序。
答案 3 :(得分:2)
对此已经有太多的答案了,但是我必须采用Christopher的解决方案并稍微修改它以支持调整和的视图,允许在{{1的子类中更改内容插入}}
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
的任何子类现在都可以修改MyViewController
中contentInset
的{{1}},并且会受到尊重。但是,如果scrollView
的{{1}}为viewDidLoad
:它将展开为contentInset
和scrollView
。
答案 4 :(得分:1)
Swift 2 中的@Christopher Pickslay解决方案:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let topInset = topLayoutGuide.length
inTableView.contentInset.top = topInset
inTableView.contentOffset.y = -topInset
inTableView.scrollIndicatorInsets.top = topInset
}
答案 5 :(得分:0)
是的 - 有点烦人。
我在主视图中有一个带有单个tableview的笔尖,而不是使用autolayout。有一个标签栏,导航栏和状态栏,应用程序需要恢复到5.0。在“界面”构建器中,整齐地“在iOS7和iOS6.1中并排查看它”可以正常工作,显示表格整齐(一旦iOS6 / 7增量设置正确)。
然而,在设备或模拟器上运行时,表顶部有一个很大的间隙,这是由于内容插入(几乎与iOS6 / 7垂直增量相匹配)的结果在笔尖。
我得到的解决方案是在viewWillAppear中输入[_tableView setContentInset:UIEdgeInsetsZero]。
另一个丑陋的黑客,屏幕上有漂亮的结果......
答案 6 :(得分:-5)
[self.navigationController setNavigationBarHidden:YES animated:YES];
在:
- (void)viewDidLoad