Ios UITableViewCell未加载某些本地图像/文本
我有一个自定义的表格视图单元格,可以加载缩略图、文本和文本的背景图像。我正在开发一个聊天应用程序,手机位于发送/接收消息屏幕中。此单元格基本上显示发送/接收的数据。下面是关于项目和问题的更多细节Ios UITableViewCell未加载某些本地图像/文本,ios,objective-c,uitableview,uiimageview,Ios,Objective C,Uitableview,Uiimageview,我有一个自定义的表格视图单元格,可以加载缩略图、文本和文本的背景图像。我正在开发一个聊天应用程序,手机位于发送/接收消息屏幕中。此单元格基本上显示发送/接收的数据。下面是关于项目和问题的更多细节 我有两张背景图片。一个用于发送方,另一个用于接收方,这些图像会根据文本大小自动调整大小 当我发送/接收小消息(1行)时,消息显示正确 但是,当我尝试发送/接收多行消息时,有时背景图像丢失,有时文本丢失(对于某些图像),当我滚动时,这些图像/文本有时会出现 我每次都使用[UIImage imagedNam
-(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:(nsindepath*)indepath中进行,以便相应地调整单元格的大小。是的,问题在于单元格的可重用性。当您
deque
Tableviewcells时,当系统尝试重新使用旧的Tableviewcells时,内容会变得混乱。您应该做的是将cellforrowatinexpath
委托中的所有单元格值设置为:
- (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";
}
希望这会有所帮助。如果您还有其他疑问,请随时询问。尝试将MyCell中的图像、文本和所有内容设置为不在
-tableView:cellForRowAtIndexPath:
委托方法中
我可以看到你把自己标记为解决了。如果成功了,那就太好了。然而,有两件事你肯定要改进和改变。这是我的建议
我认为您不必在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子类中
另外请注意,不推荐使用
-sizeWithFont:constrainedToSize:lineBreakMode:
,请使用-boundingRectWithSize:选项:属性:上下文:
如果正在显示单元格而图像和文本未显示,则问题与文本视图的框架和图像视图的框架有关
您可以尝试在视图(尤其是ImageView)中勾选“剪辑”子视图,并检查这是否成功
无论如何,我建议您使用autolayout,然后定义视图的框架。最后,我可以自己解决这个问题。下面是一个详细的响应,强调了问题的原因以及解决方案
问题原因
项目[bgImageView(UIImageView)和messageText(UILabel)]是在自定义单元格类内定义的,并连接到故事板中的单元格
无论何时,我们试图更改这些元素的框架(在故事板中定义),单元都不会更新,这是问题的根本原因李>
解决方案
为了解决这个问题,我从故事板中删除了元素,并在-initWithCoder:中定义了它们。请注意,此函数是为情节提要原型单元的单元调用的(而不是-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;
}
还提供了ROWATINDEXPATH*和*cellForRowAtIndexPath:高度以供参考
row的高度索引路径:
-(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;
}
-(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;
}
-(CGSize)getSize:(NSString*)str
{
CGSize maxSize = CGSizeMake(CELL_MESSAGE_WIDTH, 1000);
CGSize size = [str sizeWithFont:[UIFont systemFontOfSize:12] constrainedToSize:maxSize lineBreakMode:NSLineBreakByWordWrapping];
return size;
}
cellForRowAtIndexPath:
-(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;
}
-(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;
}
-(CGSize)getSize:(NSString*)str
{
CGSize maxSize = CGSizeMake(CELL_MESSAGE_WIDTH, 1000);
CGSize size = [str sizeWithFont:[UIFont systemFontOfSize:12] constrainedToSize:maxSize lineBreakMode:NSLineBreakByWordWrapping];
return size;
}
getMaxSize:
-(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;
}
-(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;
}
-(CGSize)getSize:(NSString*)str
{
CGSize maxSize = CGSizeMake(CELL_MESSAGE_WIDTH, 1000);
CGSize size = [str sizeWithFont:[UIFont systemFontOfSize:12] constrainedToSize:maxSize lineBreakMode:NSLineBreakByWordWrapping];
return size;
}
需要更多关于如何构造和填充单元格的详细信息提交代码、图像更多信息请提供有关您的问题的更多信息!@sumofighter666-代码已添加。请现在检查。@YarGnawh-代码已添加。请现在检查我正在做同样的事情。因为我使用的是故事板,所以不需要初始化。cell已退出队列,值已初始化。我现在也已在问题中添加了代码。请检查我在问题陈述中提到,有时背景图像缺失,有时文本缺失(对于某些图像),当我滚动时,这些图像/文本有时会出现。问题不在于帧(否则它们不会在滚动时出现)[cell.bgmageview setImage:[[UIImage imageNamed:@“chat_box2.png”]StretcableImageWithLeftCapWidth:0 topCapHeight:40];
在主线程上或在主线程上的后台执行(整个cellForRowAtIndexPath在主线程上执行)我知道cellForRow,但知道Stretcable的setImage函数,因为我从未使用过它。你认为Stretcable的setImage函数会导致问题吗?我们如何在单元格的初始值设定项中设置动态内容?它通常添加在tableView中:cellForRowAtIndexPath:MyCell是UITableViewCell的子类,你应该设置在MyCell对象中添加一些内容。例如,您提到您有2个背景图像-将它们设置在内部。在MyCell标识符内部创建以区分“发送者”/“接收者”,并相应地加载背景图像。此外,您的代码有重复调用[cell.messageText setText:message]
尽可能多地在MyCell内部进行操作。我仍然没有得到您想要说的内容?我需要在自定义单元格的类中移动哪条语句(以及在什么方法中)?代码示例将非常有用