ios13 UIPopoverViewController, показывающий UITableViewController — проблемы с безопасной зоной / недостающие части таблицы

В той же теме, что и этот пост:

iOS 13 — исходный код UIPopoverPresentationController видно по стрелке

У меня есть экземпляр UITableViewController, созданный из раскадровки. Я представляю это в UIPopoverViewController.

В зависимости от ориентации у меня либо отсутствует сторона, либо отсутствует верх, а содержимое _UITableViewHeaderFooterViewBackground прокручивается «сквозь» стрелку.

Что случилось:

Это когда сверху, а если сбоку, то и по всей стороне

введите здесь описание изображения введите здесь описание изображения

введите здесь описание изображения

РЕДАКТИРОВАТЬ: Я использую руководства по безопасным зонам:

введите здесь описание изображения

Как я уже говорил ранее, я перетащил из библиотеки объектов совершенно новый UITVC, а затем изменил ячейку прототипа в соответствии с требованиями моего приложения.

Я не вносил никаких изменений в какие-либо переключатели или настройки безопасной зоны.

Я не меняю никаких вставок или настроек безопасной области в коде.

Итак, спасибо @Alex, но проблема не в этом, а если и в этом, то я не знаю, что с этим делать.

РЕДАКТИРОВАТЬ 2:

Сегодня днем ​​я удостоверился, что в моих классах нет кода, который выполняет какое-либо форматирование, цвета, вставки или ЧТО-НИБУДЬ, связанное с ЛЮБОЙ формой изменения ячеек таблицы по умолчанию.

Затем я полностью удалил свой UITVC в IB и создал новый, создал новую ячейку прототипа без стилей, кроме как поместить в ячейку UIImageView.

Я убедился, что в UITVC, tableviewcell и просмотре содержимого в IB отмечены «Безопасная область» и «Безопасные поля».

Пересобрал приложение и запустил.

ТОЧНО ТАК ЖЕ.

У меня по-прежнему есть и контент, и фон, проходящие по стрелке, и если я затем добавлю рамку вокруг таблицы, сторона представления «обрезается».

РЕДАКТИРОВАТЬ 3:

Я ЗНАЮ В ЧЕМ ПРОБЛЕМА!!!

Это _UITableViewHeaderFooterViewBackground, который плохо работает с AutoLayout!!

Я не уверен, как это исправить, но проблема именно в этом.

введите здесь описание изображения

РЕДАКТИРОВАТЬ 4/обновить:

Сегодня я создал следующее приложение, и ошибка все еще присутствует - даже без заголовков разделов!

  1. В IB создайте UIVC с двумя кнопками, одна вверху слева, другая вверху справа.

  2. Перетащите UITVC из каталога активов и поместите его на одну сторону исходного VC, затем перетащите UIVC из библиотеки активов и поместите его на другую сторону.

  3. Перетащите UITableView из библиотеки активов в «новый» UIViewController и просто установите его верх и низ в макеты безопасных областей руководства, а левый и правый - в безопасные поля с константой 0 (вы можете оставить значение по умолчанию 20 - не имеет значения ).

  4. Теперь подключите эти кнопки к исходному UIVC, чтобы нажатие каждой из них создавало экземпляр одного или двух других контроллеров и отображало их во всплывающем окне.

Обратите внимание, что нет ни форматирования, ни стиля, ни изменения ЛЮБЫХ настроек IB по умолчанию на любом из UIViewController.

Вот «центральный» код VC:

import UIKit



class ViewController: UIViewController, UIPopoverPresentationControllerDelegate
{
    @IBOutlet weak var tbutton: UIButton!
    @IBOutlet weak var button: UIButton!



