#ios #uitableview #architecture
#iOS #uitableview #архитектура
Вопрос:
Когда дело доходит до написания таблицы для представления и организации области настроек приложения, я всегда чувствую себя немного «сбитым с толку». Я думаю, что лучшим способом было бы использовать статическую таблицу, но мне очень сложно ее настроить (особенно потому, что я не могу настроить сгруппированную ячейку просмотра).
Поэтому я часто получаю общую таблицу с источником данных. Мои сомнения связаны с ячейками, в которых должна непосредственно отображаться информация о параметрах.
Допустим, мне нужно 2 вида ячеек.
- Ячейка, в которой отображается переключатель
- Ячейка, в которой отображается текущее значение параметра
По сути, мои сомнения:
- Каков наилучший способ настройки ячеек? Должен ли я создать один подкласс и просто показывать или скрывать метку или переключатель во время
cellForItemAtIndex
процесса? - Какой наилучший способ взаимодействия с ячейками? Когда пользователь изменяет значение переключателя… как я могу установить ссылку на этот переключатель и нужную ячейку, содержащую его?
- Как насчет источника данных? на данный момент я реализую переключатель и в зависимости от требуемого индекса настраиваю ячейку
Не могли бы вы любезно поделиться некоторыми мыслями / примерами кода о том, как вы реализуете свои настройки?
Комментарии:
1. Минус ответ в виде небольшого совета: чтобы идентифицировать ячейку, вы можете установить тег имени для слоя ячейки в cellForRowAtIndexPath: cell. layer.name = @»Ваш идентификатор». Позже прочитайте это в didSelectRow и действуйте соответственно.
Ответ №1:
Этот ответ основан на том, что я сделал в своих собственных приложениях.
- Я бы не стал подклассом UITableViewCell, если бы не хотел сделать что-то «действительно» пользовательское. Я бы просто использовал стандартную UITableViewCell, создал элемент управления UISwitch или метку, в зависимости от того, что вы хотите показать, и добавил его в качестве аксессуара ячейки. Например:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString * cellIdentifier = @"Cell"; UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (!cell) cell = [[TSOptionCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; if (indexPath.row == 0) /* or whatever index you want to set the switch or label at */ { UISwitch * switch = [[UISwitch alloc] initWithFrame:frame]; [switch addTarget:self action:@selector(toggleSwitch:) forControlEvents:(UIControlEventValueChanged | UIControlEventTouchDragInside)]; /* create your switch and add it's target and action (method that's called when it is toggled) */ // Set the value of the switch switch = [[NSUserDefaults standardUserDefaults] boolForKey:@"key"]; [cell setAccessoryView:switch]; } }
- Метод, который вы добавили в качестве «действия» для переключателя выше, вызывается, когда пользователь взаимодействует с переключателем. Например, где-то внизу в вашем коде у вас будет это:
-(void)toggleSwitch:(id)sender { /* handle user interaction somehow */ }
- Это то, что я сейчас делаю со своим приложением в app Store. Я использую оператор switch для проверки indexPath.row по индексу того, где я хочу, чтобы переключатель отображался, поэтому я думаю, что это уместно.
Комментарии:
1. О коммутаторе: у вас должно быть много ячеек с переключателем, а не только один. Поэтому, когда вызывается cellForItemAtIndexPath, вы должны соответствующим образом установить текущее состояние коммутатора с некоторым временно сохраненным значением (это то, что я делаю прямо сейчас… но это звучит как обходной путь)
2. @MatterGoal Правильно. В настоящее время это то, что я делаю. При первом запуске приложения я устанавливаю значение по умолчанию для своих переключателей и других настроек в NSUserDefaults. Поэтому я делаю что-то вроде этого switch = [[NSUserDefaults standardUserDefaults] boolForKey:@»timerEnabled»];
Ответ №2:
Другой способ — создать две ячейки прототипа в раскадровке с разными идентификаторами, а в
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
вы должны использовать каждую ячейку по нужному вам индексу.
О второй проблеме в cellForRowAtIndexPath вы должны сохранить текущее состояние коммутатора в NSMutableArray.
вы устанавливаете тег для каждой ячейки и в
- (void)toggleSwitch:(id)sender {
NSInteger currentIndex;
currentIndex = [sender superview].tag;
[yourMutableArray replaceObjectAtIndex:currentIndex withObject:![NSNumber numberWithBool:[yourMutableArray objectAtIndex:currentIndex]BoolValue];
}
конечно, в вашем cellForRow вы устанавливаете значение массива, например:
[yourMutableArray insertObject:[NSNumber numberWithBool:[mySwitch isOn] atIndex:indexPath.row];
Надеюсь, это то, что вы искали