Подтвердить что ты не робот

Как добавить userInfo в UIAlertView?

Я хотел бы знать, как добавить объект userInfo или любой NSDictionary в UIAlertView?

Спасибо.

4b9b3361

Ответ 1

Если вы находитесь нa > iOS 4.0 (для блоков), и вам нужна только одна или две кнопки, вы можете использовать эту категорию, которую я сделал:

https://github.com/rsaunders100/UIAlertView-Blocks

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

 #import UIAlertView+Blocks.h

 ...

 ...

 NSString* myUserInfo = @"example";

 [UIAlertView displayAlertWithTitle:@"Example Alert View With Blocks"
                            message:nil
                    leftButtonTitle:@"Ok"
                  leftButtonAction:^{
                                      NSLog(@"%@", myUserInfo);
                                    } 
                  rightButtonTitle:nil
                 rightButtonAction:nil];

Ответ 2

Вы можете попробовать подклассифицировать UIAlertView, чтобы добавить это поле, или сохранить ссылку в своем классе делегата. Но самым общим способом привязки любого объекта к любому другому объекту является использование objc_setAssociatedObject.

Чтобы сделать это, вы должны #import <objc/runtime.h>, и вам нужен произвольный void *, который используется как ключ (обычный трюк заключается в объявлении static char fooKey; в вашем .m файле и использовании его адреса). Затем вы можете прикрепить объект следующим образом:

objc_setAssociatedObject(alertView, &fooKey, myDictionary, OBJC_ASSOCIATION_RETAIN);

В этом случае myDictionary будет сохранен для жизни alertView и будет выпущен, когда alertView будет освобожден.

Чтобы получить связанный объект позже, используйте логически названный objc_getAssociatedObject.

NSDictionary *myDictionary = objc_getAssociatedObject(alertView, &fooKey);

Он возвращает nil, если не было набора ассоциаций. Чтобы разбить ассоциацию, просто используйте objc_setAssociatedObject, чтобы связать новое значение для одного и того же объекта и ключа; nil можно использовать для разрыва ассоциации, не связывая новый объект.

Другие значения для типа ассоциации, кроме OBJC_ASSOCIATION_RETAIN, перечислены здесь.

Ответ 3

Я написал (проверенную) категорию на NSObject, которая дает каждому объекту возможность легко хранить данные.

Просто поместите код в файл заголовка и реализации и импортируйте его в любой из ваших проектов. Или положить его в статическую библиотеку. Mac OS X 10.6+ и iOS (только версия?).

#import <Foundation/Foundation.h>
#import <objc/runtime.h>

@interface NSObject (CCFoundation)

- (id)associativeObjectForKey: (NSString *)key;
- (void)setAssociativeObject: (id)object forKey: (NSString *)key;

@end

#pragma mark -

@implementation NSObject (CCFoundation)

static char associativeObjectsKey;

- (id)associativeObjectForKey: (NSString *)key {
    NSMutableDictionary *dict = objc_getAssociatedObject(self, &associativeObjectsKey);
    return [dict objectForKey: key];
}

- (void)setAssociativeObject: (id)object forKey: (NSString *)key {
    NSMutableDictionary *dict = objc_getAssociatedObject(self, &associativeObjectsKey);
    if (!dict) {
        dict = [[NSMutableDictionary alloc] init];
        objc_setAssociatedObject(self, &associativeObjectsKey, dict, OBJC_ASSOCIATION_RETAIN);
    } [dict setObject: object forKey: key];
}

@end

Проще говоря, каждый объект становится простым в использовании словарем (благодаря NSMutableDictionary), как только он вам понадобится. Словарь освобождается, когда объект находится, и объекты словаря освобождаются при выпуске словаря. Удивительно, как Apple сделала это просто.

Предупреждение 1: Приведенный выше код ARC включен. Он хорошо протестирован и используется в нескольких поставляемых продуктах. Я еще не видел утечек памяти или проблем с производительностью.

Предупреждение 2: Переименуйте методы по своему усмотрению, но если вы решите сохранить имя, убедитесь, что вы добавили префикс. Это категория на корневом объекте, люди. В каком-то классе кто-то использует это имя метода, и вы не хотите вмешиваться! Моя статическая библиотека, которую я включаю в каждый проект, использует имена методов associativeCCObjectForKey: и setAssociativeCCObject:forKey:.

Надеюсь, это поможет любому, кто хочет иметь простую userInfo -подобную функцию на каждом объекте. Пожалуйста!: -)

Ответ 4

Это работает для меня, если я дам ему буквальную строку c, такую ​​как "ключ", вместо создания статического char

Вместо этого, принимая во внимание то, что говорит Аномия, вы могли бы сделать это:

objc_setAssociatedObject ( alert , (const void*)0x314 , notification , OBJC_ASSOCIATION_RETAIN ) ;

Это работает на все, что позволяет вам использовать произвольные void * (наблюдение, эту функцию и т.д.) и не требует дополнительных статических переменных трюков. Кроме того, (const void *) 0x314 ВСЕГДА 0x314, независимо от того, что делает компилятор.

Кроме того, Аномия, вы только что сэкономили мне много работы в приложении, над которым я сейчас работаю. Спасибо!

Ответ 5

Я придумал более простое решение, которое может поместиться в некоторых обстоятельствах. Поскольку вы получаете контекст NSAlertView при вызове делегата, я использую фактический адрес объекта для создания тега (NSString *), который затем я использую для хранения пользовательских значений в глобальном или объектном NSDictionary. Вот пример:

+(NSString*)GetTag:(id)ObjectIn
{
    return [NSString stringWithFormat:@"Tag-%i",(int)ObjectIn];
}

В делегате:

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    NSString* MyID = [CommandManager GetTag:alertView];
    [CurrentActiveAlerts removeObjectForKey:MyID];
}

Призвание:

    UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:title_text
                                                          message:@""
                                                     delegate:self
                                            cancelButtonTitle:nil
                                        otherButtonTitles:button_text ,nil];

    CurrentActiveAlerts[[CommandManager GetTag:myAlert]] = CommandToRun;  
    [myAlert show];
    [myAlert release];

Ключи будут выглядеть так: "Tag-226811776". Надеюсь, это поможет.