Создание UITableView для настроек.

#ios #uitableview #architecture

#iOS #uitableview #архитектура

Вопрос:

Когда дело доходит до написания таблицы для представления и организации области настроек приложения, я всегда чувствую себя немного «сбитым с толку». Я думаю, что лучшим способом было бы использовать статическую таблицу, но мне очень сложно ее настроить (особенно потому, что я не могу настроить сгруппированную ячейку просмотра).

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

Допустим, мне нужно 2 вида ячеек.

  1. Ячейка, в которой отображается переключатель
  2. Ячейка, в которой отображается текущее значение параметра

введите описание изображения здесь

По сути, мои сомнения:

  1. Каков наилучший способ настройки ячеек? Должен ли я создать один подкласс и просто показывать или скрывать метку или переключатель во время cellForItemAtIndex процесса?
  2. Какой наилучший способ взаимодействия с ячейками? Когда пользователь изменяет значение переключателя… как я могу установить ссылку на этот переключатель и нужную ячейку, содержащую его?
  3. Как насчет источника данных? на данный момент я реализую переключатель и в зависимости от требуемого индекса настраиваю ячейку

Не могли бы вы любезно поделиться некоторыми мыслями / примерами кода о том, как вы реализуете свои настройки?

Комментарии:

1. Минус ответ в виде небольшого совета: чтобы идентифицировать ячейку, вы можете установить тег имени для слоя ячейки в cellForRowAtIndexPath: cell. layer.name = @»Ваш идентификатор». Позже прочитайте это в didSelectRow и действуйте соответственно.

Ответ №1:

Этот ответ основан на том, что я сделал в своих собственных приложениях.

  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];
        }
    }
     
  2. Метод, который вы добавили в качестве «действия» для переключателя выше, вызывается, когда пользователь взаимодействует с переключателем. Например, где-то внизу в вашем коде у вас будет это:
     -(void)toggleSwitch:(id)sender
     {
         /* handle user interaction somehow */
     }
     
  3. Это то, что я сейчас делаю со своим приложением в 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];
 

Надеюсь, это то, что вы искали