web-dev-qa-db-ja.com

UITableViewセルがコンテンツを上書きするのを止める方法は?

UITableViewを使用していますが、スクロールするとテーブルビューのセルが徐々に太くなっていることに気づきました。コンテンツが上書きされているため、これを停止したいのですが、どこが間違っているのかわかりません。

UITableViewで、何らかの理由でテーブルビューのコンテンツをスクロールすると、手動で作成されたUILabelが台無しになります。

後でカスタムセルが必要になるため、手動のUILabelが必要です。

上下にスクロールすると、ラベルは次第に太くなります。それらは常にオーバーラップし、場合によっては下の行に影響を与えることさえあります(ビューポートに表示される前であっても)。

続けていくと、セルの内容がわかりにくくなります。

これは、backgroundColorがclearColorとして設定されていない場合にのみ発生します。

[cellLabel setClearsContextBeforeDrawing:YES];[self.tableView setClearsContextBeforeDrawing:YES];を試しましたが効果がありません。

cell.textLabel.textを使用すると、問題は解決したようです。

コードと画像のサンプルを次に示します。

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

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

        // Configure the cell...
        //[self configureCell:cell atIndexPath:indexPath];


        NSString *txt = @"Product";


        //cell.textLabel.text = txt;
        cell.selectionStyle = UITableViewCellSelectionStyleNone;

        UIView *cellView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, cell.frame.size.height)];

        UILabel *cellLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 120, 35)];
        [cellLabel setText:txt];
        [cellLabel setFont:[UIFont boldSystemFontOfSize:12]];
        [cellLabel setBackgroundColor:[UIColor clearColor]];

        [cellView addSubview:cellLabel];
        [cellLabel release];
        [cell.contentView addSubview:cellView];
        [cellView release];


        return cell;
    }


Image follows;


![image of uitableview][1]


  [1]: http://i.stack.imgur.com/5lNy6.png


// Edit to include context

I am using a dictionary to display the contents of the UITableViewCells.

I have attempted to do the following;

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

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

            [self configureCell:cell atIndexPath:indexPath];
        } // end if


        // Configure the cell...
        //
       // Moved to inside the cell==nil        

        return cell;
    }

-(void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{

    // Get the txt from the Dictionary/Plist... *removed due verboseness*

    UILabel *cellLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 120, 35)];
    [cellLabel setText:txt];
    [cellLabel setFont:[UIFont boldSystemFontOfSize:12]];
    [cellLabel setBackgroundColor:[UIColor clearColor]];

    [cell.contentView addSubview:cellLabel];
    [cellLabel release];
}

これにより、上書きの問題が修正されますが(問題が発生します)、ラベルが完全にランダムな場所に繰り返し表示されます。以下は単なる例であり、他のフィールドやラベルも繰り返されます。

下の写真を参照してください。

repeating labels in uitableview

11
zardon
    // cell reuse
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

すでに使用されているセルが返されました。すでにUILabelサブビューがあり、その上に別のセルを追加しています。セクションにサブビューを追加します

   if (cell == nil) { //cell initialization

必要に応じてサブビューを編集しますセル​​の初期化。たとえばタグでサブビューにアクセスできます。

17
A-Live

毎回同じ再利用セルにラベルを追加しているため、太字になっています。 dequeueReusableCellWithIdentifierを使用すると、画面にすでに表示されているセルを取得することになります。これは正しい方法ですが、すでにラベルが付けられています。ラベルは毎回セルに対して同じ位置にあり、同じ色など(動的要素はテキストのみ)であるため、これらすべてを一度だけ設定する必要があります。

私が推奨する解決策は、必要なプロパティを使用してカスタムセルを作成することです。したがって、この場合、作成します

@interfacce MyCustomCell : UITableViewCell
    @property (nonatomic) UILabel *cellLabel;
@end

プロパティUILabel * cellLabelを指定し、MyCustomCell.mのinitでラベルテキストを設定する以外に、上記のすべてのコードを実行し、セルのインスタンスをselfに置き換えます。次に例を示します。

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

    if (self)
    {
        self.cellLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 120, 35)];
        [self.cellLabel setText:txt];
        [self.cellLabel setFont:[UIFont boldSystemFontOfSize:12]];
        [self.cellLabel setBackgroundColor:[UIColor clearColor]];
    }

    return self;
}

