UICollectionView in landscape on iPhone X

前端 未结 6 643
余生分开走
余生分开走 2021-01-31 02:41

When iPhone X is used landscape, you\'re supposed to check safeAreaInsets to make suitably large gutters on the left and right. UITableView has the new insetsContentViewsT

相关标签:
6条回答
  • 2021-01-31 02:48

    While Nathan is correct about the versatility of UICollectionView with various layouts, I was mainly concerned about the "default" case where one is using UICollectionViewFlowLayout.

    Turns out, iOS 11 has added a sectionInsetReference property to UICollectionViewFlowLayout. The official documentation on it currently lacks a description, however the headers describe it as

    The reference boundary that the section insets will be defined as relative to. Defaults to .fromContentInset.

    NOTE: Content inset will always be respected at a minimum. For example, if the sectionInsetReference equals .fromSafeArea, but the adjusted content inset is greater that the combination of the safe area and section insets, then section content will be aligned with the content inset instead.

    The possible values are

    @available(iOS 11.0, *)
    public enum UICollectionViewFlowLayoutSectionInsetReference : Int {
        case fromContentInset
        case fromSafeArea
        case fromLayoutMargins
    }
    

    and setting it to .fromSafeArea produces the desired results, i.e., when initially in portrait orientation:

    then when rotating to landscape, the cells are inset such that they are entirely within the safe area:

    ... HOWEVER, there's currently a bug, and when rotating back to portrait after the view has been in landscape, it continues to act as if the left/right safeAreaInsets are set to the landscape values:

    I've filed a radar (rdar://34491993) regarding this issue.

    0 讨论(0)
  • 2021-01-31 02:59

    Having the same issue. This worked for me:

    override func viewDidLoad() {
        if #available(iOS 11.0, *) {
            collectionView?.contentInsetAdjustmentBehavior = .always
        }
    }
    

    The documentation for the .always enum case says:

    Always include the safe area insets in the content adjustment.

    This solution works correctly also in the case the phone is rotated.

    0 讨论(0)
  • 2021-01-31 03:00

    Bare in mind the above solutions do not solve the case where your collection cell views (and subviews that are constrained to its cell's leading or trailing edges) are full-width to the collection view bounds and aren't set to obey Safe Area Layout Guides.

    Note: The answer by @petrsyn makes the header inset from the sides, which most people might not want and the answer by @Wes Campaigne doesn't really work correctly for full-width cells, where a subview is attached to the leading or trailing edges of the cell.

    It's imperative, especially for those coming from older projects, to set your Xib and Storyboard files to Use Safe Area Layout Guides and then use auto layout to place constraints respective to the the safe areas or do similar in code.

    0 讨论(0)
  • 2021-01-31 03:08

    If you're adding collection view as your main view's subview programmatically - then you can just do this in your viewDidLoad method:

    collectionView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(collectionView)
    
    NSLayoutConstraint.activate([
            collectionView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            collectionView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
            collectionView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
            collectionView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor)
    ])
    
    0 讨论(0)
  • 2021-01-31 03:10

    UICollectionView is intended to be flexible for a wide variety of layouts. The most common layouts are grids with multiple rows and columns, but it's possible to create non-grid layouts with UICollectionView.

    UITableView, on the other hand, is designed for full-width cells.

    Therefore, it makes sense that UITableView would have built-in support for dealing with safe area insets, since table view layouts will always be affected by it. Because UICollectionView uses custom layouts, it makes sense to solve these issues on a per-implementation basis instead of trying to provide a one-size-fits-all solution.

    0 讨论(0)
  • 2021-01-31 03:12

    Thanks to above for help. For my UICollectionViewController subClass, I added the following to viewDidLoad() (Swift 3):

    if let flowLayout = collectionView?.collectionViewLayout as? UICollectionViewFlowLayout {
        if #available(iOS 11.0, *) {
            flowLayout.sectionInsetReference = .fromSafeArea
        }
    }
    
    0 讨论(0)
提交回复
热议问题