Как передать переменную делегату UIAlertView?
Как передать переменную делегату UIAlertView
?
У меня есть переменная, которую я хочу использовать в делегате представления предупреждения. Он используется только в функции, которая показывает делегат UIAlertView
и UIAlertView
, поэтому я не думаю, что это должно быть свойство на контроллере. Есть ли способ привязать переменную к UIAlertView
и получить ее в делегате?
- (void) someUserCondition:(SOCode *)userCode {
if ([userCode warrentsConfirmation] > 0) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Title" message:@"Are you sure?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK",nil];
[alert setAlertViewStyle:UIAlertViewStyleDefault];
//TODO somehow store the code variable on the alert view
[alert show];
}
}
- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if ([title isEqualToString:@"OK"]){
SOCode *userCode = //TODO somehow get the code from the alert view
[self continueWithCode:code];
}
}
Ответы
Ответ 1
в .h перед интерфейсом:
extern const char MyConstantKey;
@interface ViewController...
в .m import:
import <objc/runtime.h>
в .m перед реализацией
const char MyConstantKey;
в .m реализация
-(void)viewDidAppear:(BOOL)animated{ //or wherever
NSString *aString = @"This is a string";
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Testing" message:@"test is test" delegate:self cancelButtonTitle:@"Okay" otherButtonTitles:nil];
[alert show];
[alert release];
objc_setAssociatedObject(alert, &MyConstantKey, aString, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
в .m обратном вызове alertview
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
NSString *associatedString = objc_getAssociatedObject(alertView, &MyConstantKey);
NSLog(@"associated string: %@", associatedString);
}
Ответ 2
Использовать связанные объекты. Это описано более подробно здесь: Ваши Новые Друзья: Связанные объекты Obj-C
Чтобы установить используемый вами объект:
objc_setAssociatedObject(alert, &key, userCode, OBJC_ASSOCIATION_RETAIN);
И затем, чтобы вернуть его:
SOCode *userCode = objc_getAssociatedObject(alertView, &key);
Вам также нужно добавить static char key;
, чтобы он находился в области методов моли.
Update
Я обернул это в категорию на UIAlertView
. Вы можете использовать Cocoapods для приведения его в действие:
pod 'HCViews/UIAlertViewHCContext', '~> 1.2'
Источник доступен здесь: https://github.com/hypercrypt/HCViews/blob/master/Categories/UIAlertView%2BHCContext.h
Ответ 3
Много сообщений говорят о концепциях связанных объектов (это хорошо!), но иногда вы просто хотите увидеть код. Вот чистая и быстрая категория, которую вы можете поместить в отдельный файл или над интерфейсом одного из ваших существующих файлов .m
(вы могли бы даже заменить UIAlertView
на NSObject
и эффективно добавить свойство context
к любому объект):
#import <objc/runtime.h>
@interface UIAlertView (Private)
@property (nonatomic, strong) id context;
@end
@implementation UIAlertView (Private)
@dynamic context;
-(void)setContext:(id)context {
objc_setAssociatedObject(self, @selector(context), context, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(id)context {
return objc_getAssociatedObject(self, @selector(context));
}
@end
И тогда вы сможете сделать что-то вроде:
NSObject *myObject = [NSObject new];
UIAlertView *alertView = ...
alertView.context = myObject;
ВАЖНО:
И не забудьте опустить контекст в dealloc
!!
Ответ 4
UIAlertView
является подклассом UIView
, который имеет свойство tag
, которое вы можете установить в целое число. К сожалению, если вам нужно что-то отличное от целого, чтобы идентифицировать/передавать информацию делегату, вам нужно будет установить некоторые свойства (или настроить массив с индексированием тега в нем) на самом делетете. Возможно, Advaith будет работать, но технически не поддерживается Apple.
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Title" message:@"Are you sure?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK",nil];
[alert setAlertViewStyle:UIAlertViewStyleDefault];
alert.tag = SOMEINTEGER;
[alert show];
Ответ 5
Я подозреваю, что наиболее прямой путь - это свойство в классе делегата представления предупреждений. В представлении предупреждения нет каких-либо положений для "пользовательской информации" и не поддерживает подкласс, который удаляет только ярлыки, которые приходят на ум.
Ответ 6
Подкласс UIAlertView, добавьте свойство userInfo с типом вашего выбора. Задайте значение информации о пользователе во время создания экземпляра подкласса UIAlertView и извлеките его из метода делегата. (Там вы получите экземпляр подкласса, который содержит userInfo)