How to display ActionSheet from master view in split view - ios

I’m using Xcode 6 on an iPad app targeted to iOS7. It’s a master-detail app with a button on each group header view in the master list. I would like the button to display an ActionSheet. I’m having trouble with the ActionSheet.
In order to get the ActionSheet to appear at all I have to pass it the SplitViewController’s view to display itself on:
UIActionSheet* menu = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:#“Button 1”, #“Button 2“, nil];
UIView* view = [[[self appDelegate] splitViewController] view];
[menu showFromRect:[sender convertRect:[sender bounds] toView:nil] inView:view animated:YES];
Passing any other view (such as the TableView, a group header, or a button) generates an exception telling me that I’m trying to display the ActionSheet from a disconnected view. But displaying the ActionSheet this way allows the master view to maintain precedence in the responder chain (mostly):
If the ActionView displays itself on the left side of the screen it displays under the master view. Only the portion to the right of the master view’s edge is visible.
When the ActionSheet is displayed, if I tap one of its buttons the master view slides offscreen and the ActionSheet remains, as if I had not tapped it. Once the master view is gone, tapping an ActionSheet button calls that button’s method.
When the ActionSheet is displayed, if I tap a cell in the master view nothing happens.
When the ActionSheet is displayed, if I tap the detail view, the master view slides offscreen, leaving the ActionSheet displayed.
I’ve read several SO posts on disconnected views and ActionSheets. The table view’s window property is defined as the app’s window, so I think it’s in the view heirarchy. I haven’t found a property in the table view or its controller hierarchy that can cause the table view to become “connected”.
It just seems that if I could find the proper view to pass to the ActionSheet it would correct ActionSheet's behavior.
Is there a solution?

Related

UIActionsheet displaying in iPhone but not in iPad

I have one actionSheet and after clicking on button of this another actionSheet is displayed. This is working fine in iPhone but in iPad second actionSheet does not appear after clicking on button of 1st actionSheet.
First of all, UIActionSheet existed before UIPopoverController and UIPopoverController isn't available on iPhone, so it's useful for backwards compatibility and universal apps.
Also, a UIActionSheet isn't necessarily presented in a popover, specifically, if you show it from a UIBarButtonItem or UIToolbar that is already inside a popover. It is then presented in a similar fashion as on the iPhone (sliding in from the bottom of the view controller). According to the HIG, you must not present multiple popovers at the same time (I once had an app rejected for that), so in cases where a view controller may be inside a popover (like in a standard split view app), you may want to use action sheets, if possible. Of course there are a lot of cases where you can't replace a popover with an action sheet, because an action sheet only shows a list of buttons and a title, whereas a popover can display any view controller.
I think that the animated parameter only has an effect when an action sheet is presented in the "classic" (as on iPhone) way.
.I think the issue is you are trying to present second action sheet before first one is dismissed.
In method
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
Check if the action sheet dismissed is first one and then present second one via
- (void)showFromRect:(CGRect)rect inView:(UIView *)view animated:(BOOL)animated
You can use tag property to differentiate between the two action sheets.

Prevent popovers from displaying over presented views

