Added block-based UIAlertview handler. This will ease development

This commit is contained in:
Guillaume BIENKOWSKI 2014-07-10 14:11:46 +02:00
parent 974fe07e2b
commit 77dfa1c6b3
4 changed files with 360 additions and 3 deletions

View file

@ -0,0 +1,59 @@
//
// UIAlertView+Blocks.h
// UIAlertViewBlocks
//
// Created by Ryan Maxwell on 29/08/13.
//
// The MIT License (MIT)
//
// Copyright (c) 2013 Ryan Maxwell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell 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.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 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.
//
#import <UIKit/UIKit.h>
typedef void (^UIAlertViewBlock) (UIAlertView *alertView);
typedef void (^UIAlertViewCompletionBlock) (UIAlertView *alertView, NSInteger buttonIndex);
@interface UIAlertView (Blocks)
+ (instancetype)showWithTitle:(NSString *)title
message:(NSString *)message
style:(UIAlertViewStyle)style
cancelButtonTitle:(NSString *)cancelButtonTitle
otherButtonTitles:(NSArray *)otherButtonTitles
tapBlock:(UIAlertViewCompletionBlock)tapBlock;
+ (instancetype)showWithTitle:(NSString *)title
message:(NSString *)message
cancelButtonTitle:(NSString *)cancelButtonTitle
otherButtonTitles:(NSArray *)otherButtonTitles
tapBlock:(UIAlertViewCompletionBlock)tapBlock;
@property (copy, nonatomic) UIAlertViewCompletionBlock tapBlock;
@property (copy, nonatomic) UIAlertViewCompletionBlock willDismissBlock;
@property (copy, nonatomic) UIAlertViewCompletionBlock didDismissBlock;
@property (copy, nonatomic) UIAlertViewBlock willPresentBlock;
@property (copy, nonatomic) UIAlertViewBlock didPresentBlock;
@property (copy, nonatomic) UIAlertViewBlock cancelBlock;
@property (copy, nonatomic) BOOL(^shouldEnableFirstOtherButtonBlock)(UIAlertView *alertView);
@end

View file

