2010-07-22 3 views
1

Что является самым простым способом передачи информации между UIViews? Если у меня есть 2 автономных представления, которые нажимают и выходят из панели навигации, и я хочу, чтобы из одного UIview выполнялась некоторая логика, когда кнопка нажата на втором UIview ??Передача сообщений между двумя независимыми UIViews

Правильный способ использования делегатов? или есть простой способ с построителем интерфейса? Я знаю, что я не могу кнопку перетащить к действию, которое не на ту же точку зрения в IB

благодаря

+0

Я не понимаю вопроса. С одной стороны, вы спрашиваете, как передавать информацию между UIViews (я предполагаю, что вы действительно имеете в виду UIViewControllers, а не UIViews), а с другой стороны вы спрашиваете, как выполнять логику на одном, когда кнопка нажата на другую. Можете ли вы предоставить более подробную информацию о том, что вы пытаетесь сделать? – jlehr

ответ

0

Самый простой способ заключается в использовании делегата, INIT в secondViewController с:

UIViewController *secondVC = [[UIViewController alloc] initWithDelegate:firstVC callback:callback]; 

[firstVC.navigationController pushViewController:secondVC animated:YES]; 
+0

так из этого кода, как я могу вызвать функцию из firstVC? как я соединяю кнопки от secondVC к firstVC Мне нужно реализовать протоколы, такие как обычный делегат? – Amir

+0

Вы можете сделать протокол. Или в методе: buttonClicked :, вы вызываете, [self.delegate performSelector: @selector (callback)] – vodkhang

+0

Massive overkill. Почему бы просто не установить свойство второго контроллера представления? – jlehr

0

Вот проще всего. Готовы ли вы разобраться с тем, насколько просто это может быть на самом деле?

Следующий код демонстрирует, как разделить объект данных между двумя контроллерами зрения:

VCOne.h

@interface VCOne : UIViewController { 
    NSString *mystring; 
} 

@property (nonatomic, retain) NSString *mystring; 

@end 

VCOne.m

@implementation VCOne 

@syntheize mystring; 

-(void)viewDidLoad { 
    //you probably wouldn't do it here, but just so it has a 
    //place to live, I'm doing it in viewDidLoad... 
    VCTwo *two = [[VCTwo alloc] initWithNibName:@"VCTwoView" bundle:nil]; 
    two.mystring = self.mystring; 
    [self.navigationController pushViewController:two animated:YES]; 
    [two release]; 
} 
-(void)dealloc { 
    [mystring release]; 
    [super dealloc]; 
} 

VCTwo.h:

@interface VCTwo : UIViewController { 
    NSString *mystring; 
} 

//nb the "assign" in the following line where you're probably 
//used to seeing "retain"!! 
@property (nonatomic, assign) NSString *mystring; 

@end 

VC Два м.:

@implementation VCTwo 

@synthesize mystring; 

-(void)viewDidLoad { 
    self.mystring = @"I set this string inside VCTwo!"; 
}  

-(void)dealloc { 
    [super dealloc]; 
} 

Хорошо, так! Один контроллер представления имеет NSString, называемый * mystring, и объявляет его как @property с помощью семантики setter retain. Второй имеет NSString, называемый * mystring, и объявляет его как @property с помощью смысловой семантики assign (и, что важно, НЕ ОТПУСКАЕТ ее в -(void)dealloc. Это безопасно для памяти, хотя это зависит от предыдущего VC, не выпускающего объект далеко от текущего!).

Затем, когда первый VC создает второй экземпляр, он назначает свое поле мистификации новому полю VC. Новый VC принимает этот объект и назначает его самостоятельно @property. Теперь все, что вы делаете с этой переменной в VCTwo, также имеет значение, указанное в VCOne. Теперь они буквально используют этот указатель. Оба контроллера представления имеют ручку на одной и той же части памяти.

Почему бы не использовать retain внутри VCTwo? Поскольку метод setter, который синтезируется, когда вы говорите, retain очищает и сбрасывает переменную, когда она установлена. Они становятся отдельными объектами, и они фактически не синхронизируются. Таким образом, вы можете передавать значения между контроллерами представления, но не ссылаться.

Если у вас возникли проблемы с удалением объекта, потому что он освобождается вверх по течению (возможно, в результате предупреждений о памяти), вы всегда можете явно позвонить [mystring retain] и сохранить его. Просто убедитесь, что вы выпустили его в -(void)dealloc, если вы это сделаете.

+1

Хотя все остальное в этом примере и объяснении велик, использование семантики присваивания здесь очень не так и потенциальная ошибка crasher. Кроме того, в документах Apple предлагается использовать копию вместо сохранения для NSString (в случае, если экземпляр, переданный в, изменен.) – jlehr

+0

Это потенциальная ошибка crasher, если базовый объект будет выпущен под вами, который я адресую в последнем абзаце. И использование семантики «copy» уничтожает всю ее суть, которая заключается в совместном использовании указателя на один и тот же объект между двумя контроллерами представлений. –

1

Это именно то, для чего предназначена цепочка ответчиков. Каждый UIView и UIViewController на iPhone является подклассом UIResponder. Кроме того, UIViews и UIViewControllers автоматически добавляются в цепочку ответчиков для вас.

Цепочка ответчика - способ отправки сообщений между респондентами.Вы можете отправлять сообщения непосредственно объектам или передавать их по цепочке ответчиков. Эта функциональность автоматически реализуется на UIButton's.

Если у вас есть ссылки на VIEW2 вы можете добавить view2 в качестве цели кнопки, как так:

[button addTarget:view2 action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; 

Если у вас нет ссылки, вы можете добавить цель к кнопке, как так:

[button addTarget:nil action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; 

Установка цели в ноль означает, что действие будет Прошлым вниз ответчик цепи, пока ответчик не найдено, который реагирует на селектор buttonClicked:.

Для получения дополнительной информации см. UIControl documentation и UIResponder documentation.

1

Вы используете NSNotificationCenter для отправки сообщений любому другому классу, зарегистрировавшему интерес к этой теме. Действительно легко :)

Notification Programming Guide

0

Я использую NSUserDefaults. Вы можете сохранить указанный элемент в приложении, запустить его в следующем представлении и снова запустить его, если вернетесь к первому виду! Например ...


//Saving the file - use in the first view controller 
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; 
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:somedataobject]; 
[prefs setObject:colordata forKey:@"DataKey"] 

//Recalling the file - use in 2nd view 
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; 
NSData *objectData = [prefs objectForKey:@"DataKey"]; 
Object *someobject = [NSKeyedUnarchiver unarchiveObjectWithData:objectData]; 

Теперь это предполагает, что данные НЕ NSInteger, NSString, или логическое значение. В этом случае вы должны использовать: [prefs setInteger: forKey:]; [prefs setBool: forKey:]; для декларации и [prefs IntegerforKey:] [prefs BoolforKey:] для вызова.

Вышеупомянутый синтаксис также работает для doubles and floats.

Смежные вопросы