DEV Community

ShoheOhtani
ShoheOhtani

Posted on

[ReactNative] How to control view orientation for Native Module

Image description

3 Steps

  1. Modify AppDelegate.h / AppDelegate.m
  2. Create AppUtility.swift for update orientation easily
  3. Fix view's position for ReactNative

Step1: Modify AppDelegate

AppDelegate.h

// add property
@property (nonatomic, assign) UIInterfaceOrientationMask orientationLock;
Enter fullscreen mode Exit fullscreen mode

AppDelegate.m

- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
  return _orientationLock;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{ ...
// default value
_orientationLock = UIInterfaceOrientationMaskPortrait; 
...
}
Enter fullscreen mode Exit fullscreen mode

Step2: Create AppUtility.swift

struct AppUtility {
  static func lockOrientation(_ orientation: UIInterfaceOrientationMask) {
    if let delegate = UIApplication.shared.delegate as? AppDelegate {
      delegate.orientationLock = orientation
    }
  }

  /// OPTIONAL Added method to adjust lock and rotate to the desired orientation
  static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation:UIInterfaceOrientation) {
    self.lockOrientation(orientation)

    UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
    UINavigationController.attemptRotationToDeviceOrientation()
  }
}
Enter fullscreen mode Exit fullscreen mode

Step3: Fix view's position for ReactNative
When you update orientation, view's position will move wrong position. So, when it's happened call this function.

private func fixViewPosition() {
    // Wait 0.1 sec and fix position.
    // It wont be fixed position in some case, so fix twice with 0.1 sec delay for that wired bug.
    DispatchQueue.main.asyncAfter(deadline: .now()+0.1) { [self] in
      let fixedPosition = CGPoint(x: -UIScreen.main.bounds.midX + targetView.bounds.midX, y: -UIScreen.main.bounds.midY + targetView.bounds.midY)
      view.bounds.origin = fixedPosition
      DispatchQueue.main.asyncAfter(deadline: .now()+0.1) { [self] in view.bounds.origin = fixedPosition }
    }
  }
Enter fullscreen mode Exit fullscreen mode

Top comments (0)