Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UITableViewCell未加载某些本地图像/文本_Ios_Objective C_Uitableview_Uiimageview - Fatal编程技术网

Ios UITableViewCell未加载某些本地图像/文本

Ios UITableViewCell未加载某些本地图像/文本,ios,objective-c,uitableview,uiimageview,Ios,Objective C,Uitableview,Uiimageview,我有一个自定义的表格视图单元格,可以加载缩略图、文本和文本的背景图像。我正在开发一个聊天应用程序,手机位于发送/接收消息屏幕中。此单元格基本上显示发送/接收的数据。下面是关于项目和问题的更多细节 我有两张背景图片。一个用于发送方,另一个用于接收方,这些图像会根据文本大小自动调整大小 当我发送/接收小消息(1行)时,消息显示正确 但是,当我尝试发送/接收多行消息时,有时背景图像丢失,有时文本丢失(对于某些图像),当我滚动时,这些图像/文本有时会出现 我每次都使用[UIImage imagedNam

我有一个自定义的表格视图单元格,可以加载缩略图、文本和文本的背景图像。我正在开发一个聊天应用程序,手机位于发送/接收消息屏幕中。此单元格基本上显示发送/接收的数据。下面是关于项目和问题的更多细节

  • 我有两张背景图片。一个用于发送方,另一个用于接收方,这些图像会根据文本大小自动调整大小
  • 当我发送/接收小消息(1行)时,消息显示正确 但是,当我尝试发送/接收多行消息时,有时背景图像丢失,有时文本丢失(对于某些图像),当我滚动时,这些图像/文本有时会出现

    我每次都使用[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:(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内部进行操作。我仍然没有得到您想要说的内容?我需要在自定义单元格的类中移动哪条语句(以及在什么方法中)?代码示例将非常有用