38

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

我有一个视图控制器,它有一个表视图作为子视图(我们称之为 ControllerA)。我用 controllerA 初始化了一个新的 uinavigationcontroller,并使用 presentviewcontroller 以模态方式呈现它。呈现的视图控制器的表格视图被导航栏挡住了。我将automaticAdjustsScrollViewInsets设置为YES,但结果没有改变。我知道我可以将edgesForExtendedLayout设置为UIRectEdgeNone,但它会使导航栏不再半透明。

表格视图被阻止

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

在此处输入图像描述

结论

  1. 两个 View Controller 的 automaticAdjustsScrollViewInsets 设置为 YES
  2. 该项目未使用情节提要
  3. 第一个是在 Xcode 4.6 上创建的,第二个是在 Xcode 5 上新创建的
  4. 我对比了两个类xib和code,差别不大
4

7 回答 7

55

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

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

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

就我而言,视图控制器是第二个。并且有一个背景图像视图作为主视图的第一个子视图。所以,它失败了。

这是 Apple 开发者论坛链接(需要开发者帐户才能访问): https ://devforums.apple.com/message/900138#900138

于 2013-10-02T02:55:24.420 回答
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
        };
    }
}
于 2013-11-22T04:39:52.007 回答
3

根据托尼的回答,我能够以编程方式解决这个问题,暂时将表格视图发送到后面,进行调整,然后将背景视图发送回后面。就我而言,这种方法没有闪烁。

在视图控制器中:


- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];

    [self.view sendSubviewToBack:self.tableView];
}

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];

    [self.view sendSubviewToBack:self.backgroundView];
}

显然,如果还有其他子视图,self.view您可能也需要重新排序。

于 2013-10-23T07:33:44.317 回答
2

可能已经有太多答案了,但我不得不采用 Christopher 的解决方案并稍微修改它以支持视图调整大小允许在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修改in并且它会被尊重。但是,如果of是: 它将扩展为and 。contentInsetscrollViewviewDidLoadcontentInsetscrollViewUIEdgeInsetsZerotopLayoutGuidebottomLayoutGuide

于 2014-02-03T11:20:01.863 回答
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
}
于 2016-06-10T13:38:04.130 回答
0

是的 - 有点烦人。

我在主视图中有一个带有单个表视图的笔尖,不使用自动布局。有一个标签栏、导航栏和一个状态栏,应用程序需要恢复到 5.0。在界面生成器中,整洁的“在 iOS7 和 iOS6.1 中并排查看”的东西起作用,显示表格整齐地适合(一旦 iOS6/7 增量设置正确)。

然而,在设备或模拟器上运行时,表格顶部有一个很大的差距,这是由于在 nib 中将内容插入(与 iOS6/7 垂直增量非常匹配)设置为零。

我得到的唯一解决方案是在 viewWillAppear 中放入 [_tableView setContentInset:UIEdgeInsetsZero]。

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

于 2013-10-04T17:00:12.447 回答
-5
[self.navigationController setNavigationBarHidden:YES animated:YES]; 

在:

- (void)viewDidLoad 
于 2013-10-08T19:22:52.223 回答