UISplitViewControllerDelegate problem - ios

I have been creating a new iPad application based on the SplitViewController. I have modeled the app after the MultipleDetailViews sample app from Apple. The problem I have is that the splitViewController:willHideViewController:withBarButtonItem:forPopoverController: method is not called at startup when the device starts in Portrait mode. This method is called during the startup sequence in the MultipleDetailViews sample app. It is during this call that the button to be presented in the toolbar in the main view should be added.
My application is working fine otherwise, i.e. I get the UISplitViewControllerDelegate calls in every other case. I can't figure out though why I am not getting the willHideViewController message during startup.
Any thoughts? Is there some other way I can get at the button to be displayed in the toolbar when starting in portrait mode if not through this willHideViewController message?
Thanks in advance,
-Eric

Related

UISplitViewController changes display mode when app suspends

I noticed some bizarre behavior in my iPad app: when the app transitions to the background, my active view controller receives viewWillAppear/viewDidAppear messages.
From my investigation, it seems this is happening because when my app moves to the background, my UISplitViewController for some reason first transitions its display mode to .PrimaryHidden and then immediately back to what it was before (.AllVisible).
Is this expected behavior? If so, why does UISplitViewController need to change its display mode (twice) when the app suspends, and is there a way to prevent it from doing so?
Edit: I just verified this behavior with a simple test app, but I'm no closer to understanding why it happens or how to prevent it.

Loading the last View Controller Active after app goes into background, swift

