我正在尝试在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;
时,它正常,但我在导航栏上失去了透明度。
答案 0 :(得分:65)
您可以设置tableView的contentInsets,使其最初位于导航栏下方,但会在其后滚动(内容会重叠)
self.tableView.contentInset = UIEdgeInsetsMake(44,0,0,0);
或者你可以偏移tableview的框架。然后滚动内容将在导航栏下面切断(看起来也不好看)
答案 1 :(得分:47)
我的案例帮助了这个(Bill Chan的代码的修改版本):
目标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.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)
}
}
答案 2 :(得分:26)
我对iOS 9有类似的问题。当我第一次打开viewController时,tableView位于顶部栏下面。滚动后的表格看起来一切正常。
答案 3 :(得分: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);
如果您使用的是自动布局,只需更新tableView顶部约束而不是更改框架。
并且还将viewController自动调整为“滚动视图集”,并将其更改为“
”self.automaticallyAdjustsScrollViewInsets = NO;
如果您支持不同的方向更新框架和contentInset到(52),因为横向模式下的导航栏高度为32。
检查此Sample
答案 4 :(得分: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);
}
答案 5 :(得分: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()
}
答案 6 :(得分:3)
大多数情况下,引入魔术常量的解决方案并不会缩放,例如,如果下一个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)
])
}
注意:在iOS 11中不推荐使用topLayoutGuide,我们应该使用UIView的safeAreaLayoutGuide属性。
答案 7 :(得分:2)
我是iOS开发和Stack Overflow的新手,所以请原谅我,如果我的帖子不完美。
我也有这个问题,当我使用内容插入我的UITableView时在首先加载或从其他标签访问它时完美地工作;但是,如果我导航回视图,它将有额外的“填充”。我想出了一个解决方法,以便每次都能正确放置我的UITableView。
首次加载UITableView或选项卡时,需要使用insets正确启动导航栏下方的表格,但是当您向后导航时它不需要插入,因为由于某种原因,它正确计算为UITableView的位置。这就是为什么你可以得到额外的填充。
解决方案涉及使用布尔值来确定您是否已导航,以便它可以正确地确定是否需要内容插入。
在-(void)viewDidLoad
我设置{{ 1}}。然后:
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
答案 8 :(得分:1)
我提出了以下解决方案,首次导航到视图控制器时,会调整表视图的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;
}
}
答案 9 :(得分:1)
只有此代码才能解决问题:
@IBOutlet weak var tableView: UITableView!
func viewDidLoad() {
super.viewDidLoad()
self.tableView.contentInset = UIEdgeInsetsZero
}
答案 10 :(得分:0)
我结合了@Adam Farrell和@Tash Pemhiwa的解决方案,最后下面的代码对我有用:
- (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行为的人。
答案 11 :(得分:0)
将表格视图限制在导航栏的底部。表视图将自动偏移44,但在代码中我们可以这样做:
tableView.contentInset = UIEdgeInsets(top: -44, left: 0, bottom: 0, right: 0)
条形图是透明的,没有颜色,但表格视图根本不重叠。请注意,尽管导航栏是透明的,但“Hook”这个词会被切断。这仅适用于将表视图上边缘约束为导航栏中的0。 <= p>,不是0
答案 12 :(得分:0)
所有您需要的是爱这个:
tableView.contentInsetAdjustmentBehavior = .automatic
从iOS 11开始,几乎不需要做丑陋的魔法常数胡子
我什至不需要将contentInsetAdjustmentBehavior设置为.none 修复导航栏重叠。
.automatic
以某种方式自动工作 让我想知道为什么这不是默认设置。
答案 13 :(得分:0)
尝试使用layoutguide修复
var constraints = [NSLayoutConstraint]()
let guide = view.safeAreaLayoutGuide
constraints.append(self.tableView.leadingAnchor.constraint(equalTo: guide.leadingAnchor))
constraints.append(self.tableView.trailingAnchor.constraint(equalTo: guide.trailingAnchor))
constraints.append(self.tableView.topAnchor.constraint(equalTo: guide.topAnchor))
constraints.append(self.tableView.bottomAnchor.constraint(equalTo: guide.bottomAnchor))