Is there any way to place a UIView above a UIPopoverController? - ios

I have code in my app that adds a UIView to the root view controller's view. This view is semi-transparent, and functions as a modal overlay that covers the entire application (the view contains a button that when clicked removes the view from its superview, which is how the user gets back to the main application).
This has worked fine up to now, but now we're using UIPopoverControllers and attempting to use this same modal overlay to block the main application. The problem is that this UIView is shown behind the popover, instead of on top of it.
Is there any way to add a subview to a root view controller's view in such a way that it appears on top of any visible UIPopoverControllers, but without dismissing them?

The reference on UIPopoverController states:
"The popover content is layered on top of your existing content in a special type of window."
NSLogging of the subviews-array shows, that the view is not added to the view hierarchy of the viewController that displays it. From my point of view what you are trying to do isn't possible.
Here is an idea though:
You could add your blocking UIView to the contentViewController of the UIPopOverController and use it to set a property on the contentViewController.
Then you set your main viewController, which actually displays the UIPopoverController, as delegate of the popover and do something like this:
- (void) popoverControllerShouldDismissPopover:(UIPopoverController*)popoverController
{
if(popoverController.contentViewController.yourProperty)
{
return YES;
}
return NO;
}
I don't know how much this helps in your current situation, but maybe it gets you started.

Related

How do I make a view that stays onscreen when the main view segues?

How do I make a view that does not appear to be reloaded (stays onscreen) every time a view segues? Like the audio controls in Apple's iOS podcast app. See pictures to see audio controls I am referencing.
How do I do it in storyboard?
What you are referring to is usually called "mini player", you'll find it in many other apps too.
The technique you should use is called "UIViewController Containment", in storyboards it is accessible as "Container View" and "Embed Segues".
A typical storyboard might look like:
The root view controller has two Container View added to it's view.
The container views have segues to view controllers. In the view
controller that relates to the lower one, setup the mini player.
The view controller of the upper container embed in a navigation
controller and a tab view controller.
This will create the view controller hierarchy.
To implement the player itself create a player class that you instantiate in the app delegate and pass it to a property on the root vc. from there pass it to the mini player view controller and to the upper view controller, that will contain the list of songs/podcast/... to select from. At selection pass hat song to the player class.
I posted an example app at GitHub: https://github.com/vikingosegundo/HearThisMiniplayer
I think you can do it adding it on top of application window(which is UIWindow, subclass of UIView)
UIView *myView = /* <- Your custom view */;
UIWindow *currentWindow = [UIApplication sharedApplication].keyWindow;
[currentWindow addSubview:myView];
Took the code from https://stackoverflow.com/a/21850538/1947419
Or you can add to UITabBarController.view directly since it's UIView spanning entire screen.
You need to make custom view for it though.

Set View Controller Subview Loaded from Storyboard

I have a custom view controller I load from a Storyboard. When I try to set one of its subviews nothing happens (remains generic white view). What I don't understand is if I try to set VC.view it works fine. Why is this? Everything seems to be initialized after I load from the Storyboard. Where would I set the VS's subview?
Yes, this slightly confusing behaviour is how it is 'supposed' to work. When a view controller is loaded, its view is not - at least not until it is actually needed. See this doc for further info. Only when the view controller is presented, will it then load the view. As you have found, this is tiresome, because you often want to set some of the the subviews' properties before it is presented (say in a prepareForSegue or prior to pushViewController: or presentViewController:).
There is a work around - based on what you have observed. If you directly access the view property, the view controller will immediately load the view and all its subviews. So, if you want to set subview properties, just "touch" the view itself:
NSLog(#"View tag is %i", viewController.view.tag);
and you should then be able to access the subviews.
Alternatively, you could pass the relevant data in (non-UI) properties of your view controller, and then set up the subviews using that data during viewDidLoad or viewWillAppear.

UIScrollView and Storyboard

I am testing out something I would like to have in my app. I have a UiViewController in a storyboard that has a UIScrollView - I now want to add other viewControllers to this scrollView and swipe between them.
I would like to add a view that I made in the storyboard into this UIScrollView. Is it possible?
I tried something along the lines of:
MYViewController *viewOne = [self.storyboard instantiateViewControllerWithIdentifier:#"myView"];
[self.scrollView addSubview:viewOne.view];
I've set the the scrollView size to be bigger than the screen and when the main view loads, I can see there is a scroll view (the scroll bars show) but my viewController is not inside it.
Anyone have any ideas?
The code you posted is still not right, on a couple of levels.
First, you should not use alloc/init for view controllers. You either need to use initWithNibName:bundle: (to create a view controller from a nib file) or instantiateViewControllerWithIdentifier: to load a view controller from a storyboard.
Second, you should not add a view controller's view as a subview of another view controller unless you use the parent/child view controller support that was added in iOS 5 and greatly improved in iOS 6. If you do what you are doing then all sorts of things won't work correctly: Auto-rotation, low memory warnings, background notifications etc. The list of things that can go wrong is unbounded.
The easiest way to do this is to add a container view as a frame to hold your child view controller, and then control-drag from your container view onto the scene that you want to set up as a child. This causes IB to set up and "Embed" segue. Embed segues do all the housekeeping you need to host one view controller's content inside another, with no code needed.
You could create a container view inside your scroll view's content view, and then it would just work fine.
I found the problem:
I was not allocating and initialising my viewController. Ooops.
This is the correct code:
BaseViewController *viewOne = [[BaseViewController alloc]init];
viewOne = [self.storyboard instantiateViewControllerWithIdentifier:#"myView"];
[self.scrollView addSubview:viewOne.view];

Top level view in a UIView hierarchy

I have a singleton instance of a custom UIView with a method -(void)display whose job is to animate the custom view in and out on whatever screen is currently being displayed. (kind of like the -show method in UIAlertView).
My question is how do I determine which view is at the top of the UIView hierarchy and currently displayed?
The "top" of the view hierarchy is a UIWindow. And there can be (and usually is) more than one UIWindow in the application. If you want to have something shown over everything else on the screen, I suggest you implement a custom UIWindow. E.g. UIAlertView is also implemented this way.

iPhone : UINavigation Controller within a view displaying another view

I think I am having a case of disappearing up my own arse.
I am creating a small view on a ipad thats for settings (so not full scree), within this view. I need a navigation controller to show another view.
At the moment I have one class / xib
The xib contains the main view (graphic / boarder). This view is linked to the files owner and appear.
On the same xib, I also have a navigation controller that contains the inner view.
OnViewDidLoad I add the navigationcontroller.view to the subview and it appears. However I cant push anything off it. I wired up the delegate and etc but I am sure I am missing something stupid
Can I do this all within one controller / xib?
The only code I have done is
[self.view addSubview:mainNavigationController.view];
Is there some code I need to do for the navigationController
Just adding the navigation controller as a subview doesn't hook up the navigation controller to the view controller hierarchy properly. That's probably why it doesn't work.
Also the properties that need to be set are readonly properties, so I don't think there's anything you can really do about it.

Resources