2013-07-19 2 views
0

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

У меня есть секционный стол, всего около 25 строк, разделенный на 2 секции. Существует переключатель для каждого cell.accessoryView, я пытаюсь сохранить состояние переключателя, когда он изменяется, в NSArray, но запись содержимого массива по этому индексу странно возвращает 0 в любом случае. (Массив конкретизируется как свойство (nonatomic, readwrite) в TableViewController и синтезируется)

И очевидно, когда я прокручивать таблицу вверх и вниз, все переключатели вернуться в OFF состояние по умолчанию.

Спасибо за помощь!

- (void)viewDidLoad 
{ 
[super viewDidLoad]; 
//countries dict and switch state array init.. 
self.countries = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"countries" ofType:@"plist"]]; 
NSNumber *b = [NSNumber numberWithBool:NO]; 
for (int i=0; i<210; i++) { 
    [statiSwitch addObject:b]; 
    NSLog(@"%d", [[statiSwitch objectAtIndex:i] integerValue]); 
} 

//tableview drawing.. 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
static NSString *CellIdentifier = @"CellWithSwitch";  
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

if (cell == nil) { 
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 
} 

NSString *continent = [self tableView:tableView titleForHeaderInSection:indexPath.section]; 
NSString *country = [[self.countries valueForKey:continent] objectAtIndex:indexPath.row]; 

//Simple tag calculation... 
NSInteger tagOb = indexPath.section * 100 + indexPath.row; 

UISwitch *mySwitch = [[UISwitch alloc] initWithFrame:CGRectZero]; 
[mySwitch addTarget:self action:@selector(switchChange:) forControlEvents:UIControlEventValueChanged]; 
mySwitch.tag = tagOb; 
if ([statiSwitch count] > tagOb) { 
    [mySwitch setOn:[[statiSwitch objectAtIndex:tagOb] boolValue] animated:NO]; 
    } 

cell.textLabel.text = country;  
cell.accessoryView = mySwitch; 

return cell; 
} 

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

- (void) switchChange:(UISwitch *)sender { 
NSNumber *c = [NSNumber numberWithBool:sender.on]; 
[statiSwitch replaceObjectAtIndex:sender.tag withObject:c]; 

NSLog(@"switch tag is: %i and state is: %d", sender.tag, sender.on); 
NSLog(@"switch states array value: %d", [[statiSwitch objectAtIndex:sender.tag] integerValue]); 
} 
+0

Try подклассов UITableViewCell, и хранить всю ячейку в массиве, а не только значение переключателя. Затем, когда свитки tableView вытаскивают ячейку из массива вместо dequeueing. – AMayes

+0

Итак, я должен настроить массив со всеми (предположим) 20-клеточными объектами, включая вспомогательные ключи, а затем иметь таблицу таблиц '- (UITableViewCell *): (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath' метод выводит ячейки из этого массива? – Paolo83

+0

И вы должны подклассифицировать UITableViewCell и обрабатывать действие переключателя в этом классе. Это похоже на использование класса объектов для хранения данных. – AMayes

ответ

0

Я думаю, что у вас пропущен для инициализации statiSwitch перед добавлением к нему объектов.

В viewDidLoad перед для цикла, добавьте эту строку

statiSwitch = [NSMutableArray array]; 
+0

. Я продолжаю использовать массив int .. Но вы правы @Rick, я забыл инициализировать массив в этом коде выше: 'statiSwitch' был объявлен как свойство' viewController', синтезирован и так далее, вот почему я думал, что не нужно вывести и инициализировать его снова. – Paolo83

+0

Не беспокойтесь, просто имейте это в виду. Будет много ситуаций, когда вам все равно придется использовать NSMutableArrays. Вы не всегда можете придерживаться C, если хотите изучить программирование на iOS. Приветствия. – Rick

0
  1. Настройка пользовательского класса клеток.
  2. Создайте прототип ячейки в своем раскадровке и поместите в нее переключатель.
  3. Установите ячейку прототипа в свой собственный класс и установите идентификатор повторного использования.
  4. Подключите коммутатор к IBOutlet в пользовательском классе ячеек. (также настроить @protocol и делегат, если вы хотите, чтобы ваша клетку, чтобы быть в состоянии общаться)
  5. Теперь каверзной/хака части:

В -viewDidLoad:

for (int i = 0; i < [self.cellDataArray count]; ++i) { 
      CustomCell *cell; 

    cell = [self.tableView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:nil]; 
    cell.delegate = self; 
    [self.cellsArray addObject:cell]; 
} 
  1. В вашей ячейкеForRowAtIndexPath выполните следующие действия:

    cell = self.cellsArray [indexPath.row]; // или .item при использовании collectionView

  2. Поскольку коммутатор подключен к каждой ячейке, вам нужен метод в вашем классе CustomCell, который будет делать что-то на основе коммутатора и, возможно, отправить вызов классу делегата.

+0

Спасибо большое! я попробую и дам вам знать. – Paolo83

+0

Я пробовал этот путь, все было в порядке с массивом ячеек и остальными, но у меня были предупреждения о компиляторе с линией 'cell = [self.tableView dequeueReusableCellWithReuseIdentifier: @" Cell "forIndexPath: nil];', помещая ее внутри ' -viewDidLoad: 'метод. он сказал мне, что 'tableView' не имеет идентификатора для' dequeueReusableCellWithReuseIdentifier: '. Я решил его обходным путем, используя простой массив int для хранения значений переменных. Не знаю, что он не работал с хранением значений в NSMutableArray из NSObjects. См. Мой ответ для деталей. – Paolo83

+0

Если вы изменили @ "Cell" на @ "CellWithSwitch", у вас не было бы этой проблемы. – AMayes

0

Я использовал простой int array для хранения значений переключателей, это, кажется, работает лучше, чем NSMutableArray, состоящий из объектов с switchTag и switchState свойствами, что является то, что я имел обыкновение делать раньше.

Вот код:

- (void)viewDidLoad 
{ 
    //[here goes the code to retrieve my table data from a dictionary, getting sections and rows] 

    //int array iniazialization, with zeros to have switches set at OFF at beginning 

    for (int i = 0; i < 300; i++) { 
    switchStates[i] = 0; 
     } 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 

    static NSString *CellIdentifier = @"Cella"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    if (cell == nil) { 
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 
} 

//Cell drawing.. 

NSString *continent = [self tableView:tableView titleForHeaderInSection:indexPath.section]; 
NSString *country = [[self.countries valueForKey:continent] objectAtIndex:indexPath.row]; 
cell.textLabel.text = country; 

//Calculate the tag to be assigned to the switches.. 

    switchTag = indexPath.section * 100 + indexPath.row 
    UISwitch *mySwitch = [[UISwitch alloc] initWithFrame:CGRectZero]; 
    [mySwitch addTarget:self action:@selector(switchChange:) forControlEvents:UIControlEventValueChanged]; 
    mySwitch.tag = switchTag; 
    mySwitch.on = switchStates[switchTag]; 

    cell.accessoryView = mySwitch; 

    return cell; 

} 

//switch change action.. 

- (void) switchChange:(UISwitch *)sender { 
    switchStates[sender.tag] = sender.on; 
} 

Теперь у меня есть «только», чтобы сохранить эти значения переключателя в основных данных .. видеть вас здесь для моих предстоящих вопросов :-)

Смежные вопросы