kkjdaniel/react-native-device-display

Fixed Bugs and Made Changes

Closed this issue · 6 comments

Hey, I know there is some official means of doing this but I'm not familiar with git really...

Anyway I made some changes I think are pretty good including the bug fix mentioned in previous

   UIDeviceOrientation deviceOrientation = [[UIDevice currentDevice] orientation];
   NSDictionary *dimensions = @{ @"width": @(frameSize.width), @"height": @(frameSize.height),      @"orientation": @(deviceOrientation) };
   NSLog(@"%@", dimensions);
   [_bridge.eventDispatcher sendDeviceEventWithName:@"orientationDidChange" body:dimensions];

I now include the actual device orientation in the dictionary. I also fixed the issue with sending the wrong width / height (it was flipped around).

Then I receive the orientation in the event receiver and parse it. I also send the new data in the handler.

 onOrientationDidChange(handler) {
     var main = this;
     return RCTDeviceEventEmitter.addListener(
       'orientationDidChange',
       function(newDimensions) {
         main.updateProps(newDimensions.width, newDimensions.height);
         var orientation = main.updateOrientation(newDimensions.orientation);
         handler(newDimensions.width, newDimensions.height, orientation);
       }
     );
   }

I parse the orientation to return easier to work with object:

 updateOrientation(orientation) {
     var o = {};
     switch (orientation) {
       case 1:
         o = {
           current: 'portrait',
           idle: false,
           facing: ''
         };
         break;
       case 2:
         o = {
           current: 'portrait',
           idle: false,
           facing: ''
         };
        break;
       case 3:
         o = {
           current: 'landscape',
           idle: false,
           facing: ''
         };
         break;
       case 4:
         o = {
           current: 'landscape',
            idle: false,
           facing: ''
         };
         break;
       case 5:
         o = {
           current: this.orientation.current,
           idle: true,
           facing: 'up'
         };
         break;
       case 6:
         o = {
           current: this.orientation.current,
           idle: true,
           facing: 'down'
         };
         break;
     }
     console.log('Orientation Updated');
     console.log(o);
     this.orientation = o;
     return o;
   }

And now my handler receives:
NEW ORIENTATION DISCOVERED!
index.ios.js:22 Height: 716
index.ios.js:23 Width: 414
index.ios.js:24 Orientation:
index.ios.js:25 Object {current: "portrait", idle: true, facing: "up"}

Tried your fix - worked like a charm! Thank you!
I've made a pull request to the repo with your suggested changes, so everyone can enjoy your fix!

Awesome, thanks.

Hi, I've tried master (as these changes aren't versioned yet) and it works fine when I develop and reload the app, but not on when I launch the app for the first time.

I can't really figure out what the issue is, it appears that [UIScreen mainScreen].applicationFrame returns the wrong data (and now I understand the crazy swap of width and height).

However, googling around, it seems that UIDeviceOrientationDidChangeNotification is deprecated in favor of viewWillTransitionToSize:
http://stackoverflow.com/questions/26069874/what-is-the-right-way-to-handle-orientation-changes-in-ios-8
Maybe it's worth exploring the new style?

Hi again,

I did additional tests, and I believe that viewWillTransitionToSize is the right way to go. It also works on slide over (multitasking) on ipad/ios9.

All I did to test is to implement a viewcontroller, and use it in my AppDelegate:

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator
{
  UIDeviceOrientation deviceOrientation = [[UIDevice currentDevice] orientation];
  NSDictionary *dimensions = @{ @"width": @(size.width), @"height": @(size.height), @"orientation": @(deviceOrientation) };

  NSLog(@"%@", dimensions);

  [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}

Unfortunately I have no idea how to send an event to js, here I need your help :)

Last comment for today, promised. I made it work with a hack: I created the controller, sent a notification, and used this module to listen to my own notification instead of UIDeviceOrientationDidChangeNotification.

I asked on SO, if I can find a better/cleaner solution, I'll post a PR:
http://stackoverflow.com/questions/33469009/implement-native-controller-in-react-native

Merged. #16