UIMoreListTableView

I am experiencing a problem with the latest version of Xcode, version 11 (now 11.3). I have a tab bar that has one too many items to fit and so has a More list tableview to the final two selections (tabs). This works fine, but when I change the appearance of the UIMoreListTableView, the changes happen when the tableview is not (yet) in the view hierarchy, resulting in a warning. This doesn't appear to cause a problem in practice, but I would like to be able to remove the warning. Here is the text of the warning I get:



2019-12-29 07:37:30.880610-0600 DunePlants[1545:546936] [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: <_UIMoreListTableView: 0x10604c000; frame = (0 20; 375 647); clipsToBounds = YES; autoresize = W+H; tintColor = <UIDynamicCatalogColor: 0x2839d4540; name = ERG-green>; gestureRecognizers = <NSArray: 0x283903150>; layer = <CALayer: 0x28374b960>; contentOffset: {0, 0}; contentSize: {375, 88}; adjustedContentInset: {0, 0, 0, 0}; dataSource: <UIMoreListController: 0x105266770>>



If I don't try to set the font and tintColor of the More List TableView, I don't get a warning. But I want to use a font and color consistent with my choices for the rest of the App. Here is the code I use:



class ERGViewController: UITabBarController {



override func viewDidLoad() {

super.viewDidLoad()

}


override func viewDidAppear(_ animated: Bool) {

//Next line gets rid of edit button and ability to reorder tabs.

moreNavigationController.topViewController?.navigationItem.rightBarButtonItem = nil

//If above line is commented out, you need to color the Edit button appropriately

moreNavigationController.topViewController?.navigationItem.rightBarButtonItem?.tintColor = UIColor.custom

if let moreList = moreNavigationController.viewControllers.first(where: { String(describing: type(of: $0)) == "UIMoreListController" }) {

moreList.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)

moreList.navigationItem.backBarButtonItem?.tintColor = UIColor.custom

}

tabBarController?.customizableViewControllers = []

if let moreTableView = moreNavigationController.topViewController?.view as? UITableView {

moreTableView.tintColor = UIColor.custom

for cell in moreTableView.visibleCells {

cell.tintColor = UIColor.custom

cell.textLabel?.font = UIFont(name: "AvenirNextCondensed-Medium", size: 20)

}

}

}

}



Is there someplace better to set the font and tintColor?

Accepted Reply

Yes, I wouyld ignore the warning.

For the color, may be you can set a very short delay (0.1 s) but only on first appearance. It'd a bit of a hack, but…

Replies

If I don't try to set the font and tintColor of the More List TableView

So the risk of trying to layout with inconsistent data should not occur.


Have a look here

https://forums.developer.apple.com/thread/120790


Could try to set font and color in DispatchQueue.main.async


        DispatchQueue.main.async { () -> Void in
            for cell in moreTableView.visibleCells {
                cell.tintColor = UIColor.custom
                cell.textLabel?.font = UIFont(name: "AvenirNextCondensed-Medium", size: 20)
            }
     }

Doesn't seem to help. The trick would seem to be to delay adding the tintColor and font to the tableview only after the More ... button in the tab bar controller is fired. But I guess I don't see how to delay to that point. If I call the DispatchQueue.main queue from the tab controller's viewDidLoad or anywhere else, for that matter, the code won't wait until the user wants to see the More tableview. That's all under Apple's control, not mine, I think. It didn't hurt to include the code in the main thread, as suggested, but it also didn't help. The forum thread suggested seems to say that it is best to ignore the warning, right?

Yes, I wouyld ignore the warning.

For the color, may be you can set a very short delay (0.1 s) but only on first appearance. It'd a bit of a hack, but…