UITableView位于半透明导航栏下

bir*_*age 57 objective-c uinavigationbar uitableview ios

我想在IOS 7应用程序中使用透明导航栏.我的应用程序中有一个全屏图像.我也在该图像上有一个UITableView.当我使用下面的代码时,图像适合我想要的屏幕,但UITableView在导航栏下.

viewDidLoad

我用

self.navigationController.navigationBar.shadowImage = [UIImage new];
self.navigationController.navigationBar.translucent = YES;
self.navigationController.view.backgroundColor = [UIColor clearColor];
Run Code Online (Sandbox Code Playgroud)

我改变的时候还可以,self.navigationController.navigationBar.translucent = NO;但是我在导航栏上失去了透明度.

rob*_*ert 65

您可以设置tableView的contentInsets,使其最初位于导航栏下方,但会在其后面滚动(内容将重叠)

self.tableView.contentInset = UIEdgeInsetsMake(44,0,0,0);
Run Code Online (Sandbox Code Playgroud)

或者你可以偏移tableview的框架.然后滚动内容将被切断导航栏下方(这看起来也不好看)

  • 确保也设置了scrollIndicatorInsets! (2认同)

小智 47

我的案例帮助了这个(Bill Chan的代码的修改版本):

Objective C版本:

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];   
    CGRect rect = self.navigationController.navigationBar.frame;
    float y = rect.size.height + rect.origin.y;
    self.tableView.contentInset = UIEdgeInsetsMake(y, 0, 0, 0);
}
Run Code Online (Sandbox Code Playgroud)

关键是必须向下推导表以获得navigationBar(rect.size.height)的高度以及状态栏高度(rect.origin.y);

Swift版本(也兼容Swift 2):

override func viewDidLayoutSubviews() {
    if let rect = self.navigationController?.navigationBar.frame {
        let y = rect.size.height + rect.origin.y
        self.tableView.contentInset = UIEdgeInsetsMake( y, 0, 0, 0)
    }
}
Run Code Online (Sandbox Code Playgroud)


Mal*_*der 31

我在iOS 9中遇到了类似的问题.当我第一次打开viewController时,tableView位于顶部栏下面.滚动后的表格看起来一切正常.

  1. 选择视图控制器
  2. 单击"属性检查器"选项卡
  3. 取消选中"Under Top Bars"

在此输入图像描述


Yat*_*B L 8

将tableview的y位置设置为导航栏的高度加上状态栏的高度(让它成为height)

  height = 64; // height of navigation bar = 44(In portait), height of status bar = 20
  tableView.frame = CGRectMake(tableView.frame.origin.x, height , tableView.frame.size.width, tableView.frame.size.height);
Run Code Online (Sandbox Code Playgroud)

如果您正在使用autolayout,则只需更改tableView顶部约束而不是更改框架.

并且还将viewController自动调整为ScrollViewInsets为NO

self.automaticallyAdjustsScrollViewInsets =  NO;
Run Code Online (Sandbox Code Playgroud)

如果您支持不同的方向更新框架和contentInset到(52),因为横向模式下的导航栏高度为32.

检查此样本


Bil*_*han 7

这适用于iOS8中的横向模式和纵向模式:

- (void)viewDidLayoutSubviews
{
  [super viewDidLayoutSubviews];

  CGRect rect = self.navigationController.navigationBar.frame;

  float y = -rect.origin.y;

  self.tableView.contentInset = UIEdgeInsetsMake(y ,0,0,0);
}
Run Code Online (Sandbox Code Playgroud)


use*_*037 5

最好不要根据设备的方向对Inset值进行硬编码.

码:

func setTableViewContentInset() {

    let contentInsetHeight = topLayoutGuide.length
    let contentInset = UIEdgeInsetsMake(contentInsetHeight, 0, 0, 0)

    tableView.contentInset = contentInset
    tableView.scrollIndicatorInsets = contentInset
}

func scrollToTop() {

    if tableView.indexPathsForVisibleRows?.count > 0 {

        let topIndexPath = NSIndexPath(forRow: 0, inSection: 0)

        tableView.scrollToRowAtIndexPath(topIndexPath, atScrollPosition: .Top, animated: false)
    }
}

func scrollToTopOfVisibleCells() {

    if let visibleIndexPaths = tableView.indexPathsForVisibleRows where tableView.indexPathsForVisibleRows?.count > 0 {

        let topMostVisibleIndexPath = visibleIndexPaths[0]

        tableView.scrollToRowAtIndexPath(topMostVisibleIndexPath, atScrollPosition: .Top, animated: false)

    }        
}

//MARK: Load Views
override func viewDidLoad() {
    super.viewDidLoad()

    setTableViewContentInset()
}

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    scrollToTop()
}

//MARK: Trait collection change
override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)

    setTableViewContentInset()
    scrollToTopOfVisibleCells()
}
Run Code Online (Sandbox Code Playgroud)


Mad*_*yar 5

引入神奇常数的解决方案在大多数情况下无法扩展。例如,如果下一代 iPhone 引入了不同的导航栏高度,我们将不得不更新我们的代码。

幸运的是,Apple 为我们提供了更简洁的方法来克服这个问题,例如topLayoutGuide

当视图控制器位于屏幕最前面时,topLayoutGuide 属性就会发挥作用。它表示您不希望出现在半透明或透明 UIKit 栏(例如状态栏或导航栏)后面的内容的最高垂直范围

您可以通过以下代码片段以编程方式实现(同样可以通过 IB 实现):

override func viewDidLoad() {
  super.viewDidLoad()

  automaticallyAdjustsScrollViewInsets = false
  tableView.translatesAutoresizingMaskIntoConstraints = false
  NSLayoutConstraint.activate([
    tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
    tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
    tableView.topAnchor.constraint(equalTo: 
       topLayoutGuide.bottomAnchor),
    tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
  ])
}
Run Code Online (Sandbox Code Playgroud)

注意:在 iOS 11 中不推荐使用topLayoutGuide,我们应该改用UIView的safeAreaLayoutGuide属性。