ipad, How to manage Popover presented from barbuttonitem? - ipad

I know that UIPopovercontroller does not retain itself while presenting.So we have to keep a reference to it to keep it alive
And When pressing the barbuttonitem which is presenting a popover, it does not automatically dismiss the popover, it actually will present another popover over it again and again when you press the button and do nothing special to check if there was already some popover.
I know we can have many properties to maintain every barbuttonitem's popover, but I think this is ugly...
Is there any better practice?

I'm using popovers with ARC and have not had to do anything special to maintain the reference count. As long as the popover is onscreen, there are strong references to it to keep it alive. Do you have a fail case you could post?
I consider the second issue you mention the more interesting one: pressing the barButtonItem repeatedly creates multiple instances of the popover. It's difficult to see them, because they stack up atop each other. But the shadows around the popup get darker with each added instance. The real tipoff to the problem is that every instance has to be dismissed separately.
One solution is to disable/enable the UIBarButtonItem on the way into and out of the popup. This worked well for me, but is slightly tedious. (I had to put code in two places - one in my own dismisser, and another in the popoverController's delegate's – popoverControllerDidDismissPopover: method, for the case where the user clicked outside the popover to dismiss it.)
I think that the (excellent) Stanford CS193P course addresses this issue by hiding the button while the popup is showing.
The iOS behavior actually seems like a bug. A click in the barButtonItem is outside the popover, and unless the barButtonItem's view is included in the popover's passthrough array, it is supposed to (according to the doc) dismiss the popover. But it doesn't and Apple didn't ask me.
I just checked and found that the passthrough array is initially nil, so removing the barButtonItem's view from that array is not an option. Drat.

Related

How Can I Float A View Over A Displayed Popover, in IOS?

I can produce a small project to illustrate this, but I think it's faster, and easier, if I simply describe it.
I have this widget I wrote. It displays a "floating" UITableView over everything else. It does this by adding itself to the main window root view controller.
However, if I am trying to display it in a popover, the table comes up under the popover. I should add that it will overlap the popover boundaries. It should not be contained in the popover.
What's the most correct way to get it to appear over the popover?
OK. I solved this, by simply attaching the table to the main view.window instance.
This seems to work in all my tests (including things like split view, and popover view).
I have not read anything that indicates that I should not do this. Apple has already passed a couple of TestFlight releases that have it, so it didn't ring any alarms for them.

Passing through Segues, Determining what view the user is on and NavigationController buttons not appearing

Sorry for the long and possibly confusing question. In this I have 2 main problems with my code, those being: 1- When I embed my viewControllers in a UINavigationController and add a bar button item, nothing appears, yet it appears when I add it to the pageViewController. Secondly, I am wondering if there is a way to do this differently and use one button on the pageView (which appears on all viewcontrollers in it) and just determine what the user was looking at when they pressed the button and are taken to another viewcontroller.
I am trying to build a page-based application, and I have set up the application with 7 view controllers (One for each day of the week). I then have an AddViewController, where users can add data to a certain day. I was wondering if there is a way to only use 1 addView linked to the NavBar on the PageViewController, as when I embed all other viewControllers and add a bar button, it does not show up.
With the pageViewController being embedded, this is what it looks like with a bar button on it.
This then leads to:
Which works well, however I am wanting to pass data to various arrays (one for each viewController), and I want to know which ViewController the user wishes to add to (based off what day they were on). Is there a way to determine this and then unwind to the viewController and append the right data to the right array or should I have one addView per dayViewController? If that is the case, I am coming across the issue whereby the bar button items do not appear on the viewControllers when they are embedded in a navigationController. It looks like this:
StoryBoard: (Example: MondayViewController)
The outcome is a missing barButton: (Keep in mind I changed the tint Colour to white so it would be visible)
I was wondering if anyone has the answer to either of my problems, and once again, thanks for taking the time to look at this array of questions in one problem.
Any suggestions are welcome !
Rowan,
You can do this:
Create an UINavigationViewController and then embed an UIPageViewController in it.
In the data source for the UIPageViewController implement these two methods:
- pageViewController:viewControllerBeforeViewController:
- pageViewController:viewControllerAfterViewController:
Here you will return the correct instance of your DayViewController for each position (or nil if you are on the first/last page). Your data model would also be set here.
Add your "Add" bar button to the navigation bar of the UIPageViewController and let it push your AddViewController. When pushing the AddViewController provide to it the info on which day is currently visible. You will probably need to keep track of this your self. Use the - pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted: method of the UIPageViewController delegate.

