Как настроить делегата в класс без использования prepareForSegue

У меня есть два класса, я хотел бы, чтобы они говорили друг с другом. Класс A содержит tableView, и когда пользователи нажимают на строку таблицы, я запускаю свой метод didSelectRowAtIndexPath. В этом методе мне нужно сообщить об этом классу B через делегата. Я знаю, как работают делегаты, но мне трудно понять, как установить делегат A без использования метода prepareForSegue.

Обычно я делаю это, когда настраиваю своего делегата

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"goToManipulator"]) {
        ManipulatorViewController *secondVC = (ManipulatorViewController *) segue.destinationViewController;
        [secondVC setDelegate:self];
    }
}

Но как я могу установить делегата без использования prepareForSegue?

заранее спасибо

ИЗМЕНИТЬ:

Вот как выглядит структура моей раскадровки. Контроллер представления «получатель» — это тот, который будет получать данные и отображать их в метке «текущее имя» в зависимости от того, что было выбрано в табличном представлении из контроллера представления «отправитель», ближайшего справа.

http://oi62.tinypic.com/2li99w1.jpg


person eagle    schedule 13.02.2014    source источник
comment
Вы имеете в виду, что не используете переход для создания нового контроллера? Как вы тогда его создаете?   -  person Wain    schedule 13.02.2014
comment
Вы хотите использовать только кодирование?   -  person Samkit Jain    schedule 13.02.2014
comment
Как вы хотите создать secondVC? Из xib, из раскадровки или программно?   -  person Valentin Shamardin    schedule 13.02.2014
comment
Я должен был объяснить это лучше, но, пожалуйста, посмотрите на редактирование, которое я сделал. И да, я считаю, что мне нужно использовать какой-то переход для создания новых контроллеров представления. :)   -  person eagle    schedule 13.02.2014
comment
@All: Что, если мой конечный VC не является классом UIViewController. Например, в моем случае это UIPageViewConroller, и я не могу использовать подготовку к Segue, поскольку он ищет пункт назначения в качестве UIViewController.   -  person Alix    schedule 12.02.2016


Ответы (4)


- (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    ManipulatorViewController *secondVC = [[ManipulatorViewController alloc] init...];
    [secondVC setDelegate:self];

    //if you use push transition in UINavigationController
    [self.navigationController pushViewController:secondVC animated:YES];

    //if you use modal transition
    [self presentViewController:secondVC animated:YES completion:nil]
}

init... означает, что инициализация зависит от архитектуры вашей программы.

ИЗМЕНИТЬ

Если вы хотите получить secondVC из раскадровки, используйте

UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    ManipulatorViewController* secondVC = [storyboard instantiateViewControllerWithIdentifier:@"secondVC"];

И не забудьте добавить идентификатор вашего viewController в раскадровку.

person Valentin Shamardin    schedule 13.02.2014
comment
Если вы не хотите использовать метод подготовки к переходу (я не знаю, почему вы этого не сделаете), вам нужно поместить VC в стек, как это делает Валентин выше. Однако обратите внимание, что вы также можете инициализировать ManipulatorViewController через раскадровку вместо alloc и init. Это единственный другой способ получить ссылку на новый контроллер представления. - person mrosales; 14.02.2014

Я понимаю ваш вариант использования следующим образом:

В Receiver вы открываете Sender. Там вы выбираете значение, и после выбора значения вы хотите сообщить получателю о новом значении.

Вы можете создать протокол на отправителе, который реализует получатель. Затем в функции, которая перехватывает выбранное значение в Sender, вы вызываете метод протокола (например, didSelectNewName() или что-то в этом роде).

Конечно, вам нужен дескриптор Получателя, который вы обычно получаете через делегата. Но независимо от того, используете ли вы переход или другой метод перехода от Получателя к Отправителю, у вас все равно будет возможность установить делегата Отправителя.

Если это не то, что вы ищете, объясните, как именно вы инициализируете отправителя и почему переход нежелателен.

person Marius Waldal    schedule 13.02.2014
comment
Пока что у меня есть протокол отправителя, и я реализовал этот протокол получателем вместе с одним требуемым методом. Я просто не могу найти способ установить делегат идентификатора отправителя делегата ‹LabelChangeTextDelegate›; со структурой раскадровки, которую я использовал. Я все еще готов использовать переход, но тогда вы могли бы сказать мне, как я могу решить эту головоломку? :) - person eagle; 13.02.2014
comment
Я вижу на вашей раскадровке, что вы связали их вместе как переход на раскадровку. Это означает, что вы можете (должны) использовать переход для перехода к отправителю. Так что я не уверен, что понимаю вашу проблему...? - person Marius Waldal; 13.02.2014

Контроллер представления B уже создан, когда нажимаются ячейки A? Если это так, и вы не используете prepareForSegue для получения идентификатора другого контроллера представления, возможно, лучше использовать NSNotification Center. В методе didSelectRowAtIndex View Controller A вы можете поместить

[[NSNotificationCenter defaultCenter] postNotificationName:@"yourNotificationName" object:nil userInfo:dictionaryWithYourData];

и он уведомит все ваше приложение о том, что строка была выбрана. Если вы заранее инициализируете словарь любой информацией, которую хотите, ее можно передать через userInfo. Затем в viewDidLoad контроллера представления B добавьте

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(yourMethod:) name:@"yourNotificationName" object:nil];

чтобы заставить его слушать уведомление. Установленный вами селектор будет принимать NSNotification в качестве параметра, поэтому вы можете получить словарь следующим образом:

- (void)yourMethod:(NSNotification *)notification
{
    NSDictionary *yourData = [notification userInfo];
}
person AndrewRodgers    schedule 14.02.2014

Вот что я делаю.

В файле .m:

@implementation ViewController{

   SecondViewController *svc;

}

А затем ниже вам нужно выполнить такое действие:

- (IBAction)goToView2:(id)sender {
    if (!svc) {
        svc = [[self storyboard] instantiateViewControllerWithIdentifier:@"View2"];
        [svc setDelegate:self];
    }
    [[self navigationController] pushViewController:svc animated:YES];
}

Просто не забудьте установить правильный идентификатор в StoryBoard для ViewController, где объявлен протокол.

person hcontreras    schedule 14.11.2015