Disabling autorotation for specific UIView iOS 12 - ios

How do I allow one subview of my view controller to autorotate on an orientation change, but keep the others static. I'm trying to get an effect similar to the native camera app where the capture and switch cameras buttons (along with all the others) stay in their locations and just rotate accordingly. The SnapChat app also does this where the UI layer that pops up after you take a photo autorotates but the other views do not.
I seemed to be able to get close following the answers here: Disable autorotate on a single subview in iOS8, however, while this prevents them from rotating, it jumbles up their positions.

I think you have to use
(i) autolayout to set constraints on view by fixing its position or width height.
for setting orientation for portrait and landscape you have to use size classes
(ii) Another trick is you can use UIViewController to fix orientation using its mask orientation delegate. then add it add child of other UIViewController

Related

How to stop autorotion of selected subview in UIViewController

I have a View Controller I have started an AVCaptureSession on the view of the View Controller,
AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
Now I add it like this,
[self.view.layer addSubLayer: captureVideoPreviewLayer]
I also have added two buttons on storyboard in this View Controller, On rotation of the device the self.view should not rotate as it has the camera going on but I want the two buttons which are capture and cancel button to align and rotate,
How can I achieve this using storyboard.
Unfortunately this is not as easy as it should be. You may not simply "not rotate" a single view while the rest of the UI is rotated.
Since you are using a camera I suggest you to capture the the device orientation change through the notification center while keeping the controller orientation locked to whatever is your default or current state.
On orientation change you should then try and rotate the view with your buttons or anything else that should rotate. This is best done if all of the controls are added to a single view which has the same size as the view controller and is centered in the view controller. This means the constraints for this view are center x, center y, width, height. You need outlets for width and height and set them manually in the code. When view will layout subviews (it is a method to override in the view controller) simply set the width and height to the same as is the view controller controller.view.frame.size. Till this point your application should look exactly the same as it does now if rotations are disabled.
Now for the fun part: You need to check the current orientation and apply a rotation transform on the view with the buttons. What you need is a property holding the current interface orientation and upon changing that orientation you should apply a different transform to the view. The device orientation will not give you the interface orientation as device orientation includes extra positions. So when device orientation changes you need to use a switch statements and only on the 4 orientations that make sense should you change the interface orientation.
Once you have all that you should create a method that takes a user interface orientation as input and and will reposition the view with the buttons. (assuming you use portrait by default) You need to swap the width and height when the interface orientation is landscape as in widthConstraint.constant = controller.view.frame.size.height and apply a rotation transform depending on the orientation.
This method should be called when:
The controller will become visible with the application status bar orientation
When view will layout with the same orientation as was previously saved from view will become visible or device orientation change
When device orientation changes if the new orientation makes sense and is different then the currently set interface orientation
There are other ways of doing this though. For instance you may keep the rotation of the view controller and rotate the camera view with the same procedure and this is even easier since you may use viewWillTransitionToSize and animateAlongsideTransition but the animation will probably not be acceptable as you may see black parts when the view controller is oriented. Though I am not sure that will actually occur and even if it does it might be possible to fix it with disabling bound clipping on the controller view.

Get UIButton labels to move under button image on device rotation

I have some UIButtons that when shows in portrait look like this
When I rotate the device to landscape, I want the label to be underneath the image.
I've seen this answer to getting the label beneath the button image - Label under image in UIButton but can't figure out how and where to implement this on device rotation that is safe.
My view hierarchy for this section looks like this with the UIScrollView as subview of the main UIView
I am targeting iOS 8 and using AutoLayout. I have seen some answers using layoutSubviews for other questions that do something similar but I've seen that layoutSubviews will be called on each rotation. I need this to only happen on landscape layouts.

Is it possible to change views when the device is rotated?

When the device is in portrait mode, I want to show text details about a graph, and when the user rotates it, I want my UIWebView to take up the full screen. This functionality can be seen in the iOS Stock app. When you are portrait, you can view all your stocks, and when the app is landscape, the full size graph is shown. How do i do this?
In your UIViewController sub-class override willRotateToInterfaceOrientation: to replace the view contents with the view contents for the appropriate destination orientation. I'd suggest using [UIView transitionFromView:toView:...] for smoother animations.

iPad application, changing popover dimensions whilst view is loaded

I have an app in which its my intention to change screen orientation as the user rotates the iPad. In my app I have several popovers.
The potential issue I'm concerned about is one of my popovers covers most the screen so if rotation changes, I'd want the popover to change view dimensions. Is it possible whilst a view is open or will i have to close it and reopen it.
Thanks
If your using a UIPopoverController the standard behaviour it does is to hide the popover when you rotate. It try's to then reposition it for you, this tends not to work so you want to use popoverController:willRepositionPopoverToRect:inView to set your new position and resize as needed.
If you use setPopoverContentSize:animated: it will re size for you, If your using autolayout you'll want to use preferredContentSize in the content viewController.
Apple Doc:
If the user rotates the device while a popover is visible, the popover
controller hides the popover and then shows it again at the end of the
rotation. The popover controller attempts to position the popover
appropriately for you but you can also implement the
popoverController:willRepositionPopoverToRect:inView: method in the
popover delegate to specify a new position.

iPad - Different designs for landscape and portrait mode

I'm making an application for iPad in Xcode in template Master-detail application. I need to do a design for portrait mode and another for landscape mode. My first idea was make two UIViews and make a rule: if portrait, show View1, if landscape, show View2. But I have text fields in it and when the user will be typing something inside and then rotate the device, text will be deleted, because it will be another UIView... Can anybody help me, how to do it, please?
You can have one view and use springs and struts or use autolayout.
You can also add views and hide/show them based on the orientation change.
You can change the size and position of the view on orientation change.

Resources