I have "Tinder" like swipping view that is located in a CardViewController. The card View Controller is accessed by moving through two other view controllers. i.e. Load App -> FirstViewController -> SecondViewController - > CardViewController.
When I am in the Card ViewController and I go into background mode, the app launches on the FirstViewController and on going to the cards, they are loaded from the first card in a stack of about 10?
Is there anyway to load the app from the last Card I had swipped and in the CardViewController without having to navigate from the FirstView Controller again?
I would really appreciate the help as it's horribly affecting some of my users.
An example of a Tinder like card view is shown!
The problem, from the sound of it, is not what happens when the app goes into the background — that would leave it in exactly the same state when it reactivates. The problem is what happens when the app goes into the background and quits. Your app is then relaunched from scratch, which is why you find yourself in the first view controller. What's upsetting you is the difference between the app's behavior in these two situations.
Apple provides a solution to this situation: UIViewController, along with the App Delegate, has methods permitting you to save and restore state. When the app goes into the background, the current configuration (what view controller's view is showing) is saved. That way, even when the app quits, when it relaunches it can get back to that configuration before it appears to the user. Thus, coming back from background-and-quit looks just like coming back from mere backgrounding.
For full details, see Apple's documentation. This is a good place to start:
https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/PreservingandRestoringState.html

Unity iOs - screen gets black when changing rotation while Unity is paused

I have a unity app, that uses Vuforia AR library. I extended this app with some iOs code. I wanted to be able to display my custom UIViewControllers sometimes instead of the main view controller that Unity uses. But I want to be able to switch back. I.e: I have a button that opens UIViewController with "About app" information and this controller then has "Exit" button to return to Unity controller.
This is my code for adding the new controller instead of the Unity View Controller:
self.unityRootController = self.keyWindow.rootViewController; // keep reference to the Unity Controller
self.keyWindow.rootViewController = controller; // display my own controller
// this pauses the unity and qcar -> so that QCAR doesn't try to recognize objects, when Unity Controller is not up
QCARUnityPlayer::getInstance().QCARPause(true);
UnityPause(true);
Then when returning from my own controller to Unity controller:
self.keyWindow.rootViewController = self.unityRootController; // return to Unity Controller
// start tracking with QCAR and unpause Unity View
QCARUnityPlayer::getInstance().QCARPause(false);
UnityPause(NO);
This works fine except one case, that's caused me to pull my hair ever since encountering it. My app supports changing orientation of screen in both Unity and ObjectiveC code. And this is the trouble: If I open my View Controller while the device is for example in Portrait Orientation, then turn the device to Landscape orientation, my controller gets correctly rotated. But if I at this moment want to close my custom view controller and return to unity controller, the screen gets black suddenly. After rotating the device to portrait orientation, the unity controller suddenly starts working as expected.
I'd like the unity controller to start directly after closing my custom view controller even if the screen orientation is changed. I suppose I have to add some code after I start again the Unity Player here:
QCARUnityPlayer::getInstance().QCARPause(false);
UnityPause(NO);
// TODO: supposedly some code should go here, that fixes black screen
But I tried to find something in the AppController.mm, that is builded by Unity and I could not find anything, that would help me. I found few lines of unity code, that had the word "orientation" in it, but I tried to use that code and didn't help. Does anybody know, what should I do, please? Thanks a bunch :)
Not sure if you have fixed this, Its been a while... But the reason that your UnityViewController is not functioning properly is because a view controller that is not visible will not receive rotation events. Because you are setting your view controller as the root view controller, the UnityDefaultViewController defined in "iPhone_View.mm" is not receiving rotation events.
I have been studying Unity's rotation for a while now as I have my own issue with a similar setup.
There are a few things that you might be able to try:
In iPhone_View.mm there is a function that is defined called: UpdateOrientationFromController(UIViewController* controller) that might be able to solve your problem. You would want to call this function on the view controller that you designed yourself where you placed your //TODO comment. That function calls a few key functions and methods that handle Unity's interface orientations:
ConvertToUnityScreenOrientation: for some reason Unity Uses their own defined screen orientations, this internally converts the orientation to what Unity uses.
QCARUnityPlayer::getInstance().QCARSetOrientation(): QCAR Also needs its orientation to be set
UnitySetScreenOrientation(_curOrientation): The unity library has an internal way of checking the screen orientation at every rendered frame. I think this function sets an internal flag for the Unity View to check in CheckOrientationRequest() defined in iPhone_View.h as well.
AppController_RenderPluginMethodWithArg is called, I am not sure what this does, but I think it does something important
OrientTo(_curOrientation): this kicks off the actual orientation change and handles the right calls. This includes the call to AppController's onForcedOrientation: method that does the final orientation.
You may be able to call AppController's onForcedOrientation: method directly with a UnityScreenOrientation after you convert a UIDeviceOrientation to a UnityScreen Orientation with ConvertToUnityScreenOrientation() defined in iPhone_OrientationSupport.h. You may not want to call this method directly though, because there are quite a few things that are involved with Unity's orientation methods. You would do this when your app returns from presenting your view controller.
The last thing, and the "hackiest thing" that you can do, that will get the job done, but not in the most efficient way, is to add UnityDefaultViewController to your ViewController as a child ViewController with the addChildViewController: UIViewController Docs, or maybe as just a property, and then override the willRotateToInterfaceOrientation:duration: and didRotateFromInterfaceOrientation:in your ViewController and after calling super, pass the message to the UnityDefaultViewController. This will cause the UnityDefaultViewController to update the UnityView every time the orientation changes, even though the view isn't actually visible. You may or may not need to unpause Unity in order for this to function.
Of the three methods, the last one should definitely work, because I have implemented it myself. However, the first one should work as well, because Unity uses it several times to check the devices current orientation from the splash screen.
Hope this helps!

IOS: turn off camera

In my app I use iphone camera, but the process is very low when I open it; then I want to start the process when I shows a splashscreen.
The problem is that when splashscreen ends I don't want to show camera.
Then while I show splashscreen I want to start process of camera and quit it before splashscreen disappear. Is it possible?
First up, Apple specifically advise against using splash screens in their Human Interface Guidelines document. I don't know if your app would get rejected for it, but best not to try.
Second, it sounds like you need to optimise the startup of your application and probably the first view controller. To do this, you need to put off loading/initialising everything you can until it's actually needed (known as "lazy initialisation). All code in applicationDidFinishLaunching: in your app delegate and your view controller's init method, loadView, viewDidLoad, viewWillAppear, viewDidAppear should be reviewed for stuff that could be done later.

How to make UIPopoverController visible at startup in portrait orientation?

I'm making an iPad application using a UISplitViewController. I want the masterView visible in a UIPopoverController when the app starts (and only when it starts) in portrait mode. If I use the presentPopoverFromBarButtonItem:permittedArrowDirections:animated: method in the splitViewController:willHideViewController:withBarButtonItem:forPopoverController:
delegate function, I get the following error, when I start the app in portait mode:
Popovers cannot be presented from a view which does not have a window.
Can anybody help me?
The particular error says that you must add the view to a window before showing the popover, not the other way round. Try sending presentPopover… from the application delegate's -application:didFinishLaunchingWithOptions: after adding the view to your app's window.

Resources