{"id":129,"date":"2012-03-10T10:21:03","date_gmt":"2012-03-10T10:21:03","guid":{"rendered":"http:\/\/ootips.org\/yonat\/?p=129"},"modified":"2016-04-17T07:24:19","modified_gmt":"2016-04-17T07:24:19","slug":"filling-uiactionsheet-dynamically","status":"publish","type":"post","link":"https:\/\/ootips.org\/yonat\/filling-uiactionsheet-dynamically\/","title":{"rendered":"Dynamic UIActionSheet"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" class=\"alignright size-full wp-image-130\" title=\"message\" src=\"https:\/\/ootips.org\/yonat\/wp-content\/uploads\/2012\/02\/message.png\" alt=\"\" width=\"240\" height=\"212\" \/>Some actions may sometimes have more than one possible target, and other times only one.<\/p>\n<p>For example: Calling a contact. If the contact has just one phone number, you <strong>openURL<\/strong> with it and you&#8217;re done. But if she has several numbers, you want to open a <strong>UIActionSheet<\/strong> to let the user choose which number to call.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-131 alignleft\" title=\"photo\" src=\"https:\/\/ootips.org\/yonat\/wp-content\/uploads\/2012\/02\/photo-200x300.png\" alt=\"\" width=\"200\" height=\"300\" srcset=\"https:\/\/ootips.org\/yonat\/wp-content\/uploads\/2012\/02\/photo-200x300.png 200w, https:\/\/ootips.org\/yonat\/wp-content\/uploads\/2012\/02\/photo.png 240w\" sizes=\"auto, (max-width: 200px) 100vw, 200px\" \/>Or picking an image. If you&#8217;re running on a camera-less iPod, you just show a <strong>UIImagePickerController<\/strong> to pick from the photo library. But with a camera, and maybe an existing image to delete, you&#8217;ll want to show an action sheet to choose the actual action that your &#8220;Photo&#8221; button performs.<\/p>\n<p>So you need to do two things:<\/p>\n<ol>\n<li>Decide whether to show an action sheet at all or just do the one possible action.<\/li>\n<li>If you need an action sheet, fill it dynamically with the possible targets for action.<\/li>\n<\/ol>\n<p>The code to do that doesn&#8217;t have to be complicated. It can actually be as simple as this:<\/p>\n<pre class=\"lang:objc decode:true \">\r\n@interface MyViewController() : <UIActionSheetDelegate> {\r\n\tNSArray *possibleTargets; \/\/ action sheet buttons go here\r\n}\r\n@end\r\n\r\n@implementation MyViewControllerMyViewController\r\n\r\n- (IBAction)selectTargetForAction:(id)sender\r\n{\r\n    possibleTargets = SomeWayToFindPossibleTargets();\r\n\r\n    if ([possibleTargets count] == 1) {\r\n        \/\/ just call the one number, or show the one image picker\r\n        [self doAction:[possibleTargets lastObject]];\r\n    }\r\n    else if ([possibleTargets count] > 1) {\r\n        \/\/ show a dynamically filled action sheet\r\n        UIActionSheet *targetsSheet =\r\n            [[UIActionSheet alloc] initWithTitle:__(@\"Select\")\r\n                delegate:self\r\n                cancelButtonTitle:nil \/\/ since we want it last\r\n                destructiveButtonTitle:nil\r\n                otherButtonTitles:nil]; \/\/ since we can't hard-code them\r\n        for (NSString *target in possibleTargets) {\r\n            [targetsSheet addButtonWithTitle:__(target.title)];\r\n        }\r\n        targetsSheet.cancelButtonIndex = [targetsSheet addButtonWithTitle:__(@\"Cancel\")];\r\n        [targetsSheet showInView:self.view];\r\n    }\r\n}\r\n\r\n- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex\r\n{\r\n    if (buttonIndex != actionSheet.cancelButtonIndex) {\r\n        [self doAction:[possibleTargets objectAtIndex:buttonIndex]];\r\n    }\r\n}\r\n\r\n@end\r\n<\/pre>\n<p><b>Notes:<\/b><\/p>\n<ol>\n<li>The @interface code above is part of the .m file, as described in my earlier post <a href=\"https:\/\/ootips.org\/yonat\/objective-c-protocol-implementation\/\">How to Keep Your Protocols Private<\/a>.<\/li>\n<li>If you&#8217;re puzzled by the meaning of <tt>__(@\"String\")<\/tt> then see my earlier post on <a href=\"https:\/\/ootips.org\/yonat\/easy-nslocalizedstring\/\">How To Make NSLocalizedString Fun To Use<\/a>.<\/li>\n<li>The objects in possibleTargets can hold a selector (SEL) of the actual method to be executed, or they can hold just relevant data for the action (like a phone number to call).<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>Some actions may sometimes have more than one possible target, and other times only one. For example: Calling a contact. If the contact has just one phone number, you openURL with it and you&#8217;re done. But if she has several &hellip; <a href=\"https:\/\/ootips.org\/yonat\/filling-uiactionsheet-dynamically\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[1],"tags":[18,7,6,13,14],"class_list":["post-129","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-cocoa","tag-ios","tag-iphone","tag-objective-c","tag-sample-code"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p2aEUP-25","_links":{"self":[{"href":"https:\/\/ootips.org\/yonat\/wp-json\/wp\/v2\/posts\/129","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ootips.org\/yonat\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ootips.org\/yonat\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ootips.org\/yonat\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ootips.org\/yonat\/wp-json\/wp\/v2\/comments?post=129"}],"version-history":[{"count":11,"href":"https:\/\/ootips.org\/yonat\/wp-json\/wp\/v2\/posts\/129\/revisions"}],"predecessor-version":[{"id":248,"href":"https:\/\/ootips.org\/yonat\/wp-json\/wp\/v2\/posts\/129\/revisions\/248"}],"wp:attachment":[{"href":"https:\/\/ootips.org\/yonat\/wp-json\/wp\/v2\/media?parent=129"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ootips.org\/yonat\/wp-json\/wp\/v2\/categories?post=129"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ootips.org\/yonat\/wp-json\/wp\/v2\/tags?post=129"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}