    @IBAction func buttonTouched(_ sender: UIButton)
    {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let libraryVC = storyboard.instantiateViewController(withIdentifier: "library")

        libraryVC.modalPresentationStyle = .popover

        if let popover = libraryVC.popoverPresentationController
        {
            popover.sourceView = self.button
            popover.sourceRect = self.button.bounds

            popover.delegate = self
        }

        libraryVC.preferredContentSize = CGSize(width: 400, height: 2048)

        libraryVC.view.layer.borderColor  = UIColor.white.cgColor
        libraryVC.view.layer.borderWidth  = 5.0
        libraryVC.view.layer.cornerRadius = 16.0

        self.present(libraryVC, animated: true)

    }



    @IBAction func tbuttonTouched(_ sender: UIButton)
    {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let libraryVC = storyboard.instantiateViewController(withIdentifier: "tlibrary")

        libraryVC.modalPresentationStyle = .popover

        if let popover = libraryVC.popoverPresentationController
        {
            popover.sourceView = self.tbutton
            popover.sourceRect = self.tbutton.bounds

            popover.delegate = self
        }

        libraryVC.preferredContentSize = CGSize(width: 400, height: 2048)

        libraryVC.view.layer.borderColor  = UIColor.white.cgColor
        libraryVC.view.layer.borderWidth  = 5.0
        libraryVC.view.layer.cornerRadius = 16.0

        self.present(libraryVC, animated: true)
    }



    func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle
    {
        return .none
    }

Вот макет в IB — обратите внимание, что я изменил цвета фона на всех представлениях по-разному, чтобы вы могли видеть, какие представления вызывают проблемы.

введите здесь описание изображения

А вот код от каждой стороны VC:


import UIKit



class LibraryViewController: UIViewController, UITableViewDelegate, UITableViewDataSource
{
    @IBOutlet weak var table: UITableView!



    override func viewDidLoad()
    {

    }



    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        12
    }



    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath) as? MyTableViewCell else
        {
            fatalError("expected to dequeue MenuItemTableCell - check storyboard")
        }

        return cell
    }
}

и другие:

import UIKit



class LibraryTableViewController: UITableViewController
{
    override func viewDidLoad()
    {
        super.viewDidLoad()

        self.tableView.delegate = self
        self.tableView.dataSource = self
    }



    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }



    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        // #warning Incomplete implementation, return the number of rows
        return 10
    }



    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath) as? MyTableViewCell else
        {
            fatalError("expected to dequeue MenuItemTableCell - check storyboard")
        }

        return cell
    }
}

Вот конфиг ИБ:

введите здесь описание изображения

введите здесь описание изображения И вот результаты:

введите здесь описание изображения введите здесь описание изображения

введите здесь описание изображения

введите здесь описание изображения


person iOSProgrammingIsFun    schedule 28.09.2019    source источник
comment
Вы не должны пытаться установить ограничения табличного представления в файле UITableViewController. Он уже будет настроен, чтобы делать правильные вещи.   -  person rmaddy    schedule 28.09.2019
comment
Убедитесь, что вы добавляете вещи только в ячейку таблицы в ее contentView.   -  person rmaddy    schedule 28.09.2019
comment
@rmaddy Хорошо, но это противоречит «предложениям» в комментариях к сообщению стека, на которое я ссылался. Если я ничего не делаю, я получаю изображения сверху, но без предупреждений о конфликтующих ограничениях.   -  person iOSProgrammingIsFun    schedule 28.09.2019
comment
iOS 13 намеренно меняет способ отображения контента во всплывающем окне, поэтому по умолчанию контент отображается в стрелке. Используйте безопасную область, чтобы хранить вещи в той части всплывающего окна, где нет стрелки. Для табличного представления ничего не нужно делать, кроме как убедиться, что ваши подпредставления ячеек помещены в contentView ячейки. И ваша фактическая проблема не ясна. На фото вообще не видно в чем проблема. И вы не показали никакого соответствующего кода для вашего табличного представления.   -  person rmaddy    schedule 28.09.2019
comment
У меня нет никакого «соответствующего» кода в UITableView, потому что я ничего не делал в табличном представлении, кроме как показывать строки, относящиеся к данным, как и в любой другой таблице. В нем нет ничего конкретного или уникального в отношении «безопасных областей», «отступов» и т. д. Возможно, вы можете продемонстрировать некоторый «правильный» код или реализацию, и я смогу проверить?   -  person iOSProgrammingIsFun    schedule 29.09.2019
comment
Давайте продолжим обсуждение в чате.   -  person iOSProgrammingIsFun    schedule 29.09.2019


