UISwitch внутри пользовательского UITableViewCell недоступен - PullRequest
10 голосов
/ 24 августа 2009

У меня есть UISwitch внутри пользовательского UITableViewCell (подкласс которого я называю RootLabeledSwitchTableCell).

Ячейка содержит UILabel и UISwitch рядом друг с другом.

У меня есть @property с именем keychainSwitch, который указывает на переключатель внутри этой пользовательской ячейки:

@interface RootLabeledSwitchTableCell : UITableViewCell {
    IBOutlet UILabel *textLabel;
    IBOutlet UISwitch *labeledSwitch;
}

@property (nonatomic, retain) IBOutlet UILabel *textLabel;
@property (nonatomic, retain) IBOutlet UISwitch *labeledSwitch;

@end

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

- (UITableViewCell *) tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
   NSString *CellIdentifier = [NSString stringWithFormat: @"%d:%d", [indexPath indexAtPosition:0], [indexPath indexAtPosition:1]];
   UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:CellIdentifier];
   if (cell == nil) {
       switch (indexPath.section) {
       case(kMyFirstSection): {
           switch (indexPath.row) {
               case(kMyFirstSectionFirstRow) {
                   [cellOwner loadMyNibFile:@"RootLabeledSwitchTableCell"];
                   cell = (RootLabeledSwitchTableCell *)cellOwner.cell;
                   self.keychainSwitch = [(RootLabeledSwitchTableCell *)cell labeledSwitch];
                   [self.keychainSwitch addTarget:self action:@selector(keychainOptionSwitched) forControlEvents:UIControlEventValueChanged];
                   break;
               }
               // ...
           }
       }
       // ...
   }
}

Так что этот селектор работает правильно:

- (void) keychainOptionSwitched {
   NSLog(@"Switched keychain option from %d to %d", ![self.keychainSwitch isOn], [self.keychainSwitch isOn]);
}

Однако я не могу использовать метод -setOn:animated: экземпляра UISwitch для инициализации его начального состояния:

- (void) updateInterfaceState {
   BOOL isFirstTimeRun = [[[NSUserDefaults standardUserDefaults] objectForKey:kIsFirstTimeRunKey] boolValue];
   if (isFirstTimeRun) {
      [self.keychainSwitch setOn:NO animated:NO];
   }
}

Из тестирования self.keychainSwitch - это nil, что заставляет -setOn:animated ничего не делать, но я все еще могу управлять коммутатором, и оператор NSLog правильно напечатает изменения состояния коммутатора, например:

[Session started at 2009-08-24 07:04:56 -0700.]
2009-08-24 07:04:58.489 MyApp[29868:20b] keychain switch is: nil
2009-08-24 07:05:00.641 MyApp[29868:20b] Switched keychain option from 1 to 0
2009-08-24 07:05:01.536 MyApp[29868:20b] Switched keychain option from 0 to 1
2009-08-24 07:05:02.928 MyApp[29868:20b] Switched keychain option from 1 to 0

Что-то мне не хватает в настройке self.keychainSwitch в методе делегата UITableView?

Ответы [ 3 ]

70 голосов
/ 24 августа 2009

Я целую вечность возился с пользовательскими UITableViewCells с простой меткой и включал их, прежде чем обнаружил, что могу просто добавить UISwitch в качестве дополнительного представления . В любом случае вы, вероятно, знаете об этом и хотите использовать пользовательскую ячейку по другим причинам, но на всякий случай я хотел бы упомянуть об этом!

Это делается следующим образом (в методе -tableView: cellForRowAtIndexPath):

UISwitch *mySwitch = [[[UISwitch alloc] initWithFrame:CGRectZero] autorelease];
cell.accessoryView = mySwitch;

Бит accessoryView также заботится о размерах и позиционировании, поэтому мы можем обойтись без CGRectZero.

Затем вы можете использовать системное управляющее событие и метод setOn следующим образом (обратите внимание, что мы приводим его как указатель UISwitch, который мы знаем):

[(UISwitch *)cell.accessoryView setOn:YES];   // Or NO, obviously!
[(UISwitch *)cell.accessoryView addTarget:self action:@selector(mySelector)
     forControlEvents:UIControlEventValueChanged];

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

5 голосов
/ 28 августа 2009

Я сделал это некоторое время назад. Вы должны изменить свой продавец

[self.keychainSwitch addTarget:self action:@selector(keychainOptionSwitched:) forControlEvents:UIControlEventValueChanged];

А затем обновите свой метод до

-(void) keychainOptionSwitched:(id)sender {
UISwitch *tempSwitch = (UISwitch *)sender;
}

Теперь tempSwitch - это переключатель, который был изменен.

0 голосов
/ 24 августа 2009

Я думаю, что здесь происходит то, что вы пытаетесь вызвать операцию, когда ячейка не видна, поэтому происходит то, что ячейка выгружается в это время, поэтому вы получаете ноль за переключение цепочки для ключей, один раз он появляется, тогда его больше нет ноль с момента его перезагрузки. Но я вижу, что вы назначаете переключатель следующим образом

 self.keychainSwitch = [(RootLabeledSwitchTableCell *)cell labeledSwitch];

Это ссылка на переключатель в ячейке таблицы, и вы не сохраняете его, поэтому он делает это, поскольку переключатель становится равным нулю, поскольку, когда ячейка выходит из поля зрения, выгружается и в результате keychainSwitch становится равным нулю поэтому ваш ученик также становится нулевым. Возможно, вы захотите сохранить keychainSwitch, а затем при восстановлении таблицы можете отключить keychainSwitch или что-то в этом роде. Надеюсь, это поможет

...