UITableview 与 iPhone X 上的主页指示器合并

Posted

技术标签:

【中文标题】UITableview 与 iPhone X 上的主页指示器合并【英文标题】:UITableview merging with the home indicator on iPhone X 【发布时间】:2017-10-24 15:14:48 【问题描述】:

我有一个以编程方式创建的UITableView。这个UITableView 与 iPhone X 设备上的主页指示器合并。

我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

以编程方式,将 tableview 的底部锚点设置为 SafeAreaLayout 的底部锚点。

这里是示例/测试代码,如何以编程方式设置界面元素的安全区域布局。

if #available(ios 11, *) 
  let guide = view.safeAreaLayoutGuide
  NSLayoutConstraint.activate([
   table.topAnchor.constraintEqualToSystemSpacingBelow(guide.topAnchor, multiplier: 1.0),
   guide.bottomAnchor.constraintEqualToSystemSpacingBelow(table.bottomAnchor, multiplier: 1.0)
   ])

 else 
   let standardSpacing: CGFloat = 8.0
   NSLayoutConstraint.activate([
   table.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor, constant: 0),
   bottomLayoutGuide.topAnchor.constraint(equalTo: table.bottomAnchor, constant: 0)
   ])

以下是有用的参考资料(答案):

Use Safe Area Layout programmatically Safe Area of Xcode 9

【讨论】:

我能有一个客观的c版本吗 当然,给我一些时间,会给你obj-c代码。分享给我 tableview 的变量名。 self.tableView 你扩展(使用)UITableController 来显示这个列表还是 UIViewController? UIViewController【参考方案2】:

您应该在 iOS11 中使用safeAreaLayoutGuide & 使用safeArea 设置约束,因此您的内容不会剪辑。

用于在UITableView中设置约束-

ObjC

    self.tableView.translatesAutoresizingMaskIntoConstraints = NO;
    UILayoutGuide * guide = self.view.safeAreaLayoutGuide;
    [self.tableView.leadingAnchor constraintEqualToAnchor:guide.leadingAnchor].active = YES;
    [self.tableView.trailingAnchor constraintEqualToAnchor:guide.trailingAnchor].active = YES;
    [self.tableView.topAnchor constraintEqualToAnchor:guide.topAnchor].active = YES;
    [self.tableView.bottomAnchor constraintEqualToAnchor:guide.bottomAnchor].active = YES;

斯威夫特 4

      tableView.translatesAutoresizingMaskIntoConstraints = false
      if #available(iOS 11.0, *) 
            let guide = self.view.safeAreaLayoutGuide

            tableView.trailingAnchor.constraint(equalTo: guide.trailingAnchor).isActive = true
            tableView.leadingAnchor.constraint(equalTo: guide.leadingAnchor).isActive = true
            tableView.bottomAnchor.constraint(equalTo: guide.bottomAnchor).isActive = true
            tableView.topAnchor.constraint(equalTo: guide.topAnchor).isActive = true

         else 
            NSLayoutConstraint(item: tableView, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1.0, constant: 0).isActive = true
            NSLayoutConstraint(item: tableView, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1.0, constant: 0).isActive = true
            NSLayoutConstraint(item: tableView, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1.0, constant: 0).isActive = true
            NSLayoutConstraint(item: tableView, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1.0, constant: 0).isActive = true
        

【讨论】:

【参考方案3】:

如果您的控制器是从 UITableViewController(不是 UIViewController)派生的,则单元格在屏幕底部看起来不太好。

我假设您使用的是导航控制器,在这种情况下我的解决方案是:

//dummy view
var bottomX: UIView?


override func viewWillAppear(_ animated: Bool) 
    super.viewWillAppear(animated)
    if Device.isIPhoneX 
        bottomX = UIView(frame: CGRect(x: 0, y: self.tableView.bounds.size.height - 34, width: self.tableView.bounds.size.width, height: 34))
        bottomX!.backgroundColor = self.tableView.backgroundColor
        self.navigationController?.view.addSubview(bottomX!)
    

别忘了删除虚拟视图

override func viewWillDisappear(_ animated: Bool) 
    super.viewWillDisappear(animated)
    bottomX?.removeFromSuperview()

结果是:

这个解决方案不是很好,但它现在确实有效

【讨论】:

【参考方案4】:

这是我在UITableViewController 中强制顶部和底部安全区域的“技巧”。首先你必须将它嵌入UINavigationController(如果不需要,隐藏导航栏),然后:

override func viewDidLoad() 
    super.viewDidLoad()

    configureFakeSafeArea()


@available(iOS 11.0, *)
override func viewSafeAreaInsetsDidChange() 
    super.viewSafeAreaInsetsDidChange()

    topSafeAreaHeight?.constant = view.safeAreaInsets.top
    bottomSafeAreaHeight?.constant = view.safeAreaInsets.bottom


private var topSafeAreaHeight: NSLayoutConstraint?
private var bottomSafeAreaHeight: NSLayoutConstraint?

private func configureFakeSafeArea() 
    guard let view = navigationController?.view else 
        return
    

    let topSafeArea = UIView()
    topSafeArea.backgroundColor = tableView.backgroundColor
    var topConstant: CGFloat = 0
    if #available(iOS 11.0, *) 
        topConstant = view.safeAreaInsets.top
    
    topSafeAreaHeight = topSafeArea.heightAnchor.constraint(equalToConstant: topConstant)
    view.addSubview(topSafeArea, constraints: [
        topSafeArea.leadingAnchor.constraint(equalTo: view.leadingAnchor),
        topSafeArea.trailingAnchor.constraint(equalTo: view.trailingAnchor),
        topSafeArea.topAnchor.constraint(equalTo: view.topAnchor),
        topSafeAreaHeight!
    ])

    let bottomSafeArea = UIView()
    bottomSafeArea.backgroundColor = tableView.backgroundColor
    var bottomConstant: CGFloat = 0
    if #available(iOS 11.0, *) 
        bottomConstant = view.safeAreaInsets.bottom
    
    bottomSafeAreaHeight = bottomSafeArea.heightAnchor.constraint(equalToConstant: bottomConstant)
    view.addSubview(bottomSafeArea, constraints: [
        bottomSafeArea.leadingAnchor.constraint(equalTo: view.leadingAnchor),
        bottomSafeArea.trailingAnchor.constraint(equalTo: view.trailingAnchor),
        bottomSafeArea.bottomAnchor.constraint(equalTo: view.bottomAnchor),
        bottomSafeAreaHeight!
    ])

很遗憾我们必须编写所有这些代码,所以如果有人知道更简单的方法来实现这一点,请告诉我们。

附:我在这里使用了这个小的UIView 扩展:

extension UIView 
    func addSubview(_ child: UIView, constraints: [NSLayoutConstraint]) 
        addSubview(child)
        child.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate(constraints)
    

【讨论】:

以上是关于UITableview 与 iPhone X 上的主页指示器合并的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 NSFetchedResultsController 支持管理 UITableView 上的数据,如 iPhone Photo 应用

NSDictionary 可以与 iPhone 上的 TableView 一起使用吗?

iOS11 与 iPhone X适配的那些坑(持更中...)

iPhone UITableView - 对配件点击的操作

UITableView 单元格布局与 iPhone 12 pro 和 promax 的区别

iPhone X 横向模式下的视图看起来不正确