Ответы (3)


Похоже, вы не пользуетесь новыми руководствами по планированию безопасных зон. Старый метод устарел. Если вы используете раскадровку, активируйте этот параметр на вкладке «Файл»:

введите здесь описание изображения

В коде вы можете использовать что-то вроде этого:

let guide = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
 greenView.topAnchor.constraintEqualToSystemSpacingBelow(guide.topAnchor, multiplier: 1.0),
 guide.bottomAnchor.constraintEqualToSystemSpacingBelow(greenView.bottomAnchor, multiplier: 1.0)
])

Для получения дополнительной информации прочитайте это: https://useyourloaf.com/blog/safe-area-layout-guide/

person alexkaessner    schedule 30.09.2019
comment
Пожалуйста, смотрите мое редактирование. Я пользуюсь этими направляющими. Точно так же, как в блоге сказано, что я читал, когда это было в другом основном вопросе об этой проблеме. Я действительно не понимаю, где я ошибся. - person iOSProgrammingIsFun; 01.10.2019
comment
@iOSProgrammingIsFun Используете ли вы какой-либо код для изменения макета? Я тоже не вижу никаких проблем, поэтому нам нужно немного больше контекста. Похоже, вы используете довольно пользовательские TableViewCells на скриншотах. - person alexkaessner; 01.10.2019
comment
Привет. Как я уже сказал в своем первоначальном вопросе, нет, не знаю. Конечно, я меняю цвета, ширину границ и т. д., но я не меняю рамки, не меняю и не добавляю вставки и не настраиваю ограничения. У меня тоже есть заголовки разделов, и они тоже страдают теми же проблемами. но даже - как показывают мои изображения - у UITableView есть проблема ... так что это не связано с ячейкой. Я даже удалил свой UITVC из IB и начал заново. - person iOSProgrammingIsFun; 01.10.2019

Хорошо, поэтому я израсходовал билет в службу поддержки Apple по этому поводу - после года без ответов.

Старый способ (установка границы всплывающего окна) больше никогда не будет работать из-за скрытой автоматической компоновки, происходящей с UITableViewController и его UITableView.

Единственное решение — полностью удалить UITableViewController и заменить его на UIViewController с одним представлением, а внутри этого представления поместить UITableView.

К счастью, изменения в коде минимальны (просто изменение наследования с UITableViewController на UIViewController, а затем добавление UITableViewDelegate).

Затем убедитесь, что UIViewController, содержащий таблицу, устанавливает себя в качестве делегата и источника UITableView.

Самая длинная часть исправления — это воссоздание макета в Interface Builder, но на этот раз убедитесь, что UITableView не получает свое верхнее, ведущее, нижнее, замыкающее значение в SUPERVIEW, а вместо этого в БЕЗОПАСНУЮ ОБЛАСТЬ.

Затем все, что вам нужно сделать, это вставить это, и оно работает:

override func viewDidLoad()
{
    super.viewDidLoad()
  
    self.tableView.delegate   = self
    self.tableView.dataSource = self
    
    self.tableView.layer.borderWidth  = 5
    self.tableView.layer.borderColor  = UIColor.white.cgColor
    self.tableView.layer.cornerRadius = 16
}
person iOSProgrammingIsFun    schedule 13.11.2020

Я нашел ответ. Мне нужно реализовать свой собственный UIPopoverBackgroundView. Пример: https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/bk2ch09p476popovers/ch22p751popovers/MyPopoverBackgroundView.swift У меня работает. мое всплывающее окно

person Marko    schedule 12.11.2019