Обработка нескольких элементов управления UISwitch в табличном представлении без использования свойства тега - PullRequest
6 голосов
/ 01 апреля 2010

У меня есть контроллер табличного представления с несколькими элементами управления UISwitch. Я установил делегата для контроллера табличного представления с тем же действием для всех коммутаторов. Мне нужно иметь возможность определить, какой переключатель был изменен, поэтому я создаю массив строк, который содержит имя каждого переключателя. Индексы в массиве будут помещены в свойство тега каждого переключателя UIS.

Однако я готов использовать свойство тега для чего-то другого, а именно, чтобы найти правильный элемент управления в ячейке в cellForRowAtIndexPath с помощью viewWithTag! (Есть несколько вещей, которые мне нужно установить в каждой ячейке.)

Итак, я думаю, что здесь правильно? Я чувствую, что довольно ограничен в том, как точно узнать, какой UISwitch изменил свое значение, поэтому я могу сделать с ним что-то полезное.

Ответы [ 4 ]

5 голосов
/ 02 апреля 2010

Я исправил это, создав подкласс UISwitch так:

@interface NamedUISwitch : UISwitch {
NSString *name;

}

Кажется элегантным (не требуются индексные массивы), а свойство tag может делать все, что захочет.

Я читал, что вы должны быть осторожны с подклассами в Objective-C, хотя ...

1 голос
/ 26 октября 2012

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

https://gist.github.com/3958325

Вы можете использовать его так:

ZUISwitch *mySwitch = [ZUISwitch alloc] init];

[mySwitch onValueChange:^(UISwitch *uiSwitch) {
        if (uiSwitch.on) {
            // do something
        } else {
            // do something else
        }
    }];

Вы также можете использовать его из файла XIB, перетащив переключатель на свой вид, а затем изменив его класс на ZUISwitch

0 голосов
/ 29 декабря 2013

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

- (void)toggleSwitch:(id) sender
{
    // declare the switch by its type based on the sender element
    UISwitch *switchIsPressed = (UISwitch *)sender;
    // get the indexPath of the cell containing the switch
    NSIndexPath *indexPath = [self indexPathForCellContainingView:switchIsPressed];
    // look up the value of the item that is referenced by the switch - this
    // is from my datasource for the table view
    NSString *elementId = [dataSourceArray objectAtIndex:indexPath.row];
}

Затем вы хотите объявить метод, показанный выше, indexPathForCellConistingView. Это, на первый взгляд, бесполезный метод, поскольку на первый взгляд может показаться, что все, что вам нужно сделать, - это определить суперпредставление коммутатора, но есть разница между суперпредставлениями ios7 и более ранних версий, поэтому он обрабатывает все:

- (NSIndexPath *)indexPathForCellContainingView:(UIView *)view {
    while (view != nil) {
        if ([view isKindOfClass:[UITableViewCell class]]) {
            return [self.myTableView indexPathForCell:(UITableViewCell *)view];
        } else {
            view = [view superview];
        }
    }   
    return nil;
}
0 голосов
/ 01 апреля 2010

Вы близки в вашем подходе. В подобных ситуациях я создал отдельные подклассы UITableViewCell, установил тег UISwitch равным index.row пути индекса и использовал этот подкласс UITableViewCell только в определенном разделе табличного представления. Это позволяет использовать тег ячейки, чтобы однозначно определить, в какой ячейке есть событие, без ведения отдельного списка индексов (как это звучит, как вы делаете).

Поскольку тип ячейки уникален, вы можете легко получить доступ к другим элементам ячейки, создав методы / свойства в подклассе UITableViewCell.

Например:

@interface TableViewToggleCell : UITableViewCell {
    IBOutlet UILabel *toggleNameLabel;
    IBOutlet UILabel *detailedTextLabel;
    IBOutlet UISwitch *toggle;
    NSNumber *value;
    id owner;
}

@property (nonatomic, retain) UILabel *toggleNameLabel;
@property (nonatomic, retain) UILabel *detailedTextLabel;
@property (nonatomic, retain) UISwitch *toggle;
@property (nonatomic, retain) id owner;

-(void) setLable:(NSString*)aString;
-(void) setValue:(NSNumber*)aNum;
-(NSNumber*)value;
-(void) setTagOnToggle:(NSInteger)aTag;

-(IBAction)toggleValue:(id)sender;

@end

В

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // ... prior iniitalization code for creating cell is assumed
toggleCell.owner = self;
[toggleCell setLable:@"some string value"];
[toggleCell setTagOnToggle:indexPath.row];
toggleCell.owner = self;
return toggleCell;
   //...  handle cell set up for other cell types as needed
}

Владелец является делегатом ячейки и может затем использоваться для инициирования действий в вашем контроллере. Убедитесь, что вы подключили UISwitch к действию toggleValue, чтобы вы могли инициировать действия в делегате при изменении состояния UISwitch:

-(IBAction)toggleValue:(id)sender;
{
    BOOL oldValue = [value boolValue];
    [value release];
    value = [[NSNumber numberWithBool:!oldValue] retain];
    [owner performSelector:@selector(someAction:) withObject:toggle];
}

Передав UISwitch с вызовом метода, вы можете получить доступ к индексному пути для ячейки. Вы также можете обойти использование свойства tag, явно имея ivar для хранения NSIndexPath ячейки, а затем передав всю ячейку с помощью вызова метода.

...