From d6bf9e41936c64810e66b7098570f78cf5713cd1 Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Tue, 30 Sep 2014 16:35:08 +0200 Subject: [PATCH] Fix UIAlertView for iOS8 (updated DTFoundation) --- Classes/Utils/DTFoundation/DTActionSheet.h | 36 +++-- Classes/Utils/DTFoundation/DTActionSheet.m | 164 ++++++++++----------- Classes/Utils/DTFoundation/DTWeakSupport.h | 33 +++++ linphone.xcodeproj/project.pbxproj | 2 + 4 files changed, 138 insertions(+), 97 deletions(-) create mode 100644 Classes/Utils/DTFoundation/DTWeakSupport.h diff --git a/Classes/Utils/DTFoundation/DTActionSheet.h b/Classes/Utils/DTFoundation/DTActionSheet.h index 71ab47650..b08744656 100755 --- a/Classes/Utils/DTFoundation/DTActionSheet.h +++ b/Classes/Utils/DTFoundation/DTActionSheet.h @@ -6,45 +6,63 @@ // Copyright (c) 2012 Cocoanetics. All rights reserved. // +#import "DTWeakSupport.h" + +// the block to execute when an option button is tapped typedef void (^DTActionSheetBlock)(void); /** - Extends UIActionSheet with support for blocks + Extends UIActionSheet with support for blocks. */ @interface DTActionSheet : UIActionSheet /** - Initializes the action sheet using the specified title. + Initializes the action sheet using the specified title. + @param title The title */ -- (id)initWithTitle:(NSString *)title; +- (instancetype)initWithTitle:(NSString *)title; /** Adds a custom button to the action sheet. @param title The title of the new button. @param block The block to execute when the button is tapped. @returns The index of the new button. Button indices start at 0 and increase in the order they are added. -*/ + */ - (NSInteger)addButtonWithTitle:(NSString *)title block:(DTActionSheetBlock)block; /** Adds a custom destructive button to the action sheet. - + Since there can only be one destructive button a previously marked destructive button becomes a normal button. @param title The title of the new button. @param block The block to execute when the button is tapped. @returns The index of the new button. Button indices start at 0 and increase in the order they are added. - */ + */ - (NSInteger)addDestructiveButtonWithTitle:(NSString *)title block:(DTActionSheetBlock)block; /** Adds a custom cancel button to the action sheet. - + Since there can only be one cancel button a previously marked cancel button becomes a normal button. @param title The title of the new button. @param block The block to execute when the button is tapped. @returns The index of the new button. Button indices start at 0 and increase in the order they are added. - */ + */ - (NSInteger)addCancelButtonWithTitle:(NSString *)title block:(DTActionSheetBlock)block; -@end +/** + Adds a custom cancel button to the action sheet. + + Since there can only be one cancel button a previously marked cancel button becomes a normal button. + @param title The title of the new button. + @returns The index of the new button. Button indices start at 0 and increase in the order they are added. + */ +- (NSInteger)addCancelButtonWithTitle:(NSString *)title; + +/** + * Use the actionSheetDelegate when you want to to receive UIActionSheetDelegate messages. + */ +@property (nonatomic, DT_WEAK_PROPERTY) id actionSheetDelegate; + +@end \ No newline at end of file diff --git a/Classes/Utils/DTFoundation/DTActionSheet.m b/Classes/Utils/DTFoundation/DTActionSheet.m index f3a474c75..ae091c824 100755 --- a/Classes/Utils/DTFoundation/DTActionSheet.m +++ b/Classes/Utils/DTFoundation/DTActionSheet.m @@ -7,6 +7,7 @@ // #import "DTActionSheet.h" +#import "DTWeakSupport.h" @interface DTActionSheet () @@ -14,55 +15,74 @@ @implementation DTActionSheet { - id _externalDelegate; - NSMutableDictionary *_actionsPerIndex; - - // lookup bitmask what delegate methods are implemented - struct - { - unsigned int delegateSupportsActionSheetCancel:1; - unsigned int delegateSupportsWillPresentActionSheet:1; - unsigned int delegateSupportsDidPresentActionSheet:1; - unsigned int delegateSupportsWillDismissWithButtonIndex:1; - unsigned int delegateSupportsDidDismissWithButtonIndex:1; - } _delegateFlags; } -- (id)init +// designated initializer +- (instancetype)init { self = [super init]; if (self) { _actionsPerIndex = [[NSMutableDictionary alloc] init]; - self.delegate = self; + [super setDelegate:self]; + } - return self; } -// designated initializer -- (id)initWithTitle:(NSString *)title +- (instancetype)initWithTitle:(NSString *)title +{ + return [self initWithTitle:title delegate:nil cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil]; +} + +- (instancetype)initWithTitle:(NSString *)title delegate:(id)delegate cancelButtonTitle:(NSString *)cancelButtonTitle destructiveButtonTitle:(NSString *)destructiveButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ... { self = [self init]; - if (self) + if (self) { self.title = title; + + if (otherButtonTitles != nil) { + [self addButtonWithTitle:otherButtonTitles]; + va_list args; + va_start(args, otherButtonTitles); + NSString *title = nil; + while( (title = va_arg(args, NSString *)) ) { + [self addButtonWithTitle:title]; + } + va_end(args); + } + + if (destructiveButtonTitle) { + [self addDestructiveButtonWithTitle:destructiveButtonTitle block:nil]; + } + if (cancelButtonTitle) { + [self addCancelButtonWithTitle:cancelButtonTitle block:nil]; + } + + self.actionSheetDelegate = delegate; } - + return self; } +- (void)dealloc +{ + [super setDelegate:nil]; + self.actionSheetDelegate = nil; +} + - (NSInteger)addButtonWithTitle:(NSString *)title block:(DTActionSheetBlock)block { NSInteger retIndex = [self addButtonWithTitle:title]; - + if (block) { - NSNumber *key = [NSNumber numberWithInt:retIndex]; - [_actionsPerIndex setObject:[[block copy] autorelease] forKey:key]; + NSNumber *key = [NSNumber numberWithInteger:retIndex]; + [_actionsPerIndex setObject:[block copy] forKey:key]; } - + return retIndex; } @@ -70,122 +90,90 @@ { NSInteger retIndex = [self addButtonWithTitle:title block:block]; [self setDestructiveButtonIndex:retIndex]; - + return retIndex; } +- (NSInteger)addCancelButtonWithTitle:(NSString *)title +{ + return [self addCancelButtonWithTitle:title block:nil]; +} + - (NSInteger)addCancelButtonWithTitle:(NSString *)title block:(DTActionSheetBlock)block { NSInteger retIndex = [self addButtonWithTitle:title block:block]; [self setCancelButtonIndex:retIndex]; - + return retIndex; } -#pragma UIActionSheetDelegate (forwarded) +#pragma mark - UIActionSheetDelegate (forwarded) - (void)actionSheetCancel:(UIActionSheet *)actionSheet { - if (_delegateFlags.delegateSupportsActionSheetCancel) + if ([self.actionSheetDelegate respondsToSelector:@selector(actionSheetCancel:)]) { - [_externalDelegate actionSheetCancel:actionSheet]; + [self.actionSheetDelegate actionSheetCancel:actionSheet]; } } - (void)willPresentActionSheet:(UIActionSheet *)actionSheet { - if (_delegateFlags.delegateSupportsWillPresentActionSheet) + if ([self.actionSheetDelegate respondsToSelector:@selector(willPresentActionSheet:)]) { - [_externalDelegate willPresentActionSheet:actionSheet]; + [self.actionSheetDelegate willPresentActionSheet:actionSheet]; } } - (void)didPresentActionSheet:(UIActionSheet *)actionSheet { - if (_delegateFlags.delegateSupportsDidPresentActionSheet) + if ([self.actionSheetDelegate respondsToSelector:@selector(didPresentActionSheet:)]) { - [_externalDelegate didPresentActionSheet:actionSheet]; + [self.actionSheetDelegate didPresentActionSheet:actionSheet]; } } - (void)actionSheet:(UIActionSheet *)actionSheet willDismissWithButtonIndex:(NSInteger)buttonIndex { - if (_delegateFlags.delegateSupportsWillDismissWithButtonIndex) + if ([self.actionSheetDelegate respondsToSelector:@selector(actionSheet:willDismissWithButtonIndex:)]) { - [_externalDelegate actionSheet:actionSheet willDismissWithButtonIndex:buttonIndex]; + [self.actionSheetDelegate actionSheet:actionSheet willDismissWithButtonIndex:buttonIndex]; } } - - (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex { - NSNumber *key = [NSNumber numberWithInt:buttonIndex]; - + if ([self.actionSheetDelegate respondsToSelector:@selector(actionSheet:didDismissWithButtonIndex:)]) + { + [self.actionSheetDelegate actionSheet:actionSheet didDismissWithButtonIndex:buttonIndex]; + } +} + +- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex +{ + NSNumber *key = [NSNumber numberWithInteger:buttonIndex]; + DTActionSheetBlock block = [_actionsPerIndex objectForKey:key]; - + if (block) { block(); } - if (_delegateFlags.delegateSupportsDidDismissWithButtonIndex) + if ([self.actionSheetDelegate respondsToSelector:@selector(actionSheet:clickedButtonAtIndex:)]) { - [_externalDelegate actionSheet:actionSheet didDismissWithButtonIndex:buttonIndex]; + [self.actionSheetDelegate actionSheet:actionSheet clickedButtonAtIndex:buttonIndex]; } } - -#pragma mark Properties - -- (id )delegate -{ - return _externalDelegate; -} +#pragma mark - Properties - (void)setDelegate:(id )delegate { - if (delegate == self) + if (delegate) { - [super setDelegate:self]; - } - else if (delegate == nil) - { - [super setDelegate:nil]; - _externalDelegate = nil; - } - else - { - _externalDelegate = delegate; - } - - // wipe - memset(&_delegateFlags, 0, sizeof(_delegateFlags)); - - // set flags according to available methods in delegate - if ([_externalDelegate respondsToSelector:@selector(actionSheetCancel:)]) - { - _delegateFlags.delegateSupportsActionSheetCancel = YES; - } - - if ([_externalDelegate respondsToSelector:@selector(willPresentActionSheet:)]) - { - _delegateFlags.delegateSupportsWillPresentActionSheet = YES; - } - - if ([_externalDelegate respondsToSelector:@selector(didPresentActionSheet:)]) - { - _delegateFlags.delegateSupportsDidPresentActionSheet = YES; - } - - if ([_externalDelegate respondsToSelector:@selector(actionSheet:willDismissWithButtonIndex:)]) - { - _delegateFlags.delegateSupportsWillDismissWithButtonIndex = YES; - } - - if ([_externalDelegate respondsToSelector:@selector(actionSheet:didDismissWithButtonIndex:)]) - { - _delegateFlags.delegateSupportsDidDismissWithButtonIndex = YES; + NSLog(@"Calling setDelegate is not supported! Use setActionSheetDelegate instead"); } } -@end +@end \ No newline at end of file diff --git a/Classes/Utils/DTFoundation/DTWeakSupport.h b/Classes/Utils/DTFoundation/DTWeakSupport.h new file mode 100644 index 000000000..a74444baf --- /dev/null +++ b/Classes/Utils/DTFoundation/DTWeakSupport.h @@ -0,0 +1,33 @@ +// +// DTWeakSupport.h +// DTFoundation +// +// Created by Oliver Drobnik on 6/3/13. +// Copyright (c) 2013 Cocoanetics. All rights reserved. +// + +/** + Useful defines for building code the compiles with zeroing weak references if the deployment target allows it. This is possible from minimum supported iOS 5.0 and OS X 10.7 and above. Note that on OS X 10.7 some AppKit classes do not support having a weak ref, e.g. NSWindowController or NSViewController. + */ + +#import + +#if __has_feature(objc_arc_weak) + +// zeroing weak refs are supported for ivars and properties +#define DT_WEAK_VARIABLE __weak +#define DT_WEAK_PROPERTY weak + +#elif __has_feature(objc_arc) + +/// zeroing weak refs not supported, fall back to unsafe unretained and assigning +#define DT_WEAK_VARIABLE __unsafe_unretained +#define DT_WEAK_PROPERTY assign + +#else + +// define something, as this header might be included in a non-ARC project for using compiled code from an ARC static lib +#define DT_WEAK_VARIABLE +#define DT_WEAK_PROPERTY assign + +#endif \ No newline at end of file diff --git a/linphone.xcodeproj/project.pbxproj b/linphone.xcodeproj/project.pbxproj index 76f81f6b9..92864dc3d 100755 --- a/linphone.xcodeproj/project.pbxproj +++ b/linphone.xcodeproj/project.pbxproj @@ -2285,6 +2285,7 @@ F03CA84218C72F1A0008889D /* UITextViewNoDefine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UITextViewNoDefine.m; sourceTree = ""; }; F04892FE180C3296002FED35 /* ImageOptim.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = ImageOptim.sh; sourceTree = ""; }; F0642EF019DAC891009DB336 /* MainStoryboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = MainStoryboard.storyboard; sourceTree = ""; }; + F0642EF719DAF32E009DB336 /* DTWeakSupport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DTWeakSupport.h; sourceTree = ""; }; F066515317F9A02E0064280C /* UITransparentTVCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UITransparentTVCell.h; sourceTree = ""; }; F066515417F9A02E0064280C /* UITransparentTVCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UITransparentTVCell.m; sourceTree = ""; }; F0818E7B17FC5160005A3330 /* linphone_icon_120.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = linphone_icon_120.png; path = Resources/linphone_icon_120.png; sourceTree = ""; }; @@ -2956,6 +2957,7 @@ children = ( D37EE160160377D7003608A6 /* DTActionSheet.h */, D37EE161160377D7003608A6 /* DTActionSheet.m */, + F0642EF719DAF32E009DB336 /* DTWeakSupport.h */, ); name = DTFoundation; path = Utils/DTFoundation;