@ -0,0 +1,264 @@
//
// UIAlertView+Blocks.m
// UIAlertViewBlocks
//
// Created by Ryan Maxwell on 29/08/13.
//
// The MIT License (MIT)
//
// Copyright (c) 2013 Ryan Maxwell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell 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.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 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.
//
#import "UIAlertView+Blocks.h"
#import <objc/runtime.h>
static const void *UIAlertViewOriginalDelegateKey = &UIAlertViewOriginalDelegateKey;
static const void *UIAlertViewTapBlockKey = &UIAlertViewTapBlockKey;
static const void *UIAlertViewWillPresentBlockKey = &UIAlertViewWillPresentBlockKey;
static const void *UIAlertViewDidPresentBlockKey = &UIAlertViewDidPresentBlockKey;
static const void *UIAlertViewWillDismissBlockKey = &UIAlertViewWillDismissBlockKey;
static const void *UIAlertViewDidDismissBlockKey = &UIAlertViewDidDismissBlockKey;
static const void *UIAlertViewCancelBlockKey = &UIAlertViewCancelBlockKey;
static const void *UIAlertViewShouldEnableFirstOtherButtonBlockKey = &UIAlertViewShouldEnableFirstOtherButtonBlockKey;
@implementation UIAlertView (Blocks)
+ (instancetype)showWithTitle:(NSString *)title
message:(NSString *)message
style:(UIAlertViewStyle)style
cancelButtonTitle:(NSString *)cancelButtonTitle
otherButtonTitles:(NSArray *)otherButtonTitles
tapBlock:(UIAlertViewCompletionBlock)tapBlock {
NSString *firstObject = otherButtonTitles.count ? otherButtonTitles[0] : nil;
UIAlertView *alertView = [[self alloc] initWithTitle:title
message:message
delegate:nil
cancelButtonTitle:cancelButtonTitle
otherButtonTitles:firstObject, nil];
alertView.alertViewStyle = style;
if (otherButtonTitles.count > 1) {
for (NSString *buttonTitle in [otherButtonTitles subarrayWithRange:NSMakeRange(1, otherButtonTitles.count - 1)]) {
[alertView addButtonWithTitle:buttonTitle];
}
}
if (tapBlock) {
alertView.tapBlock = tapBlock;
}
[alertView show];
#if !__has_feature(objc_arc)
return [alertView autorelease];
#else
return alertView;
#endif
}
+ (instancetype)showWithTitle:(NSString *)title
message:(NSString *)message
cancelButtonTitle:(NSString *)cancelButtonTitle
otherButtonTitles:(NSArray *)otherButtonTitles
tapBlock:(UIAlertViewCompletionBlock)tapBlock {
return [self showWithTitle:title
message:message
style:UIAlertViewStyleDefault
cancelButtonTitle:cancelButtonTitle
otherButtonTitles:otherButtonTitles
tapBlock:tapBlock];
}
#pragma mark -
- (void)_checkAlertViewDelegate {
if (self.delegate != (id<UIAlertViewDelegate>)self) {
objc_setAssociatedObject(self, UIAlertViewOriginalDelegateKey, self.delegate, OBJC_ASSOCIATION_ASSIGN);
self.delegate = (id<UIAlertViewDelegate>)self;
}
}
- (UIAlertViewCompletionBlock)tapBlock {
return objc_getAssociatedObject(self, UIAlertViewTapBlockKey);
}
- (void)setTapBlock:(UIAlertViewCompletionBlock)tapBlock {
[self _checkAlertViewDelegate];
objc_setAssociatedObject(self, UIAlertViewTapBlockKey, tapBlock, OBJC_ASSOCIATION_COPY);
}
- (UIAlertViewCompletionBlock)willDismissBlock {
return objc_getAssociatedObject(self, UIAlertViewWillDismissBlockKey);
}
- (void)setWillDismissBlock:(UIAlertViewCompletionBlock)willDismissBlock {
[self _checkAlertViewDelegate];
objc_setAssociatedObject(self, UIAlertViewWillDismissBlockKey, willDismissBlock, OBJC_ASSOCIATION_COPY);
}
- (UIAlertViewCompletionBlock)didDismissBlock {
return objc_getAssociatedObject(self, UIAlertViewDidDismissBlockKey);
}
- (void)setDidDismissBlock:(UIAlertViewCompletionBlock)didDismissBlock {
[self _checkAlertViewDelegate];
objc_setAssociatedObject(self, UIAlertViewDidDismissBlockKey, didDismissBlock, OBJC_ASSOCIATION_COPY);
}
- (UIAlertViewBlock)willPresentBlock {
return objc_getAssociatedObject(self, UIAlertViewWillPresentBlockKey);
}
- (void)setWillPresentBlock:(UIAlertViewBlock)willPresentBlock {
[self _checkAlertViewDelegate];
objc_setAssociatedObject(self, UIAlertViewWillPresentBlockKey, willPresentBlock, OBJC_ASSOCIATION_COPY);
}
- (UIAlertViewBlock)didPresentBlock {
return objc_getAssociatedObject(self, UIAlertViewDidPresentBlockKey);
}
- (void)setDidPresentBlock:(UIAlertViewBlock)didPresentBlock {
[self _checkAlertViewDelegate];
objc_setAssociatedObject(self, UIAlertViewDidPresentBlockKey, didPresentBlock, OBJC_ASSOCIATION_COPY);
}
- (UIAlertViewBlock)cancelBlock {
return objc_getAssociatedObject(self, UIAlertViewCancelBlockKey);
}
- (void)setCancelBlock:(UIAlertViewBlock)cancelBlock {
[self _checkAlertViewDelegate];
objc_setAssociatedObject(self, UIAlertViewCancelBlockKey, cancelBlock, OBJC_ASSOCIATION_COPY);
}
- (void)setShouldEnableFirstOtherButtonBlock:(BOOL(^)(UIAlertView *alertView))shouldEnableFirstOtherButtonBlock {
[self _checkAlertViewDelegate];
objc_setAssociatedObject(self, UIAlertViewShouldEnableFirstOtherButtonBlockKey, shouldEnableFirstOtherButtonBlock, OBJC_ASSOCIATION_COPY);
}
- (BOOL(^)(UIAlertView *alertView))shouldEnableFirstOtherButtonBlock {
return objc_getAssociatedObject(self, UIAlertViewShouldEnableFirstOtherButtonBlockKey);
}
#pragma mark - UIAlertViewDelegate
- (void)willPresentAlertView:(UIAlertView *)alertView {
UIAlertViewBlock block = alertView.willPresentBlock;
if (block) {
block(alertView);
}
id originalDelegate = objc_getAssociatedObject(self, UIAlertViewOriginalDelegateKey);
if (originalDelegate && [originalDelegate respondsToSelector:@selector(willPresentAlertView:)]) {
[originalDelegate willPresentAlertView:alertView];
}
}
- (void)didPresentAlertView:(UIAlertView *)alertView {
UIAlertViewBlock block = alertView.didPresentBlock;
if (block) {
block(alertView);
}
id originalDelegate = objc_getAssociatedObject(self, UIAlertViewOriginalDelegateKey);
if (originalDelegate && [originalDelegate respondsToSelector:@selector(didPresentAlertView:)]) {
[originalDelegate didPresentAlertView:alertView];
}
}
- (void)alertViewCancel:(UIAlertView *)alertView {
UIAlertViewBlock block = alertView.cancelBlock;
if (block) {
block(alertView);
}
id originalDelegate = objc_getAssociatedObject(self, UIAlertViewOriginalDelegateKey);
if (originalDelegate && [originalDelegate respondsToSelector:@selector(alertViewCancel:)]) {
[originalDelegate alertViewCancel:alertView];
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
UIAlertViewCompletionBlock completion = alertView.tapBlock;
if (completion) {
completion(alertView, buttonIndex);
}
id originalDelegate = objc_getAssociatedObject(self, UIAlertViewOriginalDelegateKey);
if (originalDelegate && [originalDelegate respondsToSelector:@selector(alertView:clickedButtonAtIndex:)]) {
[originalDelegate alertView:alertView clickedButtonAtIndex:buttonIndex];
}
}
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex {
UIAlertViewCompletionBlock completion = alertView.willDismissBlock;
if (completion) {
completion(alertView, buttonIndex);
}
id originalDelegate = objc_getAssociatedObject(self, UIAlertViewOriginalDelegateKey);
if (originalDelegate && [originalDelegate respondsToSelector:@selector(alertView:willDismissWithButtonIndex:)]) {
[originalDelegate alertView:alertView willDismissWithButtonIndex:buttonIndex];
}
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
UIAlertViewCompletionBlock completion = alertView.didDismissBlock;
if (completion) {
completion(alertView, buttonIndex);
}
id originalDelegate = objc_getAssociatedObject(self, UIAlertViewOriginalDelegateKey);
if (originalDelegate && [originalDelegate respondsToSelector:@selector(alertView:didDismissWithButtonIndex:)]) {
[originalDelegate alertView:alertView didDismissWithButtonIndex:buttonIndex];
}
}
- (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView {
BOOL(^shouldEnableFirstOtherButtonBlock)(UIAlertView *alertView) = alertView.shouldEnableFirstOtherButtonBlock;
if (shouldEnableFirstOtherButtonBlock) {
return shouldEnableFirstOtherButtonBlock(alertView);
}
id originalDelegate = objc_getAssociatedObject(self, UIAlertViewOriginalDelegateKey);
if (originalDelegate && [originalDelegate respondsToSelector:@selector(alertViewShouldEnableFirstOtherButton:)]) {
return [originalDelegate alertViewShouldEnableFirstOtherButton:alertView];
}
return YES;
}
@end

View file

@ -2,56 +2,73 @@
<body>
<div style="text-align:center;">
<h1>Third party softwares</h1>
<h3>CAAnimationBlocks</h3>
<p>Xissburg<br />
<a href="http://xissburg.com">http://xissburg.com</a></p>
<h3>ColorConverter</h3>
<p>Matteo Alessani<br />
<a href="http://www.extendi.it">http://www.extendi.it</a></p>
<h3>DCRoundSwitch</h3>
<p>Patrick Richards<br />
<a href="http://domesticcat.com.au">http://domesticcat.com.au</a><br />
<em>MIT license</em></p>
<h3>DTFoundation</h3>
<p>Oliver Drobnik<br />
<a href="http://www.cocoanetics.com">http://www.cocoanetics.com</a><br />
<em>BSD license</em></p>
<h3>HPGrowingTextView</h3>
<p>Hans Pinckaers<br />
<a href="http://hanspinckaers.com">http://hanspinckaers.com</a><br />
<em>MIT license</em></p>
<h3>InAppSettingsKit</h3>
<p>Luc Vandal, Edovia Inc., Ortwin Gentz, FutureTap GmbH<br />
<a href="http://www.inappsettingskit.com/">http://www.inappsettingskit.com/</a><br />
<em>BSD license</em></p>
<h3>NinePatch</h3>
<p>Tortuga 22, Inc.<br />
<a href="http://www.tortuga22.com">http://www.tortuga22.com</a><br />
<em>Apache license</em></p>
<h3>Ryan Maxwell</h3>
<p>UIAlertview+Blocks</p>
<a href="https://github.com/ryanmaxwell/UIAlertView-Blocks">https://github.com/ryanmaxwell/UIAlertView-Blocks</a><br />
<em>MIT license</em>
<h3>OrderedDictionary</h3>
<p>Matt Gallagher<br />
<a href="http://cocoawithlove.com">http://cocoawithlove.com</a></p>
<h3>TPMultiLayoutViewController</h3>
<p>Michael Tyson<br />
<a href="http://atastypixel.com">http://atastypixel.com</a><br />
<em>MIT license</em></p>
<h3>UACellBackgroundView</h3>
<p>Matt Coneybeare<br />
<a href="http://code.coneybeare.net">http://code.coneybeare.net</a></p>
<h3>XMLRPC</h3>
<p>Eric Czarny<br />
<a href="http://divisiblebyzero.com/">http://divisiblebyzero.com/</a><br />
<em>MIT license</em></p>
<h1>Graphics</h1>
<h3>Kerosine</h3>
<p><a href="http://www.kerosine.fr">http://www.kerosine.fr</a></p>
<h1>Translations</h1>
<h3>Russian</h3>
<p>Maxim Solodovnik<br />
<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#115;&#111;&#108;&#111;&#109;&#97;&#120;&#54;&#54;&#54;&#64;&#103;&#109;&#97;&#105;&#108;&#46;&#99;&#111;&#109;">&#115;&#111;&#108;&#111;&#109;&#97;&#120;&#54;&#54;&#54;&#64;&#103;&#109;&#97;&#105;&#108;&#46;&#99;&#111;&#109;</a></p>
<h1>Utilitary softwares</h1>
<h3>Localization Suite</h3>
<p><a href="http://www.loc-suite.org">http://www.loc-suite.org</a></p>
</div>
</body>
</html>

View file

@ -1428,6 +1428,8 @@
F0BB8C48193630CA00974404 /* userdb.conf in Resources */ = {isa = PBXBuildFile; fileRef = F0BB8C43193630CA00974404 /* userdb.conf */; };
F0BB8C4C193631D200974404 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22276E8813C73DC000210156 /* CoreMedia.framework */; };
F0BB8C4D193631DF00974404 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 224567C1107B968500F10948 /* AVFoundation.framework */; };
F0D00DE2196EB8F40018F6E7 /* UIAlertView+Blocks.m in Sources */ = {isa = PBXBuildFile; fileRef = F0D00DE1196EB8F40018F6E7 /* UIAlertView+Blocks.m */; };
F0D00DE3196EB8F40018F6E7 /* UIAlertView+Blocks.m in Sources */ = {isa = PBXBuildFile; fileRef = F0D00DE1196EB8F40018F6E7 /* UIAlertView+Blocks.m */; };
F476004B147AAF2800FFF19B /* liblinphone.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2211DB911475562600DEE054 /* liblinphone.a */; };
F84015BF1939FE37006ABAB5 /* test_failed.png in Resources */ = {isa = PBXBuildFile; fileRef = F84015BC1939FE37006ABAB5 /* test_failed.png */; };
F84015C01939FE37006ABAB5 /* test_inprogress.png in Resources */ = {isa = PBXBuildFile; fileRef = F84015BD1939FE37006ABAB5 /* test_inprogress.png */; };
@ -2377,6 +2379,8 @@
F0BB8C42193630CA00974404 /* tester_hosts */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = tester_hosts; path = submodules/linphone/tester/tester_hosts; sourceTree = SOURCE_ROOT; };
F0BB8C43193630CA00974404 /* userdb.conf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = userdb.conf; path = submodules/linphone/tester/userdb.conf; sourceTree = SOURCE_ROOT; };
F0BB8C4A193631B300974404 /* ImageIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = System/Library/Frameworks/ImageIO.framework; sourceTree = SDKROOT; };
F0D00DE0196EB8F40018F6E7 /* UIAlertView+Blocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIAlertView+Blocks.h"; sourceTree = "<group>"; };
F0D00DE1196EB8F40018F6E7 /* UIAlertView+Blocks.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIAlertView+Blocks.m"; sourceTree = "<group>"; };
F84015BC1939FE37006ABAB5 /* test_failed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = test_failed.png; path = Resources/test_failed.png; sourceTree = "<group>"; };
F84015BD1939FE37006ABAB5 /* test_inprogress.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = test_inprogress.png; path = Resources/test_inprogress.png; sourceTree = "<group>"; };
F84015BE1939FE37006ABAB5 /* test_passed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = test_passed.png; path = Resources/test_passed.png; sourceTree = "<group>"; };
@ -2880,6 +2884,7 @@
D3807FB615C28940005BE9BC /* DCRoundSwitch */,
D37EE15F160377D7003608A6 /* DTFoundation */,
D32B9DFA15A2F131000B6DEC /* FastAddressBook.h */,
F0D00DDF196EB8F40018F6E7 /* UIAlertView+Blocks */,
D32B9DFB15A2F131000B6DEC /* FastAddressBook.m */,
D3ED40141602172200BF332B /* GrowingTextView */,
D3807FC715C2894A005BE9BC /* InAppSettingsKit */,
@ -3598,6 +3603,16 @@
name = "Supporting Files";
sourceTree = "<group>";
};
F0D00DDF196EB8F40018F6E7 /* UIAlertView+Blocks */ = {
isa = PBXGroup;
children = (
F0D00DE0196EB8F40018F6E7 /* UIAlertView+Blocks.h */,
F0D00DE1196EB8F40018F6E7 /* UIAlertView+Blocks.m */,
);
name = "UIAlertView+Blocks";
path = "Utils/UIAlertView+Blocks";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -4916,6 +4931,7 @@
D32409C3158B49A600C8C119 /* UILongTouchButton.m in Sources */,
D36C43C6158F2E5A0048BA40 /* UICallCell.m in Sources */,
D35E7581159328EB0066B1C1 /* UIAddressTextField.m in Sources */,
F0D00DE2196EB8F40018F6E7 /* UIAlertView+Blocks.m in Sources */,
D35E7597159460580066B1C1 /* ChatViewController.m in Sources */,
D35E759F159460B70066B1C1 /* SettingsViewController.m in Sources */,
F03CA84318C72F1A0008889D /* UITextViewNoDefine.m in Sources */,
@ -5015,6 +5031,7 @@
D32409C4158B49A600C8C119 /* UILongTouchButton.m in Sources */,
D36C43C7158F2E5A0048BA40 /* UICallCell.m in Sources */,
D35E7582159328EB0066B1C1 /* UIAddressTextField.m in Sources */,
F0D00DE3196EB8F40018F6E7 /* UIAlertView+Blocks.m in Sources */,
D35E7598159460580066B1C1 /* ChatViewController.m in Sources */,
D35E75A0159460B70066B1C1 /* SettingsViewController.m in Sources */,
F03CA84418C72F1A0008889D /* UITextViewNoDefine.m in Sources */,