UISwitch внутри пользовательского UITableViewCell недоступен.
-
19-09-2019 - |
Вопрос
у меня есть 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]);
}
Однако я не могу использовать UISwitch
экземпляр -setOn:animated:
метод для инициализации его начального состояния:
- (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
делегировать метод?
Решение
Я сделал это некоторое время назад.Вам следует сменить селектор
[self.keychainSwitch addTarget:self action:@selector(keychainOptionSwitched:) forControlEvents:UIControlEventValueChanged];
А затем обновите свой метод до
-(void) keychainOptionSwitched:(id)sender {
UISwitch *tempSwitch = (UISwitch *)sender;
}
Теперь tempSwitch — это измененный переключатель.
Другие советы
Я потратил много времени, возясь с пользовательскими UITableViewCells с простой меткой и включая их, прежде чем обнаружил, что могу просто добавить UISwitch в качестве дополнительного представления.Вы, вероятно, в любом случае знаете об этом и хотите использовать пользовательскую ячейку по другим причинам, но на всякий случай я хотел упомянуть об этом!
Вы делаете это следующим образом (в методе -tableView:cellForRowAtIndexPath):
UISwitch *mySwitch = [[[UISwitch alloc] initWithFrame:CGRectZero] autorelease];
cell.accessoryView = mySwitch;
Бит аксессуарView также отвечает за размер и позиционирование, поэтому мы можем обойтись без CGRectZero.
После этого вы сможете использовать событие системного управления и метод setOn следующим образом (обратите внимание, что мы приводим его как указатель UISwitch, который, как мы знаем, это так):
[(UISwitch *)cell.accessoryView setOn:YES]; // Or NO, obviously!
[(UISwitch *)cell.accessoryView addTarget:self action:@selector(mySelector)
forControlEvents:UIControlEventValueChanged];
Надеюсь, это поможет!
Я думаю, что здесь происходит то, что вы пытаетесь вызвать операцию, когда ячейка находится вне поля зрения, поэтому происходит то, что ячейка в это время выгружается, поэтому вы получаете ноль для переключателя связки ключей, как только он входит в просмотрите, то он больше не равен нулю с момента перезагрузки.Но я вижу, что вы назначаете переключатель вот так
self.keychainSwitch = [(RootLabeledSwitchTableCell *)cell labeledSwitch];
Это ссылка на переключатель в ячейке таблицы, и вы не сохраняете его, поэтому он становится нулевым, поскольку, когда ячейка выходит из поля зрения, выгружается, и в результате keychainSwitch становится нулевым, и, следовательно, ваш класс член также становится нулевым.Возможно, вы захотите сохранить keychainSwitch, а затем при восстановлении ячейки таблицы извлечь переключатель из keychainSwitch или что-то в этом роде.Надеюсь это поможет