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];
}
これにより、上書きの問題が修正されますが(問題が発生します)、ラベルが完全にランダムな場所に繰り返し表示されます。以下は単なる例であり、他のフィールドやラベルも繰り返されます。
下の写真を参照してください。
// cell reuse
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
すでに使用されているセルが返されました。すでにUILabelサブビューがあり、その上に別のセルを追加しています。セクションにサブビューを追加します
if (cell == nil) { //cell initialization
必要に応じてサブビューを編集します後セルの初期化。たとえばタグでサブビューにアクセスできます。
毎回同じ再利用セルにラベルを追加しているため、太字になっています。 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タイプに設定することを忘れないでください。
これは少し古いスレッドです。しかし、誰かに役立つでしょう、
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;
- (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を使用して、正しく機能するようにします。
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;
}
UIView * cellViewをUITableViewCell * cellの上に置かないようにしてください。 UITableViewCellはUIViewのサブクラスであるため、必要に応じてサブビューを追加できます。ただし、UITableViewCellにはすでにラベルがあります。
[cell.textLabel setText:txt]
を使用するだけです。