UITableview объединяется с индикатором дома на iPhone X

У меня есть UITableView создан программно. это UITableView сливается с индикатором дома на устройстве iPhone X.

Как я могу исправить эту проблему?

4 ответа

Решение

Программно установите нижний якорь таблицы с нижним якорем 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)
   ])
}

Вот полезные ссылки (ответы):

Вы должны использовать safeAreaLayoutGuide в iOS11 и установить ограничения с помощью 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;

Swift 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
        }

Если ваш контроллер получен из пользовательского интерфейсаTable ViewController (не 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()
}

и результат:

клетки за пустышкой

это решение не очень хорошее, но пока работает

Это мой "взлом", чтобы заставить верхнюю и нижнюю безопасную область в 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!
    ])
}

Просто грустно, что нам приходится писать весь этот код, поэтому, если кто-нибудь знает о более простом способе достижения этого, пожалуйста, покажите нам.

PS Я использовал этот маленький UIView расширение здесь:

extension UIView {
    func addSubview(_ child: UIView, constraints: [NSLayoutConstraint]) {
        addSubview(child)
        child.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate(constraints)
    }
}
Другие вопросы по тегам