iOS 7: Custom container view controller and content inset

前端 未结 6 622
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-02-01 05:15

I have a table view controller wrapped in a navigation controller. The navigation controller seems to automatically apply the correct content inset to the table view controller

6条回答
  •  闹比i
    闹比i (楼主)
    2021-02-01 05:23

    Swift Solution

    This solution targets iOS 8 and above in Swift.

    My app's root view controller is a navigation controller. Initially this navigation controller has one UIViewController on its stack which I will call the parent view controller.

    When the user taps a nav bar button, the parent view controller toggles between two child view controllers on its view using the containment API (toggling between mapped results and listed results). The parent view controller holds references to the two child view controllers. The second child view controller is not created until the first time the user taps the toggle button. The second child view controller is a table view controller and exhibited the issue where it underlaps the navigation bar regardless of how its automaticallyAdjustsScrollViewInsets property was set.

    To fix this I call adjustChild:tableView:insetTop (shown below) after the child table view controller is created and in the parent view controller's viewDidLayoutSubviews method.

    The child view controller's table view and the parent view controller's topLayoutGuide.length are passed to the adjustChild:tableView:insetTop method like this...

    // called right after childViewController is created
    adjustChild(childViewController.tableView, insetTop: topLayoutGuide.length)
    

    The adjustChild method...

    private func adjustChild(tableView: UITableView, insetTop: CGFloat) {
        tableView.contentInset.top = insetTop
        tableView.scrollIndicatorInsets.top = insetTop
    
        // make sure the tableview is scrolled at least as far as insetTop
        if (tableView.contentOffset.y > -insetTop) {
            tableView.contentOffset.y = -insetTop
        }
    }
    

    The statement tableView.scrollIndicatorInsets.top = insetTop adjusts the scroll indicator on the right side of the table view so it begins just below the navigation bar. This is subtle and is easily overlooked until you become aware of it.

    The following is what viewDidLayoutSubviews looks like...

    override func viewDidLayoutSubviews() {
        if let childViewController = childViewController {
            adjustChild(childViewController.tableView, insetTop: topLayoutGuide.length)
        }
    }
    

    Note that all the code above appears in the parent view controller.

    I figured this out with help from Christopher Pickslay's answer to the question "iOS 7 Table view fail to auto adjust content inset".

提交回复
热议问题