Detecting iOS UIDevice orientation

后端 未结 8 892
一生所求
一生所求 2020-11-28 03:29

I need to detect when the device is in portrait orientation so that I can fire off a special animation. But I do not want my view to autorotate.

How do I override a

相关标签:
8条回答
  • 2020-11-28 04:06

    .UIDeviceOrientationDidChange notification is called many times on iphone even when device did not rotate. Do not know the reason, but if you need it only when device really rotated, then do the following.

    NotificationCenter.default.addObserver(self, selector: #selector(orientationChanged), name: .UIDeviceOrientationDidChange, object: nil)
    

    The method called from observer should look like this:

    func orientationChanged() {
    
        if traitCollection.isIphone {
    
            defer {
                self.previousTraitCollectionForIphone = traitCollection
            }
    
            guard let previousTraitCollectionForIphone = previousTraitCollectionForIphone else {
    
                updateView()
                return
            }
    
            if previousTraitCollectionForIphone != traitCollection {
                updateView()
            }
    
        } else {
            updateView()
        }
    }
    
    0 讨论(0)
  • 2020-11-28 04:09

    1) Swift version of David's answer 2) In case you still want to detect orientation when there's no orientation change (Swift vesion of Moe's answer to How Do I detect the orientation of the device on iOS?)

        // Initial device orientation
        let orientation: UIInterfaceOrientation = UIApplication.sharedApplication().statusBarOrientation
        if(orientation == UIInterfaceOrientation.Unknown){
            // code for Unknown
        }
        else if(orientation == UIInterfaceOrientation.Portrait){
            // code for Portrait
        }
        else if(orientation == UIInterfaceOrientation.PortraitUpsideDown){
            // code for Portrait
        }
        else if(orientation == UIInterfaceOrientation.LandscapeRight){
            // code for Landscape        
        }
        else if(orientation == UIInterfaceOrientation.LandscapeLeft){
            // ode for Landscape
        }
    
        // To detect device orientation change
        UIDevice.currentDevice().beginGeneratingDeviceOrientationNotifications()
        NSNotificationCenter.defaultCenter().addObserver(
            self,
            selector: "orientationChanged:",
            name: UIDeviceOrientationDidChangeNotification,
            object: UIDevice.currentDevice())
    

    orientationChanged function

    func orientationChanged(note: NSNotification)
    {
        let device: UIDevice = note.object as! UIDevice
        switch(device.orientation)
        {
            case UIDeviceOrientation.Portrait:
            // code for Portrait
            break
            case UIDeviceOrientation.PortraitUpsideDown:
            // code for Portrait
            break
            case UIDeviceOrientation.LandscapeLeft:
            // code for Landscape
            break
            case UIDeviceOrientation.LandscapeRight:
            // code for Landscape
            break
            case UIDeviceOrientation.Unknown:
            // code for Unknown
            break
            default:
            break
        }
    }
    
    0 讨论(0)
  • 2020-11-28 04:11

    If I understand you correctly, your app is landscape only. You can simply specify in the apps setup that it is landscape only and therefore do not need to worry about rotation. The app will start in landscape and stay there regardless of how the iPad is orientated.

    0 讨论(0)
  • 2020-11-28 04:15

    If you came to this question looking for how to detect an orientation change (without necessarily wanting to disable the rotation), you should also be aware of viewWillTransitionToSize, which is available from iOS 8.

    Swift example from here

    override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    
        coordinator.animateAlongsideTransition({ (UIViewControllerTransitionCoordinatorContext) -> Void in
    
            let orient = UIApplication.sharedApplication().statusBarOrientation
    
            switch orient {
            case .Portrait:
                println("Portrait")
                // Do something
            default:
                println("Anything But Portrait")
                // Do something else
            }
    
            }, completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in
                println("rotation completed")
        })
    
        super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
    }
    

    And if you don't need to worry about the actual orientation:

    override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    
        // do something
    
        super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
    }
    

    Objective-C example from here

    - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
    {   
        [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context)
        {
            UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
            // do whatever
        } completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
        { 
    
        }];
    
        [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    }
    

    And if you don't need to worry about the actual orientation (taken from this answer):

    - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
    {
        // Do view manipulation here.
        [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    }
    

    See also

    • iOS 8 Orientation Change Detection
    • iOS8 Day-by-Day :: Day 14 :: Rotation Deprecation
    0 讨论(0)
  • 2020-11-28 04:17

    Try doing the following when the application loads or when your view loads:

    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
    [[NSNotificationCenter defaultCenter]
       addObserver:self selector:@selector(orientationChanged:)
       name:UIDeviceOrientationDidChangeNotification
       object:[UIDevice currentDevice]];
    

    Then add the following method:

    - (void) orientationChanged:(NSNotification *)note
    {
       UIDevice * device = note.object;
       switch(device.orientation)
       {
           case UIDeviceOrientationPortrait:
           /* start special animation */
           break;
    
           case UIDeviceOrientationPortraitUpsideDown:
           /* start special animation */
           break;
    
           default:
           break;
       };
    }
    

    The above will allow you to register for orientation changes of the device without enabling the autorotate of your view.


    Note

    In all cases in iOS, when you add an observor, also remove it at appropriate times (possibly, but not always, when the view appears/disappears). You can only have "pairs" of observe/unobserve code. If you do not do this the app will crash. Choosing where to observe/unobserve is beyond the scope of this QA. However you must have an "unobserve" to match the "observe" code above.

    0 讨论(0)
  • 2020-11-28 04:17

    First disable all but the orientation you want (so that it doesnt rotate)

    Then like David said just get the device current orientation:

    https://developer.apple.com/library/ios/#documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/MotionEvents/MotionEvents.html

    Alternatively you can just use the accelerometer yourself (since its how it is done anyway) and check where the gravity is at to see what orientation it has. If you take this approach you can play with the values yourself to get different results.

    0 讨论(0)
提交回复
热议问题