I am attempting to display a passcode screen that appears after X amount of inactivity. I use presentViewController:animated:completion: on the root view controller, and it works as expected, except when a popover is already being displayed. The popover, displayed from a bar button item, appears over the presented passcode screen.
Is there a way to dismiss or hide all visible popovers when presenting a view controller?
Create and add a 2nd window over the first. Present the passcode screen in the 2nd window. This will allow it to appear over any and all views from the first window. When you dismiss the passcode screen, be sure to remove the new window and make the 1st one key again.
Do you have a reference to the popover? Then you can just call
[popover dismissPopoverAnimated:NO];
when you go to shop the passcode overlay.
EDIT
Looping through subviews and seeing if you can dimiss a popover. I'd really recommend trying to find some other way of doing things as this is just icky. But it should work (untested).
for (UIView* view in self.view.subviews) {
if([view respondsToSelector:#selector(dismissPopoverAnimated:)]){
[(UIPopoverController*)view dismissPopoverAnimated:NO];
}
}
NSNotifications are a good tool for this problem. Have all your views or controllers that present popovers listen for a notification named, say, WillPresentPasscodeScreen, and implement a method that dismisses the popover when the notification comes in. Then, before you present your passcode VC, post a WillPresentPasscodeScreen notification -- no more popovers, regardless of where you are in the app.

ActionSheet within UISplitViewController acts different in Portrait Mode than Landscape Mode

I created a new application using the Split View-based Application template.
I then added an Action Button to the rootViewController navigation controller called actionButton.
When the button is pressed, I display an ActionSheet like this:
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil
delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil
otherButtonTitles:#"Admin Functions", #"Refresh Data", nil];
[actionSheet showFromBarButtonItem:actionButton animated:YES];
[actionSheet release];
After I press the button when in landscape mode it displays the action sheet in a popover which is pointing to the button (as I expected it to):
However, in Portrait mode it looks completely different and the menu comes up from the bottom of the rootViewController popover just like it does on the iPhone:
My question is, how do I make the ActionSheet appear at the top while in portrait mode, just like it does when in landscape mode?
Since this is a "utility menu", it isn't really tied directly to the data being displayed so it shouldn't be part of the popover.
This behaviour is by design, if it were a popover in portrait mode you would then have 2 levels of popover.
This is technically possible by implementing your own version of UIPopover or using one someone has already written (WEPopover).
However, this is a poor design choice. You say that the functions aren't related to the data, however one is 'refresh data'. I would replace the action button with a refresh icon such as the one Apple uses in 'Find my Friends':
The other, 'Admin Functions', if not directly related to the data in the list, perhaps needs a new home, maybe with the main view of your app? It's hard to say where is best to put it without knowing more about the structure.
Another possibility is that you could move the action button from right edge of the root view controller's bar to the left edge of the detail view controller's bar.
For example, if the action button were located just to the right of the vertical bar in your first screen shot (meaning it's at the left edge of the detail view controller's bar), then when you rotate to portrait mode it would appear just to the right of the Events button in your second screen shot. You could still call UIActionSheet's showFromBarButtonItem:animated method, which would display your action sheet in popup mode.
There's still the question of whether you really want two popovers on the screen at the same time. But if you do, this is how to do it.

ios - how to move to a particular UI viewcontroller

in my app i have a tabbar. The UI tabbar controller has five indexes. Each indexes consists of 5 UI view controllers.
In some conditions if i click a button i want to open a particular view controller placed in the 0th index of the tab bar.
How to open that view controller alone directly, pls help me friends....
You can send the index of the tab you want to select with your push notification (see here http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ApplePushService/ApplePushService.html#//apple_ref/doc/uid/TP40008194-CH100-SW1 for more info)
first add a view as subview to the tabbar and then hide and show the view whereever you needs
UIView *firstview=[[UIView alloc] init];
[tabbarObject.view addsubview:firstview];
tabbar object i added to window
[self.window addsubview:tabbarObject];

TableViewCell disappears when push UINavigationController in UITabBarController's More tableview

I add 6 navigation controllers to UITabBarController's viewControllers. As normal, a More tab is created to list the last two. The problem is: after I select a table cell in the More table view, that cell's content fade out and disappear before the view controller push in. And then, after I back to the More table view by click the Back button, that cell's content show again. I guess the reason is More table view in its own navigation controller, and it push another navigation controller (created by me). I don't want to remove my navigation controller because I want to allow user rearrange tabs using the UITabBarController's Edit function. Can anyone suggest what I should do?
Create instances of your 6 navigation controllers in AppDelegate and retain them. And release in dealloc method
Just had the same problem. In my case I accidentally assigned the tabBarItem to the VC inside the navigation controller. When I instead initialized the tabBarItem on the navigation controller, the flickering / disappearing stopped.
MyViewController* viewController = [[MyViewController alloc] init];
UINavigationController* navigation = [[UINavigationController alloc] initWithRootViewController:viewController];
[viewController release];
// this has to be navigation.tabBarItem (not viewController.tabBarItem)
[navigation.tabBarItem initWithTitle:#"Title" image:[UIImage imageNamed:#"fancy.png"]
tag:42];
Initializing the tabBarItem on the viewController still showed the icon which made it harder to discover. I'm also not very sure (actually I think it's bad) about the way I initialize the tabBarItem (without alloc). But I had troubles with disappearing icons etc and hey, it works ;-)

Resources