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

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

我该如何解决这个问题?

【问题讨论】:

    标签: objective-c ios11 iphone-x safearealayoutguide


    【解决方案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)
       ])
    }
    

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

    【讨论】:

    • 我能有一个客观的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)
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2018-03-23
          • 1970-01-01
          • 1970-01-01
          • 2018-02-21
          • 1970-01-01
          • 2018-07-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多