2012-01-01 2 views
7

Во-первых, немного фона. Я новичок в разработке iOS, я давно нахожусь в сети .Net, и, наверное, поэтому я даже задаю этот вопрос, но здесь.Передача данных с одного контроллера вида на другой; iOS <= 4 против iOS 5

Основная настройка - это. У вас есть UINavigationController с RootViewController, мы позвоним MasterViewController. Когда на этом MasterViewController происходят какие-то действия, мы хотим просверлить DetailsViewController. Однако мы также хотим передать некоторые данные в DetailsViewController.

Это мое понимание, что в предыдущих версиях SDK (до прошивки 5) подход был похож на это:

@implementation MasterViewController 

    -(IBAction)someAction 
    { 
     DetailsViewController *dvc = [[DetailsViewController alloc]initWithNibName:@"DetailsView" bundle:nil]; 
     dvc.someDataProp = [self getSomeDataSomeHow]; 
     [[self navigationController] pushViewController:dvc animated:YES]; 
    } 

@end 

Теперь, однако, в прошивке 5, кажется, что теперь это делается используя раскадровку и сеги. В XCode настройке SEGUE от MasterViewController к DetailsViewController, а затем в коде вы делаете что-то вроде этого:

-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    [segue.destinationViewController setSomeDataProp:[self getSomeDataSomeHow]]; 
} 

Мой вопрос заключается в основном это: Старшее подход как-то чувствует себя намного чище меня. Вы очень четко указываете тип ViewController, который вы нажимаете на стек навигации, и вы можете легко установить на него свойства. В новом подходе, однако, destinationViewController имеет тип id (по понятным причинам), и он просто чувствует себя намного менее чистым для меня. Опять же, это может быть моя .Net сторона выходит, но это распространено в iOS? Просто используйте id и будьте осторожны с ветром?

+1

Большое уважение к вопросу о том, как это делается, а не просто копировать и вставлять фрагменты. У меня также были схожие вопросы, и с некоторым опытом здесь есть мой ответ: с iOS5 я вижу, что логика пользовательского интерфейса была разделена на две части: 1) жизненный цикл ViewController и переходы 2) поток данных.Раскадровка заботится о 1, и разработчики, как ожидается, позаботятся о них. В таком сценарии эти броски будут происходить. Для меня вопрос в том, имеет ли этот раскол смысл? Могут ли эти две концепции быть развязаны? Я думаю, что Apple идет именно так, и мы увидим, как это работает. – Guven

ответ

6

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

И в методе prepareForSegue вы должны проверить этот Идентификатор, и, таким образом, вы явно узнаете, какой сеанс будет выполнен, и какой будет destinationViewController.

if ([segue.identifier isEqualToString:@"My First Segue Identifier"]) 
{  
    DetailsViewController *dvc = (DetailsViewController *) segue.destinationViewController; 
    // Set the DVC's properties 
} 
+0

Лучше, но у вас все еще есть такой уродливый бросок. Это предпочтительный подход? – BFree

+0

Это предпочтительный подход. Вы правы, старый путь более ясен и более ясен. С помощью нового метода вы «подключаетесь» к раскадровке. К сожалению, есть новые функции, найденные только в раскадровках, которые не попали в конструктор XIB, например, новая статическая и динамическая поддержка дизайнера UITableView. –

+1

- этот фрагмент кода, вставленный в метод 'prepareForSegue'? – chwi

4

Во многих случаях контроллер вид назначения для Segue может быть UINavigationViewController, и в этом случае решение (небольшая модификация решения Денниса Mathews' выше) нужно будет использовать сообщение „topViewController“ :

if ([segue.identifier isEqualToString:@"My First Segue Identifier"]) 
{  
    NavitationViewController* navController = [segue destinationViewController]; 
    DetailsViewController *dvc = (DetailsViewController*) [navController topViewController] 
    // Set the DVC's properties 
} 
+0

Это сделало трюк для меня, за исключением того, что, я думаю, вы имеете в виду «UINavigationController * navController», а не «NavitationViewController * navController». – mpemburn

1

Я не работал с прошивкой, что долго, но я видел несколько примеров, где вы не должны бросать из-за свободно связанной системы обмена сообщениями Objective-C в.

Вместо проверки идентификатора SEGUE или приведение к конкретному ViewController вы можете сделать это:

-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    if ([segue.destinationViewController respondsToSelector: @selector(setCompany:)]) { 
     [segue.destinationViewController performSelector: @selector(setCompany:) withObject: self.company]; 
    } 
} 

В первой строке я спрашиваю, если destinationViewController имеет метод setCompany (если у вас есть свойство с именем компании это один будет создан для вас). Если это так, вы можете вызвать этот метод/установить это свойство со второй строкой кода.

Так что в этом случае вам не нужно знать конечный ViewController и легко заменить его другим, который поддерживает обработку компаний.

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