ここで、cellForRowAtIndexPathでMyCustomCellを使用します。ここで、cell == nilかどうかを確認し、セルラベルも確認することをお勧めします。

if(cell == nil || cell.cellLabel == nil)

まったく同じ方法で初期化します。

cell = [[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

今、あなたがする必要があるのは設定されているだけです:

cell.cellLabel.text = ....;

cellForRowAtIndexPathのコードは非常にクリーンでメモリ効率が高く、バグが発生することはありません。

Interface Builderで、セルをMyCustomCellタイプに設定することを忘れないでください。

6
felbus

これは少し古いスレッドです。しかし、誰かに役立つでしょう、

viewで再利用される前に、cellに追加されたtableViewを削除できます。

このコードはそれを行います、

for (UIView* view in [cell.contentView subviews])
{
    if ([view isKindOfClass:[UILabel class]])  //Condition if that view belongs to any specific class       
    {
        [view removeFromSuperview];
    }
}

これは、セルを構成する前に追加できます。

if (!cell) {
    cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:CellIdentifier];

} 

セルのラベル値をnilにして、末尾のセルでの繰り返しを回避することもできます。

cell.textLabel.text = nil;
cell.detailTextLabel.text = nil;
cell.textLabel.font = nil;
4
ramgandhi
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 

           UITableViewCell *cell = (UITableViewCell*)[self.YourTableName dequeueReusableCellWithIdentifier:nil];        
        if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
        }


            return cell; 
        }

reusablecellIdentifier nilを使用して、正しく機能するようにします。

4

CollectionView用にこのコードを記述します。再利用可能なセルから重複を取り除くのに役立ちます。

- (void)viewDidLoad {
[super viewDidLoad];
arrImg=[[NSMutableArray alloc]initWithObjects:@"images.jpeg",@"images-2.jpeg",@"images-3.jpeg", nil];

UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setItemSize:CGSizeMake(375, 200)];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];

[self.colView setCollectionViewLayout:flowLayout];
self.colView.backgroundColor=[UIColor lightGrayColor];
self.colView.delegate=self;
self.colView.dataSource=self;

// Do any additional setup after loading the view, typically from a nib.
 }

  -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {


CollectionViewCell1 *cell=(CollectionViewCell1 *)[colView dequeueReusableCellWithReuseIdentifier:@"CollectionViewCell1" forIndexPath:indexPath];
float xAxis=0;
float maxwidth=0;


for (UIView* view in [cell.contentView subviews])
{
    if ([view isKindOfClass:[UIScrollView class]])  //Condition if that view belongs to any specific class
    {
        [view removeFromSuperview];
    }
}
if(indexPath.row==1)
{
    UIScrollView *scroll=[[UIScrollView alloc]initWithFrame:CGRectMake(0,0, colView.frame.size.width, 200)];

    scroll.delegate = self;
    [cell.contentView addSubview:scroll];

    for(int i=0;i<[arrImg count];i++)
    {

    UIImageView *img=[[UIImageView alloc]init];
    xAxis=xAxis+maxwidth;
    img.frame=CGRectMake(xAxis, 0, self.view.frame.size.width, 200);
    img.image=[UIImage imageNamed:[NSString stringWithFormat:@"%@",[arrImg objectAtIndex:i]]];
        [scroll addSubview:img];
        maxwidth=self.view.frame.size.width;
    }

   scroll.contentSize=CGSizeMake(375*3, 200);
   scroll.pagingEnabled=YES;


}
   return cell;

}
2
Anuj Kumar Rai

UIView * cellViewをUITableViewCell * cellの上に置かないようにしてください。 UITableViewCellはUIViewのサブクラスであるため、必要に応じてサブビューを追加できます。ただし、UITableViewCellにはすでにラベルがあります。

[cell.textLabel setText:txt]を使用するだけです。

0
Lolloz89