TableView пустой внутри ScrollView, если я не добавлю еще один UIView? - PullRequest
0 голосов
/ 03 октября 2018

У меня есть ViewController с ScrollView внутри (закрепленный по краям, 4 ограничения).Все хорошо.

Затем я добавляю TableViewController как ChildViewController в ScrollView.TableViewController жестко закодирован, чтобы иметь 3 строки.Представление TableViewController закреплено за полным ScrollView.

@IBOutlet weak var SV: UIScrollView!

override func viewDidLoad()
{
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let TVC        = storyboard.instantiateViewController(withIdentifier: "TVC") as! TVC

    addChildViewController(TVC)
    SV.addSubview(TVC.view)
    TVC.didMove(toParentViewController: self)

    TVC.view.translatesAutoresizingMaskIntoConstraints = false
    TVC.view.topAnchor.constraint(equalTo: SV.topAnchor).isActive = true
    TVC.view.leadingAnchor.constraint(equalTo: SV.leadingAnchor, constant: 100).isActive = true
    TVC.view.trailingAnchor.constraint(equalTo: SV.trailingAnchor, constant: -100).isActive = true
    TVC.view.bottomAnchor.constraint(equalTo: SV.bottomAnchor).isActive = true
}

Если я открою отладчик, я вижу, что компоновка ScrollView неоднозначна и что override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell никогда не вызывается для контроллера табличного представления (почему?).

Вместо этого, если я просто добавлю метку в раскадровку или любое другое представление, внутри прокрутки и добавлю к нему 4 ограничения, то будет отображен TableView, и override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell будет вызван, как и ожидалось.

Что с этим?ScrollView не должен быть неоднозначным, потому что TableView должен вычислять свой собственный размер внутреннего содержимого?Что не так с табличным представлением, что оно никогда не заполняет себя, если оно одиноко внутри ScrollView?

Я добавляю весь образец проекта.Если вы запустите его, ожидаемый результат будет показан в виде таблицы.Если вы перейдете к раскадровке и удалите метку из ScrollView, то TableView не будет заполнен вообще.

Я не знаю, как я могу напрямую добавить образец проекта здесь, поэтому я загрузил его.Просто запустите его, затем удалите единственную метку из раскадровки и повторите ее, больше не будет табличного представления.https://wetransfer.com/downloads/e0a75a995992cdc2be9120224515549920181003074547/1083bc9a3cb34fe9b1ab8e513b1520f020181003074547/e68826

PS: игнорируйте другие вещи, такие как контроллеры дочерних представлений.Мой единственный вопрос - почему табличное представление отображается, когда метка существует внутри того же ScrollView, и не отображается, когда метка удалена.

1 Ответ

0 голосов
/ 03 октября 2018

Прежде всего, ограничения, применяемые к представлениям внутри ScrollView, немного, скажем, особенные.Они не связаны с фреймом ScrollView, они в некотором роде связаны с «contentSize» ScrollView.Обычно, если у вас будет представление внутри другого представления, а внутреннее представление закреплено во всех направлениях к суперпросмотру, оно будет либо растягиваться, чтобы соответствовать родительскому размеру (если родительские ограничения четко определены для другого родителя), либоparent будет «переносить» размер дочернего элемента, если родительские ограничения не определены относительно другого родителя.

Теперь ScrollView ведет себя немного иначе, в этом случае размер ScrollView никогда не будет «переносить» дочерний элемент.Дочерние ограничения добавляются просто для того, чтобы сообщить ScrollView, что такое область прокрутки (contentSize).

Более того, в вашем случае UITableView, вы можете думать о нем как о «специальном» ScrollView, не может обеспечить достаточноинформация для ScrollView для вычисления scrollableContent.Если вы прикрепите tableView во всех направлениях, он просто скажет TableView: «выровнять по родительскому элементу во всех направлениях», но представление прокрутки не будет знать «сколько я могу прокрутить».

Так что из-заПри рассмотрении вышеупомянутой проблемы вы обычно добавляете UIView внутри ScrollView, чтобы действовать как «контейнер», и в зависимости от scrollDirection вы устанавливаете ширину / высоту представления равными ScrollView или родительскому элементу scrollView (опять же, в зависимости от использованиядело).Затем весь контент, которым вы хотите быть внутри scrollView, добавляется в UIView.Кроме того, содержимое закреплено таким образом, что оно не позволит «сжатию» принудительно растянуть родительское представление (иначе контейнер), чтобы «обернуть» все содержимое, таким образом, прокрутка будет знать, сколько стоит прокрутка.area.

ScrollView не должен быть двусмысленным, потому что TableView должен вычислять свой собственный размер внутреннего содержимого?

Это неверный внутренний размер контента, определяющий минимальный размер, который необходим представлению для рисования.Подумайте об этом, сколько места нужно табличному представлению для рисования, если никакая другая специальная реализация не добавлена, ответ равен 0. TableView может иметь ширину / высоту 0, для этого нет ограничений.

Теперь, чтобы подвести итог, ваша реализация немного ошибочна, чтобы ее исправить, я предлагаю поближе познакомиться с одним из множества учебных пособий, в которых показано, как реализовать UIScrollView с автоматической компоновкой.Вы увидите, что большинство реализаций будут:

  • добавить UIView внутри UIScrollView (он же "containerView)
  • , тогда представление будет прикреплено во всех направлениях к UIScrollView
  • , тогда либо ширина, либо высота контейнера будут установлены равными scrollView или родительскому элементу представления прокрутки
  • , тогда содержимое будет добавлено в "containerView"
  • тогда к контенту будут применены ограничения таким образом, что контейнер должен будет обернуться вокруг контента.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...