Apple ipad iphone UITableViewCell с UIButton: изменение изображения кнопки при нажатии кнопки? - PullRequest
0 голосов
/ 20 января 2012

Я в настоящее время разрабатываю приложение, которое содержит UITableView.UITableView содержит пользовательские ячейки.Внутри ячейки я предоставил кнопку UI, которая будет использоваться для выбора нескольких строк.В tableView В настоящее время у меня есть 30 строк, и он работает нормально, но, когда я нажимаю на кнопку в первом ряду, кнопка в 6-й, 11-й, 16-й, 21-й, 26-й строке также нажимается, и если щелкнуть по второй строке после этогощелчок следующей строки (т. е. 7-й, 12-й и т. д.).

Код выглядит следующим образом:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
        static NSString *CellIdentifier = @"Cell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil)
        {
            //
            // Create the cell.
            //
            cell =
                [[[UITableViewCell alloc]
                    initWithFrame:CGRectZero
                  reuseIdentifier:CellIdentifier]
                    autorelease];

        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        indicatorImage = [UIImage imageNamed:@"NotSelected.png"];
        indicatorHighImage = [UIImage imageNamed:@"IsSelected.png"];
        selectbtn = [UIButton buttonWithType:UIButtonTypeCustom];
        selectbtn.frame = CGRectMake(30,122,20,20);
        [selectbtn setImage:indicatorImage forState:UIControlStateNormal];
        selectbtn.tag = rowCount++;
        [cell addSubview:selectbtn];
        [selectbtn addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
     }
     return cell;
}

-(IBAction)buttonClicked:(UIButton *)button
{
        if([button isSelected])
        {
            [button setImage:indicatorImage forState:UIControlStateNormal];
            [button setSelected:NO];
        }
        else
        {


        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Custom Button Pressed" 
                                                            message:[NSString stringWithFormat: @"You pressed the custom button on cell #%i", button.tag]//pathToCell.row + 1]  
                                                           delegate:self cancelButtonTitle:@"Great" 
                                                  otherButtonTitles:nil];
        [alertView show];
        [alertView release];
        [button setImage:indicatorHighImage forState:UIControlStateNormal];
        [button setSelected:YES];
    }
return;
}

1 Ответ

2 голосов
/ 20 января 2012

Хорошо, во-первых, вы неправильно настраиваете изображения кнопок.Чтобы установить состояния кнопки для выбранных и невыбранных, вы не меняете изображение при каждом нажатии кнопки, вы просто делаете это при создании кнопки:

[button setImage:indicatorImage forState:UIControlStateNormal];
[button setImage:indicatorHighImage forState:UIControlStateSelected];

Обратите внимание на параметр forState - это позволяетВы указываете, в каком состоянии будет отображаться изображение, таким образом кнопка автоматически отобразит другое изображение, когда вы установите его выбранное свойство.В методе buttonClicked теперь вы можете просто сказать:

button.selected = !button.selected; // toggle selection state

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

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

Кроме того, некоторые извещи, которые вы делаете внутри предложения if (cell == nil) { ... } в вашем методе cellForRowAtIndexPath, необходимо перемещать за пределы оператора if, поскольку в противном случае они будут установлены только при первом создании ячейки и не будут установлены снова при повторном использовании..

, поэтому ваш метод cellForRowAtIndexPath должен выглядеть примерно так:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
        static NSString *CellIdentifier = @"Cell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

        if (cell == nil)
        {
            cell =
                [[[UITableViewCell alloc]
                    initWithFrame:CGRectZero
                  reuseIdentifier:CellIdentifier]
                    autorelease];

        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        selectbtn = [UIButton buttonWithType:UIButtonTypeCustom];
        [selectbtn setImage:[UIImage imageNamed:@"NotSelected.png"] forState:UIControlStateNormal];
        [selectbtn setImage:[UIImage imageNamed:@"IsSelected.png"] forState:UIControlStateSelected];
        selectbtn.frame = CGRectMake(30,122,20,20);
        [cell addSubview:selectbtn];
        [selectbtn addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
     }

     //get a model object from the array
     MyModelObject *object = [myBackingArray objectAtIndex:indexPath.row];

     //get the button and set its properties
     UIButton *button = [cell.subviews lastObject]; 
     button.tag = rowCountindexPath.row;
     button.selected = object.mySelectedStateProperty;

     return cell;
}

Обратите внимание, что MyModelObject, myBackingArray и object.mySelectedStateProperty являются заполнителями для нового класса, который вы создадите в качестве модели для своей ячейки.данные и массив этих объектов хранятся в вашем контроллере представления, чтобы служить постоянным местом для хранения состояний вашей ячейки.

...