0

すべてのセルに UIButton があるアプリケーションを実装しています。このボタンは特定のイベントをユーザーのお気に入りに追加し、その画像をもう一度クリックすると、そのイベントがユーザーのお気に入りから削除されます。どのセルのユーザーがそのボタンを押したかを検出し、それに応じて背景画像を変更したい。

画像の円は uiButton です これが私のコードです(私が試したものです。)

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

            }
        uncheckButton = [[UIButton alloc]init];
        appDelegate.setValue = 0;
            [uncheckButton setFrame:CGRectMake (3, 25, 30, 30)];
            [uncheckButton setImage:[UIImage imageNamed:@"unchecked.png"] forState:UIControlStateNormal];
            [uncheckButton setSelected:NO];
            [uncheckButton addTarget:self action:@selector(uncheckedButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
            [cell addSubview:uncheckButton];

        [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
            return cell;

        }
-(IBAction)uncheckedButtonClicked:(id)sender
{

    if(appDelegate.setValue ==0)
    {
        appDelegate.setValue =1;
        [uncheckButton addTarget:self action:@selector(uncheckedButtonClicked:) forControlEvents: UIControlEventTouchUpInside];
        [uncheckButton setFrame:CGRectMake(3, 25, 30, 30)];
        [uncheckButton setImage:[UIImage imageNamed:@"checked_red.png"] forState:UIControlStateNormal];


        Reachability *reachability = [Reachability reachabilityForInternetConnection] ;
        NetworkStatus netWorkStatus = [reachability currentReachabilityStatus] ;
        if (netWorkStatus == ReachableViaWWAN || netWorkStatus == ReachableViaWiFi)
        {

                [NSThread detachNewThreadSelector:@selector(threadStartAnimating:) toTarget:self withObject:nil];
                NSLog(@"%@",appDelegate.user_id);
                Communication *objCommunication = [[Communication alloc] init];
                objCommunication.delegate = self;
                [objCommunication setServiceFor:@"My_Agenda_add"];

                NSURL *url =  [NSURL URLWithString: [NSString stringWithFormat:@"%@/api/join_session",BASE_URL]];
                NSString *body = [ NSString stringWithFormat:@"user_id=%@&session_id=%@",[appDelegate.user_id objectAtIndex:0],[[self.globalSessionArray valueForKey:@"_id"]valueForKey:@"$id"]];
                [objCommunication makeAsynchronousRequestWithUrl:url withBodyString:body andWithMethod:@"POST"];objCommunication = nil;

        }

        else
        {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:app_name message:network_connectivity delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
            [alert show];
        }
    }

    else if(appDelegate.setValue)
    {
        appDelegate.setValue = 0;
        [uncheckButton addTarget:self action:@selector(uncheckedButtonClicked:) forControlEvents: UIControlEventTouchUpInside];
        [uncheckButton setFrame:CGRectMake(3, 25, 30, 30)];
        [uncheckButton setImage:[UIImage imageNamed:@"unchecked.png"] forState:UIControlStateNormal];

        Reachability *reachability = [Reachability reachabilityForInternetConnection] ;
        NetworkStatus netWorkStatus = [reachability currentReachabilityStatus] ;
        if (netWorkStatus == ReachableViaWWAN || netWorkStatus == ReachableViaWiFi)
        {
                [NSThread detachNewThreadSelector:@selector(threadStartAnimating:) toTarget:self withObject:nil];
                NSLog(@"%@",appDelegate.user_id);
                Communication *objCommunication = [[Communication alloc] init];
                objCommunication.delegate = self;
                [objCommunication setServiceFor:@"My_Agenda_remove"];
                NSURL *url =  [NSURL URLWithString: [NSString stringWithFormat:@"%@/api/unjoin_session",BASE_URL]];
                NSString *body = [ NSString stringWithFormat:@"user_id=%@&session_id=%@",[appDelegate.user_id objectAtIndex:0],[[self.globalSessionArray valueForKey:@"_id"]valueForKey:@"$id"]];
                [objCommunication makeAsynchronousRequestWithUrl:url withBodyString:body andWithMethod:@"POST"];objCommunication = nil;

        }

        else
        {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:app_name message:network_connectivity delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
            [alert show];
        }
    }



    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0] ;
    NSLog(@"%@",indexPath);

    UITableViewCell* cell = [self.agendaTableView cellForRowAtIndexPath:indexPath];
    [cell addSubview:uncheckButton];
    [self.agendaTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];

}
4

3 に答える 3

1

このコードにはいくつかの問題があります。

  1. セルが更新されるたびに新しいボタンのサブビューをセルに追加しているため、古いボタンを再利用していないため、リークが発生しています。代わりに、ボタンを初期化コードに 1 回だけ追加し、再利用されたセルを取得するときにボタンにアクセスするために使用できるタグを与える必要があります。

  2. あなたの説明に基づいて、チェックされたケースとチェックされていないケースの両方が必要ですが、1つしかないようです。cellForRowAtIndexPathこれを解決するには、モデルのステータスに基づいてボタンの画像を正しいものに設定する if/else ステートメントを含めることができます。

100分の1の答えには、ある種のモデルを使用して、ボタンがどのセルから来たかを追跡するという良い提案があります。ここでは NSMutableDictionary がうまく機能します。ボタンのスーパービューを取得して元のセルを取得することはお勧めしません。モデルをビューの外に出そうとするのは悪い習慣であり、後で問題が発生する可能性があります。

サンプルコード:

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

    UIButton *checkButton;
    static const NSInteger kCheckButtonTag = 1;
    if (cell == nil) 
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
        [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
        checkButton = [[UIButton alloc] init];
        [checkButton setFrame:CGRectMake (3, 25, 30, 30)];
        [checkButton addTarget:self action:@selector(checkedButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
        checkButton.tag = kCheckButtonTag;
        [cell.contentView addSubview:uncheckButton];
    }
    else
    {
        checkButton = (UIButton *)[cell.contentView viewWithTag:kCheckButtonTag];
    }


    if(model is unchecked) // replace with correct condition
        [checkButton setImage:[UIImage imageNamed:@"unchecked.png"] forState:UIControlStateNormal];
    else
        [checkButton setImage:CHECKED_IMAGE_GOES_HERE forState:UIControlStateNormal]; // replace with your checked image

    // assuming buttonToModelDictionary is an initialized ivar NSMutableDictionary
    buttonToModelDictionary[checkButton] = YOUR_MODEL_OBJECT_GOES_HERE;
    return cell;

}

- (void) checkButtonClicked:(id)sender
{
    (UIButton *)button = (UIButton *)sender;
    YOUR_MODEL_OBJECT_GOES_HERE = buttonToModelDictionary[button];

    // do whatever you need to update the model here, then call [self.tableView reloadData] OR [self.tableView reloadRowsAtIndexPaths...] if you can gather the row using the model object, which you should be able to do.
}
于 2013-09-25T22:11:32.037 に答える