2

I was just looking at the clock app on the new ipad air 2 and when changing the orientation it affects the layout. There are 6 clocks in the world clock tab and in portrait there are 2 rows of 3 clocks but in landscape there is 1 row of 6 clocks.

I dont see anything based on the size classes in xcode 6 allowing a differentiation of landscape to portrait, is there a different/better way of doing this?

Shawjak3
  • 541
  • 1
  • 5
  • 18
  • 1
    I don't have an iPad Air 2 so I don't know what this looks like but it could be a `UICollectionView` with a different `UICollectionViewLayout`. Depending on what it looks like it might just be a standard `UICollectionView` flow layout. – Robotic Cat Jul 07 '15 at 23:02
  • possible duplicate of [How can I rearrange views when autorotating with autolayout?](http://stackoverflow.com/questions/30515009/how-can-i-rearrange-views-when-autorotating-with-autolayout) (although this *can* be done with size classes too) – nhgrif Jul 08 '15 at 00:25
  • Check out my answer here, it's how I went about it: http://stackoverflow.com/questions/31189792/distinguish-ipad-orientation-with-size-classes/31206948#31206948 – Kurt Anderson Jul 08 '15 at 03:29
  • Thanks those are great answers, I will look at using this idea too and see which one is better/easier. – Shawjak3 Jul 08 '15 at 14:54
  • @nhgrif question about your answer, can i do this in size classes so it wont affect iphones? For example, say i use the any width regular height to set up portrait constraints and regular width any height to set up landscape constraints. Because i feel like if i do it in the any any if i rotate an iphone the landscape constraints will affect it. – Shawjak3 Jul 08 '15 at 15:34

2 Answers2

1

There's a method--willTransitionToTraitCollection:withTransitionCoordinator:--that lets you know when any trait (e.g. horizontal size class, vertical size class, display scale, or user interface idiom) changes.

You can check newCollection.verticalSizeClass to see if it equals .Compact (landscape) or .Regular (portrait) when UIDevice.currentDevice().userInterfaceIdiom != .Pad

So, for example:

override func willTransitionToTraitCollection(newCollection: UITraitCollection, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    super.willTransitionToTraitCollection(newCollection, withTransitionCoordinator: coordinator)
    if UIDevice.currentDevice().userInterfaceIdiom != .Pad {
        switch newCollection.verticalSizeClass {
        case .Compact:
            goLandscapeWithCoordinator(coordinator)
        case .Regular, .Unspecified:
            hideLandscapeWithCoordinator(coordinator)
        }
    }
}

goLandscapeWithCoordinator(coordinator) could look something like this, for instance:

func goLandscapeWithCoordinator(coordinator: UIViewControllerTransitionCoordinator) {

    let landscapeVC = storyboard!.instantiateViewControllerWithIdentifier("LandscapeViewController") as? LandscapeViewController

    if let controller = landscapeVC {

        controller.view.frame = view.bounds
        controller.view.alpha = 0

        view.addSubview(controller.view)
        addChildViewController(controller)

        coordinator.animateAlongsideTransition({ _ in
            controller.view.alpha = 1
            },
            completion: { _ in
                controller.didMoveToParentViewController(self)
        })

    }
}
trevorj
  • 2,029
  • 1
  • 16
  • 11
  • Can you explain to me what the goLandscapeWithCoordinator(coordinator) is? What can I do in case .Compact to change items on viewcontroller. – Shawjak3 Jul 07 '15 at 22:31
  • @Suzukijak3 `goLandscapeWithCoordinator(coordinator)` and `hideLandscapeWithCoordinator(coordinator)` are custom methods that you'd have to implement. In `goLandscapeWithCoordinator(coordinator)`, for instance, you could rearrange your UI in code or instantiate an entirely different view controller. – trevorj Jul 07 '15 at 22:36
  • ok so a function named goLandscapeWithCoordinator. So let me give you an example, sorry I am fairly new to swift so forgive any errors on my part. `func goLandscapeWithCoordinator(coordinator: UIViewControllerTransitionCoordinator){ //do code here }` ?? – Shawjak3 Jul 07 '15 at 22:39
  • @Suzukijak3 Yes. I've updated my answer with an example so you can get the idea. – trevorj Jul 07 '15 at 22:44
  • Thanks for the help with this, this is a way to get around it if you like doing lots of code but I dont see another way around lots of code currently. – Shawjak3 Jul 08 '15 at 14:40
1

If you open storyboard you can find "wAny hAny" on top of the console, which allows you to specify the width and height type (compact, any, regular). If you specified some type then do layout work on storyboard, your layout will only show on the specific situation, which means you can specify different layouts in storyboard for portrait and landscape modes. For example, you can choose "Compact Width | Regular Height" the layout will be shown for all iPhones in portrait mode, and if you choose "Regular Width | Compact Height" the layout will be applied for 5.5 inch iPhones in landscape mode.

Dustin Jia
  • 67
  • 7
  • Right but there isnt an option for ipad portrait and ipad landscape like there is for iphone. Thats what I need. – Shawjak3 Jul 07 '15 at 22:38
  • You're right there's no explicitly named size classes like that. Size classes are by definition not meant to define a specific device, rather a certain class of screen. Size classes are the preferred method going forward, not explicit size checks. – Chris Slowik Jul 07 '15 at 22:40
  • Ya Im having a hard time understanding it because I came from android and you can specify orientation and screen size. But I will read up more on this, thanks for the help. – Shawjak3 Jul 08 '15 at 15:02