UITableViewAlertForLayoutOutsideViewHierarchy error: Warning once only (iOS 13 GM)

你离开我真会死。 提交于 2019-12-22 04:01:30

问题


I am getting a strange error with iOS13 when performing a Segue and I can't figure out what it means, nor can I find any documentation for this error. The problem is that this seems to cause a lot of lag (a few seconds) until the segue is performed.

2019-09-11 22:45:38.861982+0100 Thrive[2324:414597] [TableView] Warning once only: UITableView was told to layout its visible cells and other contents without being in the view hierarchy (the table view or one of its superviews has not been added to a window). This may cause bugs by forcing views inside the table view to load and perform layout without accurate information (e.g. table view bounds, trait collection, layout margins, safe area insets, etc), and will also cause unnecessary performance overhead due to extra layout passes. Make a symbolic breakpoint at UITableViewAlertForLayoutOutsideViewHierarchy to catch this in the debugger and see what caused this to occur, so you can avoid this action altogether if possible, or defer it until the table view has been added to a window. Table view: ; layer = ; contentOffset: {0, 0}; contentSize: {315, 118}; adjustedContentInset: {0, 0, 0, 0}; dataSource: >

I am using Hero but I tried disabling it and using a regular Segue and this hasn't stopped the lag.

The code to initiate the segue is didSelectRowAt

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if indexPath.section == 0 {
            selectedCell = realIndexFor(activeGoalAt: indexPath)
            performSegue(withIdentifier: "toGoalDetails", sender: nil)
        } else if indexPath.section == 1 {
            selectedCell = indexPath.row
            performSegue(withIdentifier: "toIdeaDetails", sender: nil)
        } else {
            selectedDecision = indexPath.row
            hero(destination: "DecisionDetails", type: .zoom)
        }
    }

And then none of the code in viewDidLoad or viewWillAppear from the destination VC affects this in any way (I tried commenting it all out with no difference.

Any idea what's causing this? I can share whatever other details are needed.

Thank you.


回答1:


It happened to me because I registered the device for change orientation notification in the viewWillAppear(:) method. I moved the registration in the viewDidAppear(:) and Xcode it's not stopping at the breakpoint anymore.

What I can say is that layout changes might be run when the view is already visible...




回答2:


I'm new to Xcode/Swift so this may or may not help anyone. I started getting this error after updating to iOS 13 and Xcode 11 within the app when going back to a list from a detail view.

I found that I was doing a tableView.reloadRows and tableView.insertRows in the unwind(as suggested by Apple in one of their tutorials)

@IBAction func unwindToMealList(sender: UIStoryboardSegue) {
    if let sourceViewController = sender.source as? MealViewController, let meal = sourceViewController.meal {

        if let selectedIndexPath = tableView.indexPathForSelectedRow {
            // Update an existing meal.
            meals[selectedIndexPath.row] = meal
            tableView.reloadRows(at: [selectedIndexPath], with: .none)
        }
        else {
            // Add a new meal.
            let newIndexPath = IndexPath(row: meals.count, section: 0)

            meals.append(meal)
            tableView.insertRows(at: [newIndexPath], with: .automatic)
        }
    }
}

)

I commented out that section of code and it went away.

Oddly enough leaving the sort and self.tableView.reloadData() didn't give me the error.




回答3:


extension UIView {

  func rootView() -> UIView {
     var view = self
     while view.superview.isNotNil {
         view = view.superview!
     }
     return view
  }

  var isOnWindow: Bool {
     return self.rootView() is UIWindow
    }
  }

then you just need to check if your tableView isOnWindow like...

if self.tableView.isOnWindow {
/// do stuff
}

Disclaimer: as the documentation explains, you may need to defer the call which means that there is no warranty your method will be called again so it's your responsibility to perform your update when isOnWindow is true.




回答4:


iPadOS 13.2.3 swift 5.2 Xcode 11.2.1

Just ran into this issue only when starting the app while the device was landscape. I was calling the detail seque in the viewDidLoad func of the master controller to make sure the detail view was setup correctly.

     override func viewDidLoad() {
       super.viewDidLoad()
            ...
       self.performSegue(withIdentifier: "showDetail", sender: self)
     }

When I removed the performSeque the warning not longer appeared, however, the left bar buttons on the detail controller no longer worked properly, again only when starting the app while the device was landscape. The left most button would activate the next button to the right instead of what the first button was suppose to do.

The fix for the bar buttons was to add to the viewDidLoad

     override func viewDidLoad() {
       super.viewDidLoad()
            ...
       self.splitViewController?.preferredDisplayMode = UISplitViewController.DisplayMode.allVisible
     }

Then execute

     override func viewWillAppear(_ animated: Bool) {
       self.splitViewController?.preferredDisplayMode = UISplitViewController.DisplayMode.automatic
       super.viewWillAppear(animated)
     }

I have no explanation why this worked!

This app had worked flawlessly until iPados 13 was loaded.



来源:https://stackoverflow.com/questions/57897288/uitableviewalertforlayoutoutsideviewhierarchy-error-warning-once-only-ios-13-g

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!