From e2555db52cacd50a576235713a09f33acb1b1b97 Mon Sep 17 00:00:00 2001 From: jerome Morissard Date: Sat, 8 Mar 2014 18:02:51 +0100 Subject: [PATCH 1/2] [UIAlertView-Blocks] Fix crash when user is trying to add a nil RIButtonItem + return a BOOL value that represent success of addition --- RIButtonItem.h | 1 + RIButtonItem.m | 9 ++++++++- UIActionSheet+Blocks.h | 2 +- UIActionSheet+Blocks.m | 12 ++++++++---- UIAlertView+Blocks.h | 2 +- UIAlertView+Blocks.m | 12 ++++++++---- 6 files changed, 27 insertions(+), 11 deletions(-) diff --git a/RIButtonItem.h b/RIButtonItem.h index 545106b..73bb6a4 100644 --- a/RIButtonItem.h +++ b/RIButtonItem.h @@ -17,5 +17,6 @@ @property (copy, nonatomic) void (^action)(); +(id)item; +(id)itemWithLabel:(NSString *)inLabel; ++(id)itemWithLabel:(NSString *)inLabel action:(void(^)(void))action; @end diff --git a/RIButtonItem.m b/RIButtonItem.m index a503f4e..61803fc 100644 --- a/RIButtonItem.m +++ b/RIButtonItem.m @@ -19,10 +19,17 @@ +(id)item +(id)itemWithLabel:(NSString *)inLabel { - id newItem = [self item]; + RIButtonItem *newItem = [self item]; [newItem setLabel:inLabel]; return newItem; } ++(id)itemWithLabel:(NSString *)inLabel action:(void(^)(void))action +{ + RIButtonItem *newItem = [self itemWithLabel:inLabel]; + [newItem setAction:action]; + return newItem; +} + @end diff --git a/UIActionSheet+Blocks.h b/UIActionSheet+Blocks.h index 2ecba7f..daf9e52 100644 --- a/UIActionSheet+Blocks.h +++ b/UIActionSheet+Blocks.h @@ -13,7 +13,7 @@ -(id)initWithTitle:(NSString *)inTitle cancelButtonItem:(RIButtonItem *)inCancelButtonItem destructiveButtonItem:(RIButtonItem *)inDestructiveItem otherButtonItems:(RIButtonItem *)inOtherButtonItems, ... NS_REQUIRES_NIL_TERMINATION; -- (NSInteger)addButtonItem:(RIButtonItem *)item; +- (BOOL)addButtonItem:(RIButtonItem *)item; /** This block is called when the action sheet is dismssed for any reason. */ diff --git a/UIActionSheet+Blocks.m b/UIActionSheet+Blocks.m index b852947..cc8bf04 100644 --- a/UIActionSheet+Blocks.m +++ b/UIActionSheet+Blocks.m @@ -57,14 +57,18 @@ -(id)initWithTitle:(NSString *)inTitle cancelButtonItem:(RIButtonItem *)inCancel return self; } -- (NSInteger)addButtonItem:(RIButtonItem *)item -{ - NSMutableArray *buttonsArray = objc_getAssociatedObject(self, (__bridge const void *)RI_BUTTON_ASS_KEY); +- (BOOL)addButtonItem:(RIButtonItem *)item +{ + if (nil == item) { + return NO; + } + + NSMutableArray *buttonsArray = objc_getAssociatedObject(self, (__bridge const void *)RI_BUTTON_ASS_KEY); NSInteger buttonIndex = [self addButtonWithTitle:item.label]; [buttonsArray addObject:item]; - return buttonIndex; + return (buttonIndex >= 0); } - (void)setDismissalAction:(void(^)())dismissalAction diff --git a/UIAlertView+Blocks.h b/UIAlertView+Blocks.h index 6fec7ca..29ed2ac 100644 --- a/UIAlertView+Blocks.h +++ b/UIAlertView+Blocks.h @@ -13,6 +13,6 @@ -(id)initWithTitle:(NSString *)inTitle message:(NSString *)inMessage cancelButtonItem:(RIButtonItem *)inCancelButtonItem otherButtonItems:(RIButtonItem *)inOtherButtonItems, ... NS_REQUIRES_NIL_TERMINATION; -- (NSInteger)addButtonItem:(RIButtonItem *)item; +- (BOOL)addButtonItem:(RIButtonItem *)item; @end diff --git a/UIAlertView+Blocks.m b/UIAlertView+Blocks.m index e94f675..cc91237 100644 --- a/UIAlertView+Blocks.m +++ b/UIAlertView+Blocks.m @@ -47,14 +47,18 @@ -(id)initWithTitle:(NSString *)inTitle message:(NSString *)inMessage cancelButto return self; } -- (NSInteger)addButtonItem:(RIButtonItem *)item -{ - NSMutableArray *buttonsArray = objc_getAssociatedObject(self, (__bridge const void *)RI_BUTTON_ASS_KEY); +- (BOOL)addButtonItem:(RIButtonItem *)item +{ + if (nil == item) { + return NO; + } + + NSMutableArray *buttonsArray = objc_getAssociatedObject(self, (__bridge const void *)RI_BUTTON_ASS_KEY); NSInteger buttonIndex = [self addButtonWithTitle:item.label]; [buttonsArray addObject:item]; - return buttonIndex; + return (buttonIndex >= 0); } - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex From 932c2d9feffbee9b8f780d5d7d54ee6be9064c24 Mon Sep 17 00:00:00 2001 From: jerome Morissard Date: Sat, 8 Mar 2014 18:09:59 +0100 Subject: [PATCH 2/2] [UIAlertView-Blocks] Restore NSInteger --- README.md | 43 ++++++++++++++++++++++++------------------ UIActionSheet+Blocks.h | 2 +- UIActionSheet+Blocks.m | 6 +++--- UIAlertView+Blocks.h | 2 +- UIAlertView+Blocks.m | 6 +++--- 5 files changed, 33 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 73a2d92..d4ac0f1 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Using UIAlertView as the main example here, instead of calling the traditional ` The action blocks are of type RISimpleAction, which is typedef'd to be a block as follows: typedef void (^RISimpleAction)(); - + This is just a simple block which takes no arguments and returns nothing. The RIButtonItem class also provides a convenience method which returns an autoreleased item called, conveniently enough, `+item`. If you don't specify an action, the button will still show, but won't do anything when tapped other than dismiss the dialog. This is pretty common with cancel buttons, so another convenience method called `+itemWithLabel:` allows you to quickly create an item that has no action. @@ -25,41 +25,46 @@ HOW TO USE IT Typically, you'll create items that represent the buttons and the actions to take when they are tapped. For example imagine a dialog box confirming deletion of an item: - RIButtonItem *cancelItem = [RIButtonItem item]; - cancelItem.label = @"No"; - cancelItem.action = ^ - { + RIButtonItem *cancelItem = [RIButtonItem itemWithLabel:@"No" action:^{ // this is the code that will be executed when the user taps "No" // this is optional... if you leave the action as nil, it won't do anything // but here, I'm showing a block just to show that you can use one if you want to. - }; + }]; - RIButtonItem *deleteItem = [RIButtonItem item]; - deleteItem.label = @"Yes"; - deleteItem.action = ^ - { + RIButtonItem *deleteItem = [RIButtonItem itemWithLabel:@"Yes" action:^{ // this is the code that will be executed when the user taps "Yes" // delete the object in question... [context deleteObject:theObject]; - }; + }]; The label property on the button items is the text that will be displayed in the button. Once you've created these, you simply initialize your UIAlertView using the initializer, passing your button items accordingly: - UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Delete This Item?" - message:@"Are you sure you want to delete this really important thing?" - cancelButtonItem:cancelItem + UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Delete This Item?" + message:@"Are you sure you want to delete this really important thing?" + cancelButtonItem:cancelItem otherButtonItems:deleteItem, nil]; [alertView show]; - [alertView release]; + +Alternatively you can also use a single line to create buttons and declare the alert view + + [[[UIAlertView alloc] initWithTitle:@"Delete This Item?" + message:@"Are you sure you want to delete this really important thing?" + cancelButtonItem:[RIButtonItem itemWithLabel:@"Yes" action:^{ + // Handle "Cancel" + }] + otherButtonItems:[RIButtonItem itemWithLabel:@"Delete" action:^{ + // Handle "Delete" + }], nil] show]; + Again, this is designed to be fire and forget, so you initialize it, show it, and release it. It'll take care of cleaning up after itself. You can also add a RIButtonItem to the UIAlertView after initialization, just like you normally would: [alertView addButtonItem:deleteItem]; - + This is useful if building an UIAlertView, or UIActionSheet dynamically from an Array: for (RIButtonItem *item in buttonItemArray) { @@ -83,7 +88,9 @@ copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +all copies or substantial portions of the Software source code. Permission +is hereby granted to reproduce the Software in binary form by compiling it +into your own projects without this attribution requirement. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -91,4 +98,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file +THE SOFTWARE. diff --git a/UIActionSheet+Blocks.h b/UIActionSheet+Blocks.h index daf9e52..2ecba7f 100644 --- a/UIActionSheet+Blocks.h +++ b/UIActionSheet+Blocks.h @@ -13,7 +13,7 @@ -(id)initWithTitle:(NSString *)inTitle cancelButtonItem:(RIButtonItem *)inCancelButtonItem destructiveButtonItem:(RIButtonItem *)inDestructiveItem otherButtonItems:(RIButtonItem *)inOtherButtonItems, ... NS_REQUIRES_NIL_TERMINATION; -- (BOOL)addButtonItem:(RIButtonItem *)item; +- (NSInteger)addButtonItem:(RIButtonItem *)item; /** This block is called when the action sheet is dismssed for any reason. */ diff --git a/UIActionSheet+Blocks.m b/UIActionSheet+Blocks.m index cc8bf04..b13f38c 100644 --- a/UIActionSheet+Blocks.m +++ b/UIActionSheet+Blocks.m @@ -57,10 +57,10 @@ -(id)initWithTitle:(NSString *)inTitle cancelButtonItem:(RIButtonItem *)inCancel return self; } -- (BOOL)addButtonItem:(RIButtonItem *)item +- (NSInteger)addButtonItem:(RIButtonItem *)item { if (nil == item) { - return NO; + return -1; } NSMutableArray *buttonsArray = objc_getAssociatedObject(self, (__bridge const void *)RI_BUTTON_ASS_KEY); @@ -68,7 +68,7 @@ - (BOOL)addButtonItem:(RIButtonItem *)item NSInteger buttonIndex = [self addButtonWithTitle:item.label]; [buttonsArray addObject:item]; - return (buttonIndex >= 0); + return buttonIndex; } - (void)setDismissalAction:(void(^)())dismissalAction diff --git a/UIAlertView+Blocks.h b/UIAlertView+Blocks.h index 29ed2ac..6fec7ca 100644 --- a/UIAlertView+Blocks.h +++ b/UIAlertView+Blocks.h @@ -13,6 +13,6 @@ -(id)initWithTitle:(NSString *)inTitle message:(NSString *)inMessage cancelButtonItem:(RIButtonItem *)inCancelButtonItem otherButtonItems:(RIButtonItem *)inOtherButtonItems, ... NS_REQUIRES_NIL_TERMINATION; -- (BOOL)addButtonItem:(RIButtonItem *)item; +- (NSInteger)addButtonItem:(RIButtonItem *)item; @end diff --git a/UIAlertView+Blocks.m b/UIAlertView+Blocks.m index cc91237..5f73592 100644 --- a/UIAlertView+Blocks.m +++ b/UIAlertView+Blocks.m @@ -47,10 +47,10 @@ -(id)initWithTitle:(NSString *)inTitle message:(NSString *)inMessage cancelButto return self; } -- (BOOL)addButtonItem:(RIButtonItem *)item +- (NSInteger)addButtonItem:(RIButtonItem *)item { if (nil == item) { - return NO; + return -1; } NSMutableArray *buttonsArray = objc_getAssociatedObject(self, (__bridge const void *)RI_BUTTON_ASS_KEY); @@ -58,7 +58,7 @@ - (BOOL)addButtonItem:(RIButtonItem *)item NSInteger buttonIndex = [self addButtonWithTitle:item.label]; [buttonsArray addObject:item]; - return (buttonIndex >= 0); + return buttonIndex; } - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex