Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set Notification if view size changed when using multitasking | Swift

When testing my app on an iPad using multitasking and I change the app size on the app, the collection view cells need to be resized or else they don't fit in the view window.

I have took some measures such as

  • detecting device to change the size of the cells
  • measure view size to make sure cells fit within the window
  • Add an observer if user changes device orientation

This is all great but however when actually changing the window size when using multitasking, or going back to the full screen app, the cell sizes don't change and look out of place. This is until forced by switching orientation or switching view controllers so viewWillLoad or viewDidLoad gets executed again.

So how can I set a notification if the view.frame size changes ?

like image 776
A.Roe Avatar asked Mar 30 '16 01:03

A.Roe


3 Answers

I think the right function to override is viewWillTransition(to:, with:). It is called whenever the container size is about to change.

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)

    self.collectionView?.collectionViewLayout.invalidateLayout()
}
like image 72
Jadamec Avatar answered Oct 19 '22 03:10

Jadamec


I think you are over complicating the issue, just use the following so when the device is rotated or resized the collection view also changes accordingly.

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    guard let collectionLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout else {
        return
    }

    if UIApplication.shared.statusBarOrientation == UIInterfaceOrientation.landscapeLeft ||
        UIApplication.shared.statusBarOrientation == UIInterfaceOrientation.landscapeRight {
        //here you can do the logic for the cell size if phone is in landscape
    } else {
        //logic if not landscape
    }

    collectionLayout.invalidateLayout()
}
like image 25
RileyDev Avatar answered Oct 19 '22 02:10

RileyDev


I tried RileyDev answer but the app entered in an infinite loop.

There is no delegate that is executed just when the App's window bounds change, so I've made my own version of the viewWillTransition(to size and traitCollectionDidChange.

With the code below you can detect the window bounds resizing change even if the traits don't change, and resize your collection view cells accordingly invalidating the collection view layout.

var previousWindowBounds: CGRect?

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    if let currentBounds = view.window?.bounds,
        let previousWindowBounds = previousWindowBounds, currentBounds != previousWindowBounds {
        collectionView?.collectionViewLayout.invalidateLayout()
    }

    previousWindowBounds = view.window?.bounds
}
like image 1
rockdaswift Avatar answered Oct 19 '22 02:10

rockdaswift