From 6ac7f3534960212b0eb33cd4f79b7a8b10d5d6fb Mon Sep 17 00:00:00 2001 From: Philip Belemezov Date: Sat, 27 Mar 2021 21:30:59 +0100 Subject: [PATCH] Fix #1952: Use SafeArea Autolayout Constraints when FormViewController Is Presented Modally --- Source/Core/Core.swift | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/Source/Core/Core.swift b/Source/Core/Core.swift index 1c7ffddfc..4f92bf1d1 100644 --- a/Source/Core/Core.swift +++ b/Source/Core/Core.swift @@ -456,14 +456,22 @@ open class FormViewController: UIViewController, FormViewControllerProtocol, For navigationAccessoryView = customNavigationAccessoryView ?? NavigationAccessoryView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 44.0)) navigationAccessoryView.autoresizingMask = .flexibleWidth + var shouldSetupConstraints = false if tableView == nil { tableView = UITableView(frame: view.bounds, style: tableViewStyle) - tableView.autoresizingMask = [.flexibleWidth, .flexibleHeight] tableView.cellLayoutMarginsFollowReadableWidth = false + shouldSetupConstraints = true } if tableView.superview == nil { view.addSubview(tableView) } + if shouldSetupConstraints { + setupTableViewConstraintsIfPresented() + } + // Always set up a mask. If the UITableView uses constraints, `translatesAutoresizingMaskIntoConstraints` will + // be set to false, and so the autoresizing mask will be ignored. + tableView.autoresizingMask = [.flexibleWidth, .flexibleHeight] + if tableView.delegate == nil { tableView.delegate = self } @@ -739,6 +747,28 @@ open class FormViewController: UIViewController, FormViewControllerProtocol, For tableView?.endUpdates() } + /** + * Fix for #1952: `UITableView.scrollRectToVisible(, animated:)` and `UITableView.scrollToRow()` don't work properly + * in `keyboardWillShow()` due to, what seems to be, a bug in iOS when autoresizing mask is used for a `UIViewController` that is + * presented modally as `.formSheet/.pageSheet` within a `UINavigationController`. + * The check below preserves the existing behavior of using autoresizing masks in other cases. + */ + open func setupTableViewConstraintsIfPresented() { + if #available(iOS 13, *) { + if presentingViewController != nil && navigationController != nil { + // Need to set the background color as otherwise black shows underneath the translucent navigation bar. + view.backgroundColor = .systemBackground + tableView.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + tableView.topAnchor.constraint(equalTo: tableView.superview!.safeAreaLayoutGuide.topAnchor), + tableView.bottomAnchor.constraint(equalTo: tableView.superview!.safeAreaLayoutGuide.bottomAnchor), + tableView.leadingAnchor.constraint(equalTo: tableView.superview!.safeAreaLayoutGuide.leadingAnchor), + tableView.trailingAnchor.constraint(equalTo: tableView.superview!.safeAreaLayoutGuide.trailingAnchor) + ]) + } + } + } + // MARK: Private var oldBottomInset: CGFloat?