2010-08-26 4 views
0

Предостережение: я искал ответ на мой вопрос, а некоторые подошли вплотную, но я все еще что-то пропустил. Вот сценарий:UISwitch и UITableViewCell iOS4

Я хочу, чтобы создать UITableViewCell s, которые содержат UISwitch es динамически во время выполнения, на основе данных в таблице (что я могу сделать). Проблема становится подключением переключателей таким образом, что я могу получить их значение, когда это представление будет изменено (перемещено, закрыто и т. Д.). Я попытался использовать события UIControlEventValueChanged для получения уведомления, но не смог его правильно определить, потому что он сбрасывает, когда этот коммутатор подключен. Кроме того, похоже, что нет никакого способа однозначно идентифицировать коммутатор, чтобы, если все события обрабатываются одной подпрограммой (идеальной), я не могу отличить их друг от друга.

Итак ...

Если у меня есть UITableView:

@interface RootViewController : UITableViewController 
{ 
    UISwitch * autoLockSwitch; 
} 

@property (nonatomic, retain) UISwitch * autoLockSwitch; 
-(void) switchFlipState: (id) sender; 
@end 

// .m файл:

@implementation RootViewController 
// ... 


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString * CellIdentifier = @"Cell"; 
    int row   = 0; 
    NSString * label = nil; 
    TableCellDef_t * cell_def = nil; 

    row = indexPath.row; 
    cell_def = &mainMenuTableCellsDef[ row ]; 

    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) 
    { 
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 
    } 
    label = (NSString *) mainMenuTableCellsDef[indexPath.row].text; 
    [cell.textLabel setText:(NSString *) mainMenuItemStrings[ indexPath.row ]]; 
    if (cell_def->isSpecial) // call special func/method to add switch et al to cell. 
    { 
     (*cell_def->isSpecial)(cell); // add switch, button, etc. 
    } 
    else 
    { 
     [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator]; 
    } 
} 


and this is the 'special' function: 

-(void) autoLockSpecialItem :(UITableViewCell *) cell 
{ 
    autoLockSwitch = [[[UISwitch alloc] initWithFrame:CGRectZero] autorelease]; 
    [autoLockSwitch addTarget:self action:@selector(switchFlipState:) forControlEvents:UIControlEventValueChanged ]; 
    [cell addSubview:autoLockSwitch]; 
    cell.accessoryView = autoLockSwitch; 
} 

и, наконец:

-(void) switchFlipState: (id) sender 
{ 
    NSLog(@"FLIPPED"); 
} 

= ================================================= ============

Вопросы:

  1. Почему он сломается (плохой селектор), когда переключатель был использован? Я считаю, что мой код следует за всем примером кода, который я видел, но, очевидно, что-то не так.

  2. Я не могу поместить метод экземпляра в таблицу в качестве указателя функции; и это не похоже на метод класса. Если я создаю функцию C/C++, как мне получить доступ к переменным-членам класса/экземпляра? То есть, если я хочу поместить вызов autoLockSpecialItem в статическую таблицу (или разумную факсимильную связь), чтобы я мог получить переменную-член autoLockSwitch? Если я сделаю это методом класса и autoLockSwitch var a static, это будет действительным?

  3. Проще говоря: как подключить UIControlEventValueChanged к моему представлению (я попытался и не смог) и могу ли я дифференцировать во время выполнения в обработчике событий, какой переключатель изменился?

  4. Есть ли лучший способ? Я не могу поверить, что я первый человек, которому приходится решать эту проблему.

Извинения за длину, благодарность за внимание и благодарность за любую помощь.

: пн:

ответ

0

Не знаю, почему ваш метод не связан, но простой способ «дифференцироваться во время выполнения в обработчик событий, который переключатель изменилось» это взять (идентификатор) отправителю, переданному вашему обработчику событий, просмотрите таблицу и сравните отправителя с любыми переключателями, если они есть, в каждом элементе таблицы. Если это слишком медленно, хеш-таблица, связывающая отправителей с ячейками таблицы или что-то в этом роде, является возможной оптимизацией.

Если вы хотите использовать указатели функций C, вам необходимо передать объект функции, чтобы использовать его для вызова методов доступа к объекту объекта внутри функции. (Или вы можете присвоить объект глобальной переменной, если это явно одноэлементный, но это очень политически неверный ответ.)

0

Во-первых, и простой способ определить ваши разные коммутаторы будет определять их тег на основе номера строки , Когда один из переключателей задействован, вы можете получить доступ к sender.tag, чтобы получить номер строки таким образом.

Кроме того, вероятно, вы должны добавить переключатель в список содержимого ячеек, а не фактическую ячейку, [cell.contentView addSubview:autoLockSwitch]. Также необходимо установить рамку (примечание CGRectZero, какао будет игнорировать ширину и высоту, но использует координаты x, y, чтобы определить, где вы хотите переключиться в ячейке.

+0

Спасибо. Я думал, что .tag был устаревший в iOS4 - не так ли? Почему коммутатор должен быть подключен к представлению содержимого вместо ячейки? Будет ли переключатель по-прежнему прокручиваться с помощью ячейки, если бы я это сделал? –

+0

Нет, тег не оформлен, проверьте ' Ссылка на класс UIView' для свойства тега. Кроме того, проверьте документ для содержимого содержимого UITableViewCell. ContentView - это должно быть супервизор для всех компонентов ячейки. И да, коммутатор по-прежнему будет прокручиваться. – thelaws

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