StrawHara
StrawHara

Reputation: 1321

Catch rotation event into UIInputViewController

I'm developing a custom Keyboard and I'm trying to catch a device rotation event.

I've already tried :

override func viewDidLayoutSubviews() {
    print("Foo")
}

and

override func viewWillLayoutSubviews() {
    print("🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳 Bar")
}

and

override func didRotateFromInterfaceOrientation(sender : UIInterfaceOrientation){ 
    print("🐳🐳🐳🐳");
}

and

 override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    print("Bar")
}

and

override func updateViewConstraints() {
    super.updateViewConstraints()
    print("🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳 Foo")
}

But it's not working.

iPad Air 2 Simulator - iOS9

Any idea ?

Upvotes: 1

Views: 773

Answers (3)

ΠœΠΎΡ€Ρ‚
ΠœΠΎΡ€Ρ‚

Reputation: 1179

Most of the methods related to rotation are deprecated now. Apple is moving towards sizes and traits changes notifications, and not so much direct device orientation change notifications.

Also, UIDevice.currentDevice().orientation always returns Unknown in keyboard extensions with both Full Access and beginGeneratingDeviceOrientationNotifications.

The correct method (and the one listed as replacement for the deprecated methods in the documentation) is

- viewWillTransitionToSize:withTransitionCoordinator:

It's strange that it didn't work for you. I just tried it in an UIInputViewController on iPad Air 2 iOS9 Simulator and it works:

2015-10-13 12:28:15.347 [Info] [KeyboardViewController.swift:60] viewWillTransitionToSize(:withTransitionCoordinator:) > Rotate to size (1024.0, 313.0) 2015-10-13 12:28:20.512 [Info] [KeyboardViewController.swift:60] viewWillTransitionToSize(:withTransitionCoordinator:) > Rotate to size (768.0, 313.0)

Are you debugging the correct target? To see console messages from your extension, you must set it as the run target: enter image description here

Note that there is also

- willTransitionToTraitCollection:withTransitionCoordinator:

But this one won't work for the iPad, because the iPad is always Regular,Regular for both landscape and portrait.

Upvotes: 1

Charles Truluck
Charles Truluck

Reputation: 981

It looks like this works in my project with iOS 9 and iPad Air 2:

override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
    print("hi")
}

it looks like you tried that but it didn't work though...

Upvotes: 0

Rory McKinnel
Rory McKinnel

Reputation: 8014

Not all view controllers will receive the transition events. I think it depends on whether your view controller is inside a container controller like a UINavigationController or UITabBarController and whether they pass the change on to their child controllers or not.

A guaranteed method of receiving orientation changes would be to register for UIDevice orientation change notifications. See https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIDevice_Class/#//apple_ref/c/data/UIDeviceOrientationDidChangeNotification for the list of notification events.

Here is what you would do in ObjC. Should translate easy enough to Swift.

In your app delegate activate orientation changes using:

 [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

In the view controller you want notifications add methods to handle the notification, add and remove observing the notification.

// Method to be called when orientation notification is changed.
- (void)orientationDidChange:(NSNotification *)notification { 
  // Add your code to deal with the orientation.
  // You can get the current orientation for UIDevice as follows:

  UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
}

// Adds observation of orientation change
-(void)addObserver
{
    [[NSNotificationCenter defaultCenter] addObserver:self 
     selector:@selector(orientationDidChange:) 
     name:@"UIDeviceOrientationDidChangeNotification" 
     object:nil];
}

// Removes observation of orientation change
-(void)removeObserver
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

Add calls to addObserver and removeObserver in an appropriate place. viewDidAppear and viewDidDisappear for example.

Upvotes: 0

Related Questions