Передача данных из одного контроллера представления в другой; iOS <= 4 против iOS 5 - PullRequest
7 голосов
/ 01 января 2012

Сначала немного фона.Я новичок в разработке для iOS, я давно нахожусь в .Net land, и, возможно, поэтому я даже задаю этот вопрос, но здесь все идет.

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

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

@implementation MasterViewController

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

@end

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

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

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

Ответы [ 3 ]

6 голосов
/ 01 января 2012

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

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

if ([segue.identifier isEqualToString:@"My First Segue Identifier"])
{    
   DetailsViewController *dvc = (DetailsViewController *) segue.destinationViewController;
   // Set the DVC's properties 
}
4 голосов
/ 11 апреля 2012

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

if ([segue.identifier isEqualToString:@"My First Segue Identifier"])
{    
   NavitationViewController* navController = [segue destinationViewController];   
   DetailsViewController *dvc = (DetailsViewController*) [navController topViewController]
   // Set the DVC's properties 
}
1 голос
/ 19 августа 2012

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...