我有一个自定义的表视图单元格,用于加载缩略图,文本和文本的背景图像。我正在开发一个聊天应用程序,Cell正在发送/接收消息屏幕中。该单元基本上显示发送/接收。以下是有关项目和问题的更多详细信息。
然而,当我尝试发送/接收多行消息时,有时背景图像丢失,有时文本丢失(对于某些图像),当我滚动时,这些图像/文本会出现一些。
我每次都使用 [UIImage imagedNamed:] 加载背景图片。
在我看来,问题是由于记忆,因为大约6-8个细胞一直可见。请帮助我解决问题。
添加一些代码
-(UITableViewCell *)tableView:(UITableView *)tblView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCell *cell = [tblView dequeueReusableCellWithIdentifier:@"myCell"];
//Setting background image view of cell
[cell.bgImageView setImage:[[UIImage imageNamed:@"chat_box2.png"] stretchableImageWithLeftCapWidth:0 topCapHeight:40]];
String message = ........;
CGSize textSize = CGSizeMake(250, 1000);
CGSize size = [message sizeWithFont:[UIFont systemFontOfSize:12] constrainedToSize:textSize];
size.width += 9;
[cell.messageText setText:message];
[cell.messageText sizeToFit];
[cell.messageText setText:message];
//Setting frames of background Image View and message Text to our desired frame (**size** is calculated in the above lines)
[cell.bgImageView setFrame:CGRectMake(79,5, cell.bgImageView.frame.size.width, size.height+18)];
[cell.messageText setFrame:CGRectMake(98, 13, size.width, size.height)];
return cell;
}
注意:大小计算也在 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 中完成,以便调整单元格大小相应
答案 0 :(得分:0)
是的,问题是由于细胞可重用性。当您deque
Tableviewcells时,当系统尝试重新使用旧的tableviewCells时,内容将变为混合。您应该做的是在cellForRowAtIndexPath
委托中将您的单元格的所有值设置为:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//All Initialization code
.
.
.
//Set all the values of your Custom Table View Cell here
cell.image = yourImage;
cell.text = "your text";
cell.backGroundImage = yourBackGroundImage;
cell.TimeLabel.Text = "time value";
}
希望这应该有所帮助。如果您有进一步的疑问,可以随意询问。
答案 1 :(得分:0)
尝试在-tableView: cellForRowAtIndexPath:
委托方法中设置MyCell内的图像,文本和所有内容。
我可以看到你把自己标记为已解决。如果它工作得那么好。但是有一些事情你应该肯定改进和改变。有我的建议。
我认为你不必在initWithCoder:
中做任何事情。您可以留下故事板来处理。以下是我认为你应该做的代码:
<强> MyCell.h 强>
// define enum for type of cell
typedef NS_ENUM(NSInteger, MyCellType) {
MyCellTypeSender,
MyCellTypeReceiver
};
@interface MyCell : UITableViewCell
@property (nonatomic, assign) MyCellType cellType;
@property (nonatomic, strong) NSString *message;
- (void)fitToSize:(CGSize)size;
@end
<强> MyCell.m 强>
@implementation MyCell
// As you can see image is implemented inside the cell in setter of cellType
-(void)setCellType:(MyCellType)cellType {
if (_cellType != cellType) {
_cellType = cellType;
UIImage *bgImage = [UIImage imageNamed:(cellType == MyCellTypeReceiver) ? @"receiverImg" : @"senderImg"];
self.bgImageView.image = [bgImage stretchableImageWithLeftCapWidth:11 topCapHeight:23];
}
}
-(void)setMessage:(NSString *)message {
if (![message isEqualToString:_message]) {
_message = message;
self.messageLabel.text = _message;
}
}
-(void)fitToSize:(CGSize)size {
self.messageLabel.frame = CGRectMake(98, 13, size.width, size.height);
self.bgImageView.frame = CGRectMake(79,5, size.width+32, size.height+18);
}
@end
在您的文件中,您使用以下代码实现表的委托和数据源方法:
-(CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *message = @"some message ....";
CGSize size = [self sizeForText:message];
return size.height;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:@"myCell"];
CGRect cellFrame = [tableView rectForRowAtIndexPath:indexPath]; // Do not calculate the size again. Just grab cell frame from current indexPath
[cell fitToSize:cellFrame.size]; // You set the content of the cell in MyCell by passing size of cell
cell.cellType = MyCellTypeRecever; // Or MyCellTypeSender whichever you decide
cell.message = @"some message ....";
return cell;
}
-(CGSize)sizeForText:(NSString*)str {
NSDictionary *attributes = @{NSFontAttributeName: [UIFont systemFontOfSize:18.f]};
CGSize maxSize = CGSizeMake(CELL_MESSAGE_WIDTH, 1000);
// This is the method you should use in order to calculate the container size
// Avoid using -sizeWithFont:constrainedToSize:lineBreakMode: as it is depracated in iOS7
CGRect rect = [str boundingRectWithSize:maxSize
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributes
context:NULL];
return rect.size;
}
评论了一些行。正如您所看到的,大多数重要代码都落在了UITableVieCell的MyCell子类中。
另请注意{@ 1}}已弃用并使用-sizeWithFont:constrainedToSize:lineBreakMode:
答案 2 :(得分:0)
如果正在显示单元格而图像和文本不显示,则问题与textView
的框架和imageView
的框架有关。
您可以尝试在视图中勾选剪辑子视图(尤其是imageViews)并检查是否可以解决这个问题。
无论如何,我建议您使用autolayout然后定义视图的框架。
答案 3 :(得分:0)
最后,我能够自己解决这个问题。下面是一个详细的回答,突出了问题的原因和解决方案。
为了解决这个问题,我从故事板中删除了元素,并在 -initWithCoder:中定义了它们。请注意,为Storyboard原型单元格的单元格(而不是 -initWithStyle:reuseIdentifier )调用此函数。
initWithCoder:此方法将在自定义UITableViewCell类中定义(在我的例子中,类的名称是MyCell
-(id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if(self)
{
//Settings sizes to zero as they will be changed in cellForRowAtIndexPath
_bgImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
[self.contentView addSubview:_bgImageView];
_messageText = [[UILabel alloc] initWithFrame:CGRectZero];
_messageText.backgroundColor = [UIColor clearColor];
[_messageText sizeToFit];
[_messageText setFont:[UIFont systemFontOfSize:12]];
[_messageText setNumberOfLines:0];
[self.contentView addSubview:_messageText];
}
return self;
}
heightForRowAtIndexPath *和* cellForRowAtIndexPath:也可供参考。
<强> heightForRowAtIndexPath:强>
-(CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *message = .......;
CGSize size = [self getSize:message]; //look below for getSize:
size.height += 18 + 15; //to cater for padding (top & bottom).
return height;
}
<强>的cellForRowAtIndexPath:强>
-(UITableViewCell *)tableView:(UITableView *)tblView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCell *cell = [tblView dequeueReusableCellWithIdentifier:@"msgCell"];
NSString *message = ......;
CGSize size = [self getSize:message]; //look below for getSize:
cell.messageText.text = message;
[cell.messageText setFrame:CGRectMake(98, 13, size.width, size.height)];
[cell.bgImageView setFrame:CGRectMake(79,5, CELL_MESSAGE_WIDTH+32, size.height+18)]; //write #define CELL_MESSAGE_WIDTH 200 at the top of the file (below include statements)
[cell.bgImageView setImage:[[UIImage imageNamed:@"img.png"] stretchableImageWithLeftCapWidth:11 topCapHeight:23]];
return cell;
}
<强> getMaxSize:强>
-(CGSize)getSize:(NSString*)str
{
CGSize maxSize = CGSizeMake(CELL_MESSAGE_WIDTH, 1000);
CGSize size = [str sizeWithFont:[UIFont systemFontOfSize:12] constrainedToSize:maxSize lineBreakMode:NSLineBreakByWordWrapping];
return size;
}