LNPopupController makes UIKeyboard unclickable

I'm using LNPopupController (https://github.com/LeoNatan/LNPopupController) in my project. I also have an UISearchController for my Table View.
But when I imported the LNPopupController in the project, the UIKeyboard on the Search Controller is not clickable. As soon as I click on a letter on the keyboard, the search controller just gets dismissed. Please let me know the reason for this bug.
The issue has been fixed. The issue was, a view was added to an internal controller of Apple, which caused them to return an incorrect tappable view on the keyboard. I changed the logic to more correctly only load the helper view if needed and not necessarily on first layout.
I looked at the sample code you provided.
Here's what's going on.
LNPopupController has categories that swizzle (override) methods in UITabViewController and UIViewController, which affect your view controllers when they load.
The effect you're seeing when the search is active is the same behavior if you clicked the dimmed background (of the tableView above the keyboard) -- the search is cancelled.
In other words, the touch events aren't being handled by the keyboard overlay, but by your view controller, as if the keyboard overlay wasn't even present.
If you want to use the LNPopupController project, you should open an issue on GitHub so the maintainer can fix it.

Segues from a subView

Just trying to teach myself storyboarding and have run into a question I was hoping people may have an answer to.
I wanted to create a reusable upper toolbar so that in case I ever had to change it, it would update all of my scenes. I created a sized ViewController in my storyboard. I then load it into a subview of each of my scenes using the menu's identifier. THat seems to work pretty well (although, feel free to tell me that's the wrong way to do it).
Here's where the problem starts. On that top toolbar, I have a UIButton which I connect to another sized ViewController in my storyboard as a popover. Basically, a drop down menu. If I just load up the top toolbar, works fine. If I connect just a regular button to that popover scene using a segue, that works too. If, however, I try to click the button and follow the segue while the toolbar is within a subView I crash with EXC_BAD_ACCESS. I presume I'm not allowed to spawn a popOver from a subView or follow a segue within a subview? The latter seems wrong since you effectively do that with any UI object.
How else should I handle this?
Thanks!
I'd recommend using a UINavigationController and setting the toolbar to include your UIButton (as a UIBarButtonItem). If you have any trouble "keeping track" of the toolbar or button you can subclass UINavigationController, add the UIButton (or entire toolbar) as a property of the subclass, and access it from any subsequent view through the self.navigationController property (might violate strict OO, but you could use a protocol).
As for the popover, I think you're OK on iPad but not on iPhone. There are custom projects on github to implement UIPopoverController, and indeed the Facebook app makes use of a custom popover for notifications in their app. iPhone raises an exception if you try to show a UIPopoverController.

Specific iPad modal view

Okay, I am still learning how to program and things are moving along quite well, but I have a question for the group about something that has been plaguing me:
How do I create a pop view where the background can still be seen? I mean, say my iPad view has 5 buttons on it, and I want a small square to pop up over where that button was, asking the user a question - how would i do that? Can I make a modal view with an invisible background? (I don't want a UIAlert BTW - I know that would solve my problem, but I am trying to learn how to do this with my own view)
Can anyone point me in the right direction?
You say "pop view" which makes me think you're describing a popover. Have you read the iPad Programming Guide, specifically, the section "Creating and Presenting a Popover"? It really is required reading in this case.
Are you showing the popover from a bar button? If so, you'll want to use presentPopoverFromBarButtonItem:permittedArrowDirections:animated:. If not, you'll need to identify a CGRect that represents the button (you can use its bounds), and then use presentPopoverFromRect:inView:permittedArrowDirections:animated:.
You do not want to obscure the button with the popover. When you show the popover using the above methods, the framework will take care of positioning the popover on-screen. Use the UIPopoverArrowDirectionAny for directions whenever possible.
If you actually want to show a modal view, you can create whatever view you want and then display it in such a way that the background is not fully obscured. Just set the modalPresentationStyle of the view controller to something like UIModalPresentationPageSheet.
You should create a custom UIView with the dimensions and content that you want to display. Then, you can place the custom UIView on screen by calling something like:
//where 'self' is the view controller currently visible and 'customView' is
//the view which has the question for the user. Don't forget to set the
//frame property on customView so that it knows the correct place to display.
[self.view addSubview:customView];
Hope this helps. Andrew

Resources