0

I am making a drawing app and I would like the user to be able to rotate their device and draw on the canvas in any orientation. The toolbar of brushes/colors/etc needs to change orientation to always be on the top of the screen HOWEVER the drawing canvas needs to NOT change orientation (so as to preserve the drawing's orientation; imagine rotating a piece of paper with a drawing on it - the drawing would sometimes be sideways or upside down but your pencils would be still right in front of you).

I have tried several attempts and have concluded that I DO want to support iOS's default orientation changes because things like UIAlert popups need to be oriented correctly. Implementing override var supportedInterfaceOrientations: UIInterfaceOrientationMask on the view controller is not the best option.

I have gotten closer by subscribing to device orientation changed notifications and rotating the drawing canvas in the opposite direction to compensate for the default UI orientation rotation. In this case I am applying a CGAffineTransform rotation of 90, -90, 0, or 180 degrees to the canvas container view but its subviews are not rotating correctly with it.

Any ideas that I may be missing to get the behavior I want?

This is what I want. Notice how the toolbar is always being oriented to the top after rotation but the drawing stays glued to the device.

Before orientation change:

After orientation change:

aircraft
  • 25,146
  • 28
  • 91
  • 166
Tyler White
  • 398
  • 4
  • 10
  • Possible duplicate of [Force landscape for one view controller ios](http://stackoverflow.com/questions/18409310/force-landscape-for-one-view-controller-ios) –  Mar 25 '17 at 03:46
  • How are the subviews of the canvas view laid out? For example, are they simply placed on the canvas view with no constraints? Or are you using autolayout? – Fahim Mar 25 '17 at 04:13
  • @Fahim They use autolayout. – Tyler White Mar 25 '17 at 04:24

1 Answers1

0

I did a quick test app to see if what you experienced (with regards to rotating the canvas view and not having its subviews rotate as well) and I cannot replicate what you're seeing.

I simply have an observer set up on viewDidLoad from the main view:

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

And the orientation change notification is handled like this:

func orientationChanged(_ n:Notification) {
    let orientation = UIDevice.current.orientation
    if orientation == UIDeviceOrientation.portrait {
        // No rotation
        vwCanvas.transform = CGAffineTransform(rotationAngle:0)
    } else if orientation == UIDeviceOrientation.portraitUpsideDown {
        // Rotate canvas 180 degrees
        vwCanvas.transform = CGAffineTransform(rotationAngle:CGFloat.pi)
    } else if orientation == UIDeviceOrientation.landscapeLeft {
        // Rotate canvas 90 degrees counterclockwise
        vwCanvas.transform = CGAffineTransform(rotationAngle:CGFloat.pi/2.0)
    } else if orientation == UIDeviceOrientation.landscapeRight {
        // Rotate canvas 90 degrees clockwise
        vwCanvas.transform = CGAffineTransform(rotationAngle:-CGFloat.pi/2.0)
    }
}

Here's my portrait orientation screen:

enter image description here

And here's the rotated version: enter image description here

As you'll notice, the sub-views are rotated in the above too. So just wondering what the difference is between my version and yours (since I don't know what your code is like) that you don't have the subviews rotate when you rotate the canvas ...

Fahim
  • 3,466
  • 1
  • 12
  • 18