How to stop autorotion of selected subview in UIViewController - ios

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.

Related

Disabling autorotation for specific UIView iOS 12

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

Prevent view from moving on orientation change

When you rotate apple's camera app, notice how none of the interface elements change position. Only the buttons on the top toolbar animate and rotate in place:
I would like to do this for my app. This view is currently defined in a storyboard, so I would prefer to use Interface Builder. How can I configure the view such that it registers an orientation change (calls the UIViewController's didRotateToInterfaceOrientation etc) while keeping the views in the same place?
I already know how to rotate the buttons, etc, I'm only asking about how to configure the view so it doesn't move the toolbar on an orientation change (my toolbar is currently defined as a vanilla view, not a UIToolbar)

iOS View does not change orientation on orientation change

I have a root view which contains a scroll view which contains a (content) view. The content view contains many child controls. Using the simulator, when I change orientation, none of the views, including the scroll view changes orientation. For example the image below starts out in portrait mode and all controls are played out correctly, but moving to landscape mode just shows portrait mode horizontally:
All of this was laid out using Interface Builder, so I don't have much code in the control view file besides some IB outlets to the controls.
Is there some sort of constraint that is preventing the reorientation of all the controls and views? Or do I always have to lay these out manually on orientation change?
First you need to check you have allowed the app to rotate by checking the orientations you want are ticked:
Click on the top-left corner (Show the Project Navigator)
Select the name of your project
See what is under General->Deployment Info->Device Orientation.
Adjust the tickboxes accordingly.
Update:
Also slide up on the simulator and check that rotation isn't locked for the device.
Try putting this in your AppDelegate/view controller:
- (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
(I don't think it's a constraint/layout issue as the status bar isn't even rotating)

UIImageview/UIVIew in UIWindow cannot rotate to landscape

In my AppDelegate, I have an uiwindow like this. Inside that, there are uiimageview as background.
Problems is that those Imageview aren't rotated when iPad is rotated and status bar is also in landscape position already. May I know how to do?
Edited: If I listen to orientation change, my image view is rotated but I want to set that image view to the origin (0,0) of device. However, it look like uiwindow is offset in horizontal position. Now, I am setting origin of image view as origin of uiwindow. Then, my image view is also offset. How shall I do?
That's the correct behavior. UIWindow objects doesn't support rotations.
To do that, you should rotate them by yourself listening to UIDeviceOrientationDidChangeNotification notification.
Managing rotation in a window is a little bit tricky, also because during rotation animation you should be able to detect the rotation direction to make a good user experience.
In my opinion is better if you embed you image views in a view of a view controllers.

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.

Resources