UITableView进入半透明的导航栏

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

viewDidLoad

我用

 self.navigationController.navigationBar.shadowImage = [UIImage new]; self.navigationController.navigationBar.translucent = YES; self.navigationController.view.backgroundColor = [UIColor clearColor]; 

当我改变到self.navigationController.navigationBar.translucent = NO; 但后来我在导航栏上失去了透明度。

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

 self.tableView.contentInset = UIEdgeInsetsMake(44,0,0,0); 

或者你可以抵消tableview的框架。 然后,滚动内容将被切断在导航栏下面(这也不会很好看)

我的案子帮助了这个(比尔的代码的修改版本):

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); } 

重点是该表必须下推导航栏的高度( rect.origin.y )加上状态栏的高度( 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) } } 

将tableview的y位置设置为导航栏的高度加上状态栏的height (让它为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); 

如果您使用的是自动布局,只需更改tableView顶部约束,而不是更改框架。

并自动更改viewControllerAdjustsScrollViewInsets为NO

 self.automaticallyAdjustsScrollViewInsets = NO; 

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

检查这个示例

这在iOS8的横向模式和纵向模式下都可以工作:

 - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; CGRect rect = self.navigationController.navigationBar.frame; float y = -rect.origin.y; self.tableView.contentInset = UIEdgeInsetsMake(y ,0,0,0); } 

我有类似的问题为iOS 9.当我第一次打开viewController,tableView是在顶部栏。 滚动tableView后,一切工作正常。

  1. select你的视图控制器
  2. 点击“属性检查器”选项卡
  3. 取消勾选“顶部酒吧”

在这里输入图像说明

最好不要硬编码插入值,因为它可能基于设备的方向。

码:

 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() } 

介绍

我是iOS开发和堆栈溢出的新手,所以请原谅我,如果我的post不完美。

我也有这个问题,当我用我的UITableView的内容插入它完美加载第一,或从我的其他选项卡访问时,完美的工作; 但是,如果我导航回到视图,它将有额外的“填充”。 我想出了一个解决办法,以便我的UITableView将被正确放置每次。

问题

当你第一次加载UITableView或者Tab时,需要使用insets来正确的在导航栏下面启动表格,但是当你回到页面时并不需要insets,因为某些原因, UITableView。 这就是为什么你可以得到额外的填充。

解决scheme

解决scheme涉及使用布尔值来确定您是否已经导航,以便它可以正确地确定是否需要内容插入。

-(void)viewDidLoad我设置了hasNavigatedFurther = NO 。 然后:

 -(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; if (!hasNavigatedFurther) { self.tableView.contentInset = UIEdgeInsetsMake(64, 0, 0, 0); } else { self.tableView.contentInset = UIEdgeInsetsZero; //In order to allow visiting between tabs and retaining desired look hasNavigatedFurther = NO; } } 

为了使这个工作,你需要在代码之前设置hasNavigatedFurther = YES ,将另一个视图推到导航堆栈上。

 -(void)btnTouched:(id)sender { hasNavigatedFurther = YES; NextViewController* nvc = [NextViewController new]; [self.navigationController pushViewController:nvc animated:YES]; } 

我想出了以下的解决scheme,第一次导航到视图控制器,调整表视图的contentInset导航栏的高度,考虑到顶部单元格可能有的任何填充。 当将另一个视图控制器推入堆栈之后返回到此视图控制器时,我将contentInset重新调整为UIEdgeInsetsZero

 - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self adjustEdgeInsetsForTableView]; } - (void)adjustEdgeInsetsForTableView { if(self.isMovingToParentViewController) { self.tableViewForm.contentInset = UIEdgeInsetsMake(self.navigationController.navigationBar.frame.size.height + padding, 0, 0, 0); } else { self.tableViewForm.contentInset = UIEdgeInsetsZero; } } 

只有这个代码解决了这个问题:

  @IBOutlet weak var tableView: UITableView! func viewDidLoad() { super.viewDidLoad() self.tableView.contentInset = UIEdgeInsetsZero } 

我结合了@Adam Farrell和@Tash Pemhiwa的解决scheme,最后下面的代码适用于我:

 - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self adjustEdgeInsetsForTableView]; } - (void)adjustEdgeInsetsForTableView { if(self.isMovingToParentViewController) { self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0); } else { self.tableView.contentInset = UIEdgeInsetsMake(64, 0, 0, 0); } } 

希望这会帮助那些浪费几个小时来处理这个奇怪的UI行为的人。

将表视图限制在导航栏的底部。 表视图会自动偏移44,但是在代码中我们可以这样做:

 tableView.contentInset = UIEdgeInsets(top: -44, left: 0, bottom: 0, right: 0) 

酒吧是透明的,没有颜色,但表视图根本不重叠。 请注意,尽pipe导航栏是透明的,但“钩子”一词也会被切断。 这只会使你在导航栏中限制表视图顶边为0。 不是从顶视图0。

在这里输入图像说明

大多数情况下,引入魔术常量的解决scheme并不会扩展,例如,如果下一个iPhone引入了不同的导航栏高度,我们将不得不更新我们的代码。

幸运的是,苹果为我们提供了克服这个问题的更清晰的方法,例如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) ]) } 

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