4

Я пытаюсь написать вспомогательный класс, чтобы наше приложение могло поддерживать как UIAlertAction, так и UIAlertView. Однако при написании метода alertView:clickedButtonAtIndex: для UIAlertViewDelegate я столкнулся с этой проблемой: Я не вижу способа выполнить код в блоке обработчика UIAlertAction.Как я могу выполнить обработчик UIAlertAction?

Я пытаюсь сделать это, держа массив UIAlertAction с в собственности под названием handlers

@property (nonatomic, strong) NSArray *handlers; 

, а затем реализовать делегат, как, например:

- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 
{ 
    UIAlertAction *action = self.handlers[buttonIndex]; 
    if (action.enabled) 
     action.handler(action); 
} 

Однако есть нет action.handler, или, действительно, каким-либо образом я могу это увидеть, поскольку заголовок UIAlertAction имеет только:

NS_CLASS_AVAILABLE_IOS(8_0) @interface UIAlertAction : NSObject <NSCopying> 

+ (instancetype)actionWithTitle:(NSString *)title style:(UIAlertActionStyle)style handler:(void (^)(UIAlertAction *action))handler; 

@property (nonatomic, readonly) NSString *title; 
@property (nonatomic, readonly) UIAlertActionStyle style; 
@property (nonatomic, getter=isEnabled) BOOL enabled; 

@end 

Есть ли другой способ выполнить код в блоке handlerUIAlertAction?

+0

Это, возможно, не ответ, который вы ищете (который я не уверен, что это возможно в любом случае), но вы пробовали переходящую в некоторых блоках для ваших действий, а не с помощью обработчиков ? Поэтому сохраните другой источник данных для действий, которые вы хотите запустить, на основе выбранного индекса. – timgcarlson

+0

@timgcarlson, должен ли я также предоставить способ передать текст, стиль и включенность действий? –

ответ

4

После некоторых экспериментов я просто понял это. Оказывается, что блок обработчика может быть отличен как указатель на функцию, и может быть выполнен указатель функции.

Подобно

//Get the UIAlertAction 
UIAlertAction *action = self.handlers[buttonIndex]; 

//Cast the handler block into a form that we can execute 
void (^someBlock)(id obj) = [action valueForKey:@"handler"]; 

//Execute the block 
someBlock(action); 
+0

Используется ли это с использованием непубличных API? Apple не разрешит приложение в магазине, если оно есть. –

+0

Я не знаю, сможет ли Apple использовать приложение для него. Я использую его для модульных тестов (которые не встроены в двоичный файл приложения). –

+1

Если вы пытаетесь выполнить тот же блок кода как снаружи, так и внутри дескриптора, я бы реорганизовал код на отдельный метод или переместил код в блок и выполнил блок в обработчике. Вне модульного тестирования я не могу думать о причине, по которой нужно было бы выполнить обработчик UIAlertAction. –

0

Кол-во классов отлично, а?

В .h:

@interface UIAlertActionWrapper : NSObject 

@property (nonatomic, strong) void (^handler)(UIAlertAction *); 
@property (nonatomic, strong) NSString *title; 
@property (nonatomic, assign) UIAlertActionStyle style; 
@property (nonatomic, assign) BOOL enabled; 

- (id) initWithTitle: (NSString *)title style: (UIAlertActionStyle)style handler: (void (^)(UIAlertAction *))handler; 

- (UIAlertAction *) toAlertAction; 

@end 

и в .m:

- (UIAlertAction *) toAlertAction 
{ 
    UIAlertAction *action = [UIAlertAction actionWithTitle:self.title style:self.style handler:self.handler]; 
    action.enabled = self.enabled; 
    return action; 
} 

...

- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 
{ 
    UIAlertActionWrapper *action = self.helpers[buttonIndex]; 
    if (action.enabled) 
     action.handler(action.toAlertAction); 
} 

Все, что вам нужно сделать, это убедиться, что UIAlertActionWrapper s вставлены helpers вместо UIAlertAction s.

Таким образом, вы можете сделать все свойства доступными и настраиваемыми для вашего сердца, и при этом сохранить функциональность, предоставляемую исходным классом.

+0

Просьба пояснить любые нисходящие комментарии с сопроводительным комментарием, поэтому я знаю, как лучше ответить в будущем :) –