Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
979 views
in Technique[技术] by (71.8m points)

swift - ios13 UIPopoverViewController showing UITableViewController - Safe Area problems / Missing parts of table

In the same theme as this post:

iOS 13 - UIPopoverPresentationController sourceview content visible in the arrow

I have a UITableViewController instantiated from the Storyboard. I'm presenting it in a UIPopoverViewController.

Depending on orientation I either have a side missing or the top missing and the content of the _UITableViewHeaderFooterViewBackground scrolls 'through' the arrow.

What's wrong:

These are when it's on the top, but if it presents on the side then the whole side

enter image description here enter image description here

enter image description here

EDIT: I AM using the Safe Area Guides:

enter image description here

As I said previously, I dragged on from the object library a brand new UITVC and then changed the prototype cell to my app's requirements.

I made zero changes to any safe area toggles or settings.

I do not change any safe area insets or adjustments in code.

So, thank you @Alex, but that's not the problem, or if it is, I don't know what to do about it.

EDIT 2:

This afternoon, I made sure I have zero code in my classes that do any formatting, colours, inserts, or ANYTHING to do with ANY form of changing default table cells.

I then completely deleted my UITVC in IB and created a new one, create new prototype cell with no styling except to put a UIImageView in the cell.

I ensured the UITVC, the tableviewcell and content view all has 'Safe Area' and 'Safe Margins' ticked in IB.

Rebuilt the app and ran.

EXACTLY THE SAME.

I still have both content and background going over the arrow and if I then add a border around the table the presenting side is 'cut off'.

EDIT 3:

I KNOW WHAT THE PROBLEM IS!!!

It's the _UITableViewHeaderFooterViewBackground that doesn't play nicely with AutoLayout!!

I'm not sure how to fix it, but that's what the problem is.

enter image description here

EDIT 4 / Update:

Today I built the following app, and the bug is still present - even without Section Headers!

  1. In IB, create a UIVC with two buttons, one top left, the other top right.

  2. Drag a UITVC from the Asset Catalog and place it on one side of the original VC, then drag a UIVC from the Asset Library and put that on the other side.

  3. Drag a UITableView from the Asset Library onto the 'new' UIViewController and just set it's top and bottom to the guide safe area layouts and the left and right to the safe margins with a 0 constant (you can keep the default 20 - makes no difference).

  4. Now, wire up those buttons to the original UIVC so that pressing each instantiates one or the other two controllers, and displays them in a popover.

Notice, there is no formatting, no styling, no changing of ANY default IB settings on any of the UIViewControllers.

Here's the 'centre' VC code:

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
    }

Here's the layout in IB - note that I've changed the background colours on all the views differently so you can see what views are causing problems.

enter image description here

And here is the code from each of the side VC's:


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

and the other:

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

Here's the IB config:

enter image description here

enter image description here And here is the results:

enter image description here enter image description here

enter image description here

enter image description here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It seems that you are not using the new Safe Area Layout Guides. The old method is deprecated. If you use storyboard please activate this setting in the File tab:

enter image description here

In code you can use something like this:

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

For more information read this: https://useyourloaf.com/blog/safe-area-layout-guide/


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...