2
votes

I am trying to create a view that doesn't rotate with device orientation. I want just this one view to not rotate because I have a UIToolbar that I don't want to rotate. Is this possible? If so, how do I implement it? I am using Swift. Also, is it possible to rotate the UIBarButtonItems with device orientation on the UIToolbar? If so, how do I implement that? Just to restate: I want the view and toolbar within it to not rotate with orientation; I want the buttons on the toolbar to rotate with orientation. Thanks.

5
@devian It's not a duplicate because I do not want my toolbar to rotate with orientation. I want the buttons on the toolbar to rotate with orientation. Also, I don't believe that question is written in Swift. โ€“ TonyStark4ever

5 Answers

2
votes

Per the View Controller Programing Guide

If you want to temporarily disable automatic rotation, avoid manipulating the orientation masks to do this. Instead, override the shouldAutorotate variable on the initial view controller. This method is called before performing any autorotation. If it returns NO, then the rotation is suppressed.

So you need to subclass 'UINavigationController', implement shouldAutorotate and use your navigation controller class in your storyboard.

Swift 3

override var shouldAutorotate: Bool {
    let currentViewController = self.topViewController
    return !currentViewController.isKind(of: DetailViewController.classForCoder())
}
1
votes

Why not just rotate the view in question -90 degrees or +90 degrees as required? I'll happily provide example code if you'd like. Edit: I was suggesting something like this (but look at the caveat after the code):

let degrees = 90.0 // or -90, 180 depending on phone's movement.
let rotatedView: UIView = <yourOriginalView>
rotatedView.transform = CGAffineTransform = CGAffineTransform(rotationAngle: degrees * CGFloat(M_PI / 180))

In iOS 8.0 and later, the transform property does not affect Auto Layout. Auto layout calculates a viewโ€™s alignment rectangle based on its untransformed frame. -- So this might not work for your purposes if you're using autolayout.... And I admit this is a kludge. ๐Ÿ˜‰๐Ÿ™„๐Ÿ˜‰

1
votes

I see two possibilities, and prefer the second because it doesn't rotate your views twice. I will use the term static view for the single view that you don't want to rotate (= the UIToolbar).


Possibility 1

Subscribe to device orientation changes. Then, when the orientation changes, and the UI rotates, rotate the static view in the opposite direction.

For example when you get a notification that the device is rotated 90ยฐ clockwise:

  • The whole user interface (including the static view) will rotate 90ยฐ counterclockwise automatically
  • Rotate the static view 90ยฐ clockwise, to cancel the automatic rotation behaviour.

Possibility 2

Disable the automatic rotation behaviour and then manually rotate all views except the one you don't want to rotate. To rotate multiple views at once: put them in a custom view and rotate that custom view. Here is a step-by-step guide:

  1. Disable automatic rotation in your view controller. Do this by overriding the ViewController's shouldAutoRotate variable.

  2. In interface builder: put everything except the static view in a custom UIView.

  3. Observe device orientation changes and rotate the statusbar and your custom view (you created in step 2) when the device's orientation changes.

An example implementation in swift can be found at: GitHub/Dev1an/Static iOS toolbar


Rotating views

For the question "how to rotate views" have a look at: https://stackoverflow.com/a/28717635/2616297

1
votes

Straightforward. You should simply override the shouldRotate variable and set it to false for the VC you wish to prevent rotation in.

UPDATED - Swift 3

override var shouldAutorotate: Bool {
    return false    
}
0
votes

I used the information from all of the answers here, as well as from this post overriding shouldAutorotate not working in Swift 3, to find the answer to my question. I created a MainNavigationController class within my MainViewController.swift file and then overrided shouldAutorotate like so:

import UIKit

class MainNavigationController: UINavigationController {

override var shouldAutorotate: Bool {
   return false    }

}

class MainViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()

    }
}

The last step was to go into my Main.storyboard file, click on the navigation controller for the view, and change its class to MainNavigationController. Once I did that, it worked perfectly. Thanks to all the people who answered this question.