0

空の星と塗りつぶされた星でお気に入りを表示するために、tableviewcontrollerに次のメソッドを実装しました。

-(IBAction) tapped:(UIButton *)sender
{
    if([sender isSelected])
    {
        //...
        [sender setImage:[UIImage imageNamed:@"fav-empty.png"] forState:UIControlStateNormal];
        [sender setSelected:NO];
    }
    else 
    {
        //... 
        [sender setImage:[UIImage imageNamed:@"fav-filled.png"] forState:UIControlStateNormal];
        [sender setSelected:YES];
        NSLog(@"%@",sender);
    }

}

そして私はこの部分で使用しようとしました:

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

        UILabel *recept_neve=[[UILabel alloc] initWithFrame:CGRectMake(10, 10, 100, 40)];
        [recept_neve setTag:1];
        UIButton *kedvenc_btn=[UIButton buttonWithType:UIButtonTypeCustom];
        [kedvenc_btn setImage:[UIImage imageNamed:@"fav-empty.png"] forState:UIControlStateNormal];//default appereance on the startup
        kedvenc_btn.frame=CGRectMake(200, 20, 50, 50);
        [kedvenc_btn setTag:2];
        [kedvenc_btn addTarget:self action:@selector(tapped:) forControlEvents:UIControlEventTouchUpInside];
        [[cell contentView] addSubview:recept_neve];
        [[cell contentView] addSubview:kedvenc_btn];

        //[(UILabel*) [[cell contentView] viewWithTag:1] setText:[receptek objectAtIndex:indexPath.section*blokk+1]];
        //[(UIButton *) [cell contentView] viewWithTag:2];



    }
    // Configure the cell...
    cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
    [(UILabel*) [[cell contentView] viewWithTag:1] setText:[receptek objectAtIndex:indexPath.section*blokk+1]];

    return cell;

}

私の問題は、セルの5つおきのボタンが同じように機能していることです。最初のセルのボタン(空の星)をタップすると、結果は次のようになります。最初のボタンは塗りつぶされた星になりますが、これまでのところ良好(期待される動作)ですが、同時に6番目の星が塗りつぶされていますそれも。または、2番目の星をタップすると、7番目の星がいっぱいになり、その逆も同様です...

タップしたボタンをログに記録しましたが、上記のボタンの場合、メモリアドレスは同じであることがわかりました。私の英語について申し訳ありません、そして事前にすべての助けに感謝します!

4

1 に答える 1

1

問題は、ボタンを常に再利用していたことです。

カスタマイズされた UITableViewCell を正しく構造化するためのサンプルの作業コードを示します... ステップごとにやってみましょう。

MyObjTableViewCellForSelection という新しいクラスを作成し、これらのメソッドを提供します。あなたのニーズに合わせてください!

@class MyObj;

@interface MyObjTableViewCellForSelection : UITableViewCell
{
    MyObj *myObj;
    UIImageView *imageView;
    UILabel *titleLabel;

}

@property (nonatomic,strong) MyObj *myObj;
@property (nonatomic,strong) UIImageView *imageView;
@property (nonatomic,strong) UILabel *titleLabel;

@end

次に、実装:

    @implementation MyObjTableViewCellForSelection
    @synthesize myObj;
    @synthesize imageView;
    @synthesize titleLabel;


    - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
    {
        self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
        if (self) {

            imageView = [[UIImageView alloc] initWithFrame: CGRectZero];
            imageView.contentMode = UIViewContentModeScaleAspectFit;
            [self.contentView addSubview: imageView];

            titleLabel = [[UILabel alloc] initWithFrame: CGRectZero];
            [titleLabel setFont:[UIFont systemFontOfSize:14.0]];
            [titleLabel setTextColor:[UIColor blackColor]];
            [titleLabel setHighlightedTextColor:[UIColor darkGrayColor]];
            [titleLabel setLineBreakMode: UILineBreakModeWordWrap];
            titleLabel.numberOfLines = 2;

            [self.contentView addSubview: titleLabel];

        }
        return self;
    }

    -(void) layoutSubviews {
        [super layoutSubviews];
        [imageView setFrame:CGRectMake(8.0, 10.0, 20.0, 20.0)];
        [titleLabel setFrame:CGRectMake(40.0, 1.0, 250.0, 40.0)]; //two lines

    }

    - (void)setMyObj:(MyObj *)myObjX {
        if (myObjX != myObj) {
            [myObj release];
            [myObjX retain];
            //myObj = myObjX; //only with ARC on
        }

       titleLabel.text = whatever you need accessing myObj
    }

    - (void)setSelected:(BOOL)selected animated:(BOOL)animated
    {
      //  selection has to be adapted to your structure
        [super setSelected:selected animated:animated];
        switch (myObj.selectedFlag) {
            case MYOBJ_STATUS_UNSELECTED:
                imageView.image =  [UIImage imageNamed:@"EmptyBullet.png"];
                 break;
            case MYOBJ_STATUS_SELECTED:
                imageView.image =  [UIImage imageNamed:@"GreyBullet.png"];
                break;


            default:
                break;
        }

@end

ビュークラスで、最終的にできるようになりました:

- (MyObj *)myObjForIndexPath:(NSIndexPath *)indexPath {
     MyObj* tmpObj = get the corresponding object
     return tmpObj;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    MyObjTableViewCellForSelection *cell = (MyObjTableViewCellForSelection *)[tableView dequeueReusableCellWithIdentifier:@"cellID"];
    if (cell ==  Nil) {
        cell = [[ECUTableViewCellForSelection alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cellID"];
    }
    cell.myObj = [self myObjForIndexPath:indexPath]; //the assignment calls setMyObj of CLASS ECUTableViewCellForSelection that you just declared

    return cell;
}

最後に、それはそれを行うためのクリーンな方法です...

于 2011-09-28T06:57:17.267 に答える