Why is viewWillTransitionToSize... not called when displayModeButtonItem triggers splitViewController collapse?
Asked Answered
P

3

6

I have a UISplitViewController whose secondary (detail) VC is a UICollectionViewController. I want the cells of the collection to resize based on changes to the size and aspect of the collection view. I trigger this resizing by overriding the UIContentContainer protocol method:

// MARK: - UIContentContainer protocol methods

override
func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)
{
    setFlowLayoutItemSizeForViewSize(size)
    collectionViewLayout.invalidateLayout()
}

This is called and works just how I want when the device rotates; but this method is not being called when the button supplied by splitViewController?.displayModeButtonItem() is pressed to show or collapse the primary (master) view controller. Since that collapse necessarily changes the size of the secondary (detail) view, I would have though that the viewWillTransitionToSize... method should be called when it is triggered.

So, two questions:

1) Should the viewWillTransitionToSize... method in fact be invoked when the displayModeButtonItem is pressed? If so, I seem to have found a bug.

2) If what I'm seeing is in fact the correct behavior, can anyone suggest a way for my secondary (detail) controller to "know" either when the displayModeButtonItem is pressed, or when its size is changing as a result of that button being pressed?

Thanks!

Carl

Puckery answered 21/8, 2015 at 22:36 Comment(1)
Did you ever find a solution ?Acculturation
F
6

1) Not a bug; displayModeChange is not being treated a sizeTransition

2) Your UISplitviewController most likely already has a UISplitViewControllerDelegate which can implement the optional:

splitViewController(_ svc: UISplitViewController,
      willChangeToDisplayMode displayMode: UISplitViewControllerDisplayMode)

method that will get called with UISplitViewControllerDisplayModePrimaryHidden or UISplitViewControllerDisplayModeAllVisible depending on which mode the splitView is switching to.

Firepower answered 16/10, 2015 at 16:18 Comment(4)
Thanks for the answer! It would really be great if viewWillTransitionToSize were also called, since willChangeToDisplayMode doesn't provide any information about the resulting size of the secondary view controller (this can be inferred or calculated for a specific UI design based on the display mode, but I'd really like to have a general method).Puckery
Does anyone know of a better way that KVO (as e.g. here: #25696781) to always detect when a secondary view controller's size has or is about to change?Puckery
I also have the need to trigger viewWillTransitionToSize in this case, and am having a difficult time trying to figure out if I can trigger it without hacking anythingVictorinavictorine
Can someone shed a light on why this should not be considered a bug?Salzburg
S
0

The way I solved this problem was to subclass the UISplitViewController and overriding the viewWillTransitionToSize(...) as followed:

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)

    //Get the master controller
    guard let masterController = viewControllers[0] as? UIViewController else {
        return print("master controller not of type UINavigationController")
    }

    //Notify masterController that the view will transition
    masterController.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
}

Hope it helps!

Seedcase answered 27/7, 2016 at 15:13 Comment(1)
func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) is not being called on the split view controller, when the display mode button is triggered, because the size of the root view does not change.Salzburg
L
0

There is a built-in notification for this:

// Sometimes view controllers that are using showViewController:sender and showDetailViewController:sender: will need to know when the split view controller environment above it has changed. This notification will be posted when that happens (for example, when a split view controller is collapsing or expanding). The NSNotification's object will be the view controller that caused the change.
UIKIT_EXTERN NSNotificationName const UIViewControllerShowDetailTargetDidChangeNotification NS_AVAILABLE_IOS(8_0);

See Apple's AdaptivePhotos sample for how to use it.

Livialivid answered 6/11, 2018 at 21:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.