What is the user interface class of slide up menus? - ios

I'm wondering if there is a specific UI class that slides up to allow user to make a choice, like the "More" button on the safari or the interface confirming iDevice shut down. Both looks like UIToolBars but they seemed to be rendered so well (the button and the toolbar background) that I am starting to suspect it is a separate class designed specifically for such slide-up choices.
Or are they actually different UIViews with designed background that slides up using animateWithDuration:animations: and the background is a translucent mask? How did apple do it?

UIActionSheet. Here is the code:
UIActionSheet *actionSheet = [[UIActionSheet alloc]initWithTitle:#"Share" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"E-Mail",#"SMS", nil];
[actionSheet showInView:self.view];

i think what you are looking for is an action sheet

You mean UIActionSheet?
If so, yea its a separate class under UIView !
UIActionSheet

Related

iOS 8 iPad only bug with action sheets

On an iPhone running iOS 8, the code below causes an action sheet to pop up. However, on an iPad running iOS 8 the code below does not cause an action sheet to pop up and instead nothing happens.
NSUserDefaults *defauj = [NSUserDefaults standardUserDefaults];
NSArray *cod = [defauj objectForKey:#"customlistofstuff"];
UIActionSheet* actionSheet = [[UIActionSheet alloc] init];
actionSheet.delegate = self;
for(int i=0;i<[cod count];i++)
{
[actionSheet addButtonWithTitle:[cod objectAtIndex:i]];
}
actionSheet.cancelButtonIndex = [actionSheet addButtonWithTitle:#"None"];
[actionSheet showInView:[UIApplication sharedApplication].keyWindow];
Try this:
[actionSheet showInView:[UIApplication sharedApplication].keyWindow.rootViewController.view];
It looks like you can't present action sheets on UIWindows directly anymore, you have to present them on an actual view that is managed by a view controller, so the root view controller's view is perfect for this.
I think this has less to do with the fact that UIActionSheet is deprecated (and you can't just magically switch to UIAlertController just yet if you need to support iOS 7), and more to do with the way their presentation is handled in the underlying implementation — I'm guessing it now relies on the view the sheet is presented in having a view controller, which is not true for windows.
EDIT: If you have a view controller presented modally over the top of the root view controller, this obviously won't work as the root view controller's view is no longer visible. You'll need to present the sheet in a view that is currently visible, e.g. the view of the current view controller (self.view).
I bet this has something to do with UIActionSheet being deprecated in iOS 8. You're supposed to use UIAlertController instead with a preferredStyle of UIAlertControllerStyleActionSheet.
Try using that instead and see if it works. You'll have to use blocks instead of methods, but that shouldn't be too hard to do.
According to Apple's Human Interface Guidelines about Temporary Views, A cancel button should only be used when the view presenting the action sheet is a popover, because, according to the HIG, users can tap outside the popover to dismiss the action sheet.
Therefore, cancel buttons do not work on iPads.
UIActionSheet has also been deprecated, and you should use UIAlertController instead.

How to disable navigation bar back button when some activity is loading in iOS?

I have two ViewControllers.
In second view controller, When I click on search button action (activity started, like web service is executing).After getting data from web service, It will show UIAlertview.
My problem is, When I pressed search button(activity start), now I clicked on back button on Navigation Bar. Now, I am on previous view(First view controller). I have now response of search button activity with UIAlertview.
Obviously, My app will crash on OK button of alert view.
So, In that case
How can I disable navigation bar back button? (when I click on search)
OR
How to prevent UIAlerview to display when I click on back button?
Update :
I tried all methods to hide back bar button. :-)
Only hiding button or disabling user interaction is not the best practice cause the user won't know what's happening with the app, in case of longer process the user will thing that the app is frozen and will terminate it. Good practice in these cases are HUDs, progress indicators that block user interactions. In this case the user will see that something is happening in background and will wait for it to finish, and if he tires to go back the HUD wont let him. I usually use this one:
https://github.com/jdg/MBProgressHUD
, the implementation is very easy and it looks quite nice, but you can always program one of your own.
save reference of your UIAlertView as property
#property (strong, nonatomic) UIAlertView *alert;
show alert
self.alert = [[UIAlertView alloc] initWithTitle:#"title" message:#"message" delegate:self cancelButtonTitle:#"cancel" otherButtonTitles: nil];
[self.alert show];
in case of "risk", remove the delegate
self.alert.delegate = nil;
When risk finished, reset delegate
self.alert.delegate = self;

ios button doesn't tap - noob issue

So I'm a new ios developer and am working on my first app. I have a 3d game in unity that I exported as an xcode project and my goal is to add an ios menu before accessing the game. Suffice it to say, I'm struggling with this. I've watch some of the stanford tutorials (great!), and read some tutorials I thought was applicable, but I'm stuck. Here's what I've got:
I hijacked the main.m file to load myAppDelegate (instead of the one Unity made). myAppDelegate then loads an instance of myViewController and adds it as a subview to the window. In the myViewController, I have:
-(IBAction) displayView:(id) sender{
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Button Pressed"
message:#"You have pressed the Button view."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
I'm just trying to issue an alert on a button click. I have the function defined in the .h file with -(IBAction) displayView:(id) sender;
On the view side of things, I added an entry to my plist file I have Main Nib File Base Name set to MainWindow.
Then in the Interface Builder, in MainWindow.xib, I had added from the Library, myAppDelegate and myViewController. For myAppDelegate, I added myViewController as the viewController delegate, window is Window, and the reference outlet is the file owner. For myViewController, the referencing outlet is the myAppDelegate. (To be honest, this part confuses me. It doesn't have much of a corollary to my php web app background.)
In myViewController.xib, the File Owner is myViewController. Received action shows a link from my function (displayView) to a button. Then for the view, I opened that up, painted it red and littered it with general ios widgets (buttons, datepickers, etc). I hooked up one of the buttons to have a touch up inside of displayView.
So that's all that I've done, I load up the app on my device and I see exactly what I laid out on view. But nothing is intractable. I expect taping my button to show the alert defined above. But that doesn't happen. In fact nothing happens. So I suspect the hooking of all of this up is incorrect. But the button doesn't even depress? I would expect the white button to flash blue (down state) when I tap it. Further, I would expect the date picker (not hooked up to function), to spin as I interact with it.
It's as if my touches aren't getting sent to the view. Does anybody have any idea what I might be doing wrong? Thanks in advance for your help!
Try this code:
-(IBAction) displayView:(id) sender{
UIAlertView * myAlert;
myAlert = [[UIAlertView alloc]initWithTitle:#"Button Pressed"
message:#"You have pressed the Button view."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[myAlert show];
/* And make sure to have this action connected to your button in xib
file */
}

iPad crash with UIActionSheet displayed from child view controller

I apologize if this has been asked but I can't seem to find it anywhere. I even recreated my issue in a demo project in case any of you want to see it first-hand, although I don't know where I should post it.
I have a xibless UINavigationController based app. Some of my child ViewControllers have a button on the right side at the top that then displays a UIActionSheet. My app is designed for iPhone and iPad, so when I get ready to display the UIActionSheet I do:
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:[NSString stringWithFormat:#"%# Menu", [self title]] delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Email", #"Print", nil];
[actionSheet setActionSheetStyle:UIActionSheetStyleDefault];
if ([actionSheet respondsToSelector:#selector(showFromBarButtonItem:animated:)])
[actionSheet showFromBarButtonItem:[[self navigationItem] rightBarButtonItem] animated:YES];
else [actionSheet showInView:[self view]];
[actionSheet release];
On iPad, I'm trying to show the UIActionSheet attached to the right bar button and on iPhone it should slide in from the bottom. All of this works beautifully.
Unfortunately, if you tap the button and show the menu on iPad, but then tap the back button on the top left side of the app, the menu doesn't dismiss. Instead UINavigationController dutifully pops back and the UIActionSheet is still there. If you try to tap something on the menu you of course get a crash. If the user would have tapped anything else on the screen instead of the Back button, the menu properly dismisses.
If you try this test on iPhone, everything works as expected. There is no issue.
My demo project has an AppDelegate and a ViewController and that's about it. The AppDelegate builds an NSDictionary of NSDictionaries just so I have a model I can recurse through to demonstrate the issue. The ViewController shows all of the keys of the dictionary and if the corresponding value is an NSDictionary, you can tap it to drill down.
This is an interesting problem. Here's what the UIActionSheet Class Reference has to say.
On iPad, this method presents the action sheet in a popover and adds
the toolbar that owns the button to the popover’s list of passthrough
views. Thus, taps in the toolbar result in the action methods of the
corresponding toolbar items being called. If you want the popover to
be dismissed when a different toolbar item is tapped, you must
implement that behavior in your action handler methods.
So when you display the action sheet, it's automatically creating a UIPopoverController and set the containing toolbar (or navigation bar) as the popover's passthrough views, allowing touch events to continue. I think the best bet is to create an instance variable for your action sheet and to force it to dismiss if it is visible in -viewWillDisappear:.
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
if (self.actionSheet.window) // If action sheet is on screen, window is non-nil
[self.actionSheet dismissWithClickedButtonIndex:self.actionSheet.cancelButtonIndex animated:animated];
}
Have you tried force-dismissing the ActionSheet on viewWillDisappear?
Try this:
// In MyViewController.m
- (void)viewWillDisappear:(BOOL)animated {
[actionSheet dismissWithClickedButtonIndex:nil animated:animated];
}
*The crash sounds like a possible EXC_BAD_ACCESS. You might be losing your pointer reference to 'actionSheet' when you change views due to your release. Might be good to hang on to a reference to actionSheet in your .h file and manage the timing of your release.
*Also see the docs for info about the dismiss message: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIActionSheet_Class/Reference/Reference.html

UIActionSheet cancel button strange behaviour

I have a UIBarButtonItem opening an action sheet to offer users choices about what to do. Everything works as expected unless I try to click on the "Cancel" button. The target of the button appears to have moved up from where it should be. I can only activate it by clicking somewhere in the middle of the "Cancel" and "Ok" buttons.
I've tried at action sheets in other applications and they work fine, so it's not just my big thumb. The action sheet is opening in a UIViewController
- (void)showOpenOptions
{
UIActionSheet *sheet = [[UIActionSheet alloc]
initWithTitle:NSLocalizedString(#"Open link in external application?", #"Open in external application")
delegate:self
cancelButtonTitle:NSLocalizedString(#"Cancel", #"Cancel")
destructiveButtonTitle:NSLocalizedString(#"Open Link", #"Open Link")
otherButtonTitles:nil];
[sheet showInView:self.view];
[sheet release];
}
Instead of passing the current view controller's view to the action sheet, use the showFromTabBar: method of UIActionSheet.
The Right Way
This will give the correct tappable area:
[actionSheet showFromTabBar:self.tabBarController.tabBar];
The Wrong Way
This will put the tappable area in the wrong place (if you're using a tab bar or toolbar):
[actionSheet showInView:self.view];
If you're using a toolbar, use the showFromToolbar: method instead. You'll need a reference to the toolbar, most likely an ivar
[actionSheet showFromToolbar:self.myToolbar];
My Old Answer Also works, but is hacky:
Just found a possible answer:
01-Dec-2008 10:22 PM Tom Saxton:
I looked at this bug some more, and it seems to be an issue with the tabbar.
If you call UIActionSheet's [sheet showInView:self.view] from a view controller that is a child of a UITabViewController, then the hit testing on the cancel button fails in that portion of the UIActionSheet that lies above the tabbar's view.
If you instead pass in the UITabBarController's view, then the UIActionSheet acts as expected.
NOTE: in iPhone OS 2.1 and earlier, the UIActionSheet came up from the top of the tab bar when you pass the child view, but in 2.2, it comes up from the bottom of the tab bar, and thus covers the tab view.
http://openradar.appspot.com/6410780
Edit: It works correctly when I change the view to be the tab bar's view
[sheet showInView:self.parentViewController.tabBarController.view];
I found an answer over here that works.
using: [filterActionSheet showInView:[self.view window]];
i tried a few ways to get to my tab bar and they way this app is set up it seem convoluted...
Instead use:
[sheet showFromTabBar:theTabBar];
Here is the fix.Try this:
[actionsheet showInView:[UIApplication sharedApplication].keyWindow];
I think a combination of three of the answers is the right way of handling this:
[actionSheet showFromTabBar:self.tabBarController.tabBar];
i.e., use showFromTabBar (that's why it exists) and you don't need the parentViewController as Nathan pointed out (in fact, self.parentViewController.tabBarController.tabBar returns nil for me.
FYI - had the same problem with UIDocumentInteractionController's actionsheet stepping on the tabbar. Used the following to fix.
UIViewController *parentView = [[self parentViewController] parentViewController];
[docController presentOptionsMenuFromRect: rect inView: parentView.view animated:YES];
write simplite code
actionSheet.actionSheetStyle = UIActionSheetStyleDefault;
this work fine

Resources