Is it possible to delay or trigger auto rotation in any way in iOS 7, without switching to a new view controller?
Consider the example of Siri on iPad. When Siri is activated, the application running behind it is deferred and blurred with Siri's transparent interface laid over top. If you rotate the device while using Siri, nothing happens, but upon dismissing Siri, the auto rotation event finally fires.
I'm accomplishing a similar blur/defer effect in my application by taking a snapshot of the window, blurring/scaling it, placing it over top of the view being displayed, and placing additional transparent content over top. Because this is a snapshot and cannot resize on-the-fly, I prevent auto rotation from occurring (like Siri) with -shouldAutorotate returning NO high up in the view hierarchy. Once this state is dismissed, I once again allow auto rotation, but no rotation is triggered. This is because the rotation that occurred while the app was in this blur/defer mode was ignored.
Is it possible to trigger auto rotation to occur to properly rotate to the device's actual orientation after I return from this mode?
Here are my three suggestions:
Use a live blur view and allow animation. There are many open-source implementations, most of which use a stretched toolbar or its blurring CALayer. This will allow you to support rotation as well as have a live view under the blurred background (like Siri). Edit: After digging around, I found out that certain open-source implementations, which were taking the CALayer of a toolbar were rejected by Apple. By taking a toolbar and stretching it seems safe.
After taking a snapshot of the key window, display that snapshot as the root view of another window which is displayed above the key window. If I recall correctly, a view alone, without a view controller attached, will not rotate when added to the window's view hierarchy. (If it does, it is very easy to counter using a counter-transform.) In essence, you will achieve a non-rotating view. The window below will rotate normally, however. When dismissing the snapshot holding window, fade it out so that the view hierarchy below is smoothly presented to the user. Drawbacks of this approach is no live preview of the blurred background, the rotation animation will not be seen by the user.
Rotation in iOS is basically the view controller setting a transform to the view, if all conditions are met and it is determined that interface rotation is supported. In the view controller responsible for the blurred view, counter rotation with inverted transforms. This should make views appear as if not rotating. Once it comes time to hide the blurred view, use an animation block to reset the transform, which will create the same animation as rotation. If you combine this approach with a live blur view, this will recreate the native Siri experience 1:1. Your only problem will be the status bar will rotate regardless of the view's transform, because it gets its transform from a different system. There are gray-area remedies for this.
These recommendations are sorted by ease of implementation. Each can be implemented by itself or a combination of 1+2, 1+3 or 1+2+3.
Siri follows different rules. It is a whole different application (and a privileged system application at that) that is displaying on top of the previously frontmost application.
As for your situation, the thing to do is probably to present a full-screen modal view controller on top of the current view controller that only allows the current orientation. Then, when it's dismissed, the previous VC will allow rotation again and everything should pick up where it left off.
Related
I'm currently working on a small iOS camera app and have a storyboard-related question.
(Sorry for my bad drawing) Here is what I got on my storyboard, I have two view controllers, mainVC and cameraVC, and I added table view cells to mainVC to add a segue to cameraVC. This app is a vertical orientation app, and I want to make this app horizontally only when the user gets to the cameraVC. I'm not planning to make this app rotatable, hence this app only supports the vertical orientation if the user is in MainVC and only supports the horizontal orientation if the user is in CameraVC.
I'd add several more vertical view controllers later on, so I make the app vertical on the storyboard. However, I was not sure how should I design the camera VC on my storyboard.
While the app is running and the user gets to the camera VC, I want the app orientation horizontal (and don't rotate to vertical) and display buttons on the right side, like the image below.
So my question is while all the view controllers set to vertical, should I place buttons on the cameraVC at the bottom like the first image, or is better to place buttons on the right side with assuming the VC rotates when the user gets the camera VC, like the image below?
Sorry for the confusing question.
When designing a view controller in storyboard there is no property for orientation. There are however simulated values that are applied to whole storyboard to be either landscape or portrait.
If you want to simulate these values differently I suggest that you move your camera view controller to another storyboard. I would actually do that regardless of the issue you are facing.
If this doesn't suit you for any reason then you can still simulate your view differently. You can simply select your camera view controller in storyboard and use a Freeform simulated size like on the screenshot below.
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
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.
I'm making an iOS 7+ only app, and I need to have a view that can be pulled from the bottom of the screen, very similar to the system Control Center. Blur would be nice, but that doesn't look like an easy task, sadly.
I want to take advantage of OS 7's UIDynamicAnimator, and the Gravity/Collisions features. But I can't figure out how!
The view will cover about 3/4s of the screen, and be semi-transparent (0.6 alpha). It will contain some controls that I'd like to lay out in IB.
The view should be activated when the user 'pulls' from the bottom 0.25" on the screen. I want it to behave like the control center or lock screen - not a single swipe gesture, but a view that tracks the users' pan, and snaps up or down accordingly.
I've got a map view, as a subview within a semi complex view hierarchy. Everything works fine, except that the accuracy circle, pulsing wave causes the underlying map view to bleed onto both the navigation bar, and the tab bar whenever the blue, user location pin is near either one. I've got all the parent views' clip subviews set, so wondering what else might be the problem. The view hierarchy is window/scrollview/content/mapview. Thanks.
Update:
I've since tried rearranging the view hierarchy to test various layouts, and confirmed that all the parent views have clipsToBounds = YES and still getting the bleed whenever the "pulse" occurs. Odd things is that the only two views affected by this are the nav bar, and the tab bar. The undesired behavior is that when the pulse ring expands, near either the tab bar or nav bar, the underlying map view begins to draw under the area within those views where the pulse intersects them; as if they are being wiped away and exposing the map view underneath it
Thought I'd share some recent info on this, in case somebody else happens to hit this same issue.
In my case, I had to set the parent view of the mkmapview (content view) clipsToBounds property NO, and everything worked. It seems counter intuitive, I know, but it's the solution an iOS support engineer proposed. Technically, it's not a supported configuration, but the tech engineer also indicated that it shouldn't bleed like that anyway. I filed a bug for it, as he suggested. The only downside to this is that I had to let go of rounding corners and drop shadow; can't get that without clipsToBounds=YES.