Могу ли я использовать segues с назначенными инициализаторами контроллеров вида?

Я новичок в раскадровки, и я настроил segue от кнопки к контроллеру представления. Этот контроллер представления имеет собственный подкласс SFListViewController, который имеет назначенный инициализатор initWithList:.

Использование назначенного инициализатора - единственный способ правильно инициализировать контроллер вида. Однако при использовании segues назначенный инициализатор не будет вызываться (очевидно).

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  if ([segue.identifier isEqualToString:@"Show List"]) {
    SFListViewController *listViewController = segue.destinationViewController;
    // ????
  }
}

Как я могу сделать вызов segue назначенным инициализатором при выполнении?

Ответ 1

Насколько я знаю, это невозможно, так как инфраструктура раскадровки просто вызывает alloc и init в классе, который вы определяете в Interfacebuilder. Кроме того, атрибут segue destinationViewController доступен только для чтения, поэтому вы не можете просто заменить существующий ViewController.

Единственным способом использования Storyboarding, вероятно, будет создание класса-оболочки, который внутренне создает SFListViewController с требуемыми атрибутами, а затем выполняет функции прокси-объекта и, таким образом, распространяет методы viewDid*** и viewWill*** на завернутый класс, а также возвращая завернутый вид VC в свойство readonly view... Вы получаете идею.

Как правило, существует несколько альтернативных способов инициализации a UIViewController в таком случае:

  • Существует возможность указать "Пользовательские атрибуты времени выполнения", которые могут быть использованы для инициализации.

  • Переопределите метод prepareForSegue:, как вы пытались, в корневом ViewController и выполните "post-alloc-init-initialisation" там.

  • Если худшее наступит хуже, вы можете вернуться к IBAction, чтобы иметь возможность самостоятельно инициализировать ViewController.

Надеюсь, это поможет.

Изменить: Я могу проверить, работает ли Proxy-Approach, так как я столкнулся с аналогичной проблемой с ABPeoplePickerNavigationController, где этот подход работал хорошо. Поскольку мы установили что-то в нашей истории, обратите внимание, что вам нужно использовать awakeFromNib, чтобы выполнить первоначальную настройку (вместо некоторого метода init).

Это код для моего класса-оболочки:

#import "PeoplePickerViewControllerWrapper.h"

@implementation PeoplePickerViewControllerWrapper

@synthesize ppvc = _ppvc;  // This is the object I'm proxying (The proxyee so to speak)
@synthesize delegate = _delegate;

- (void)awakeFromNib
{
        self.ppvc = [[ABPeoplePickerNavigationController alloc] init ];
        self.ppvc.peoplePickerDelegate = self;
        self.ppvc.addressBook = ABAddressBookCreate(); 
        self.ppvc.displayedProperties = [NSArray arrayWithObject:[NSNumber numberWithInt:kABPersonPhoneProperty]];
}

#pragma mark - View lifecycle

- (void)loadView
{
    [super loadView];
    [self.ppvc loadView];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.ppvc viewDidLoad];
}

-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    [self.ppvc viewWillAppear:animated];
}

-(void)viewDidDisappear:(BOOL)animated{
    [super viewDidDisappear:animated];
    [self.ppvc viewDidDisappear:animated];
}

-(UIView *)view{
    return self.ppvc.view;
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    [self.ppvc viewDidUnload];
}