自定义 UITableViewCell imageView 在 setImage 后未更新

发布于 2024-09-24 08:50:24 字数 1411 浏览 2 评论 0原文

我有一个自定义 UITableViewCell 类,其模型对象执行要在单元格中显示的图像的异步下载。我知道我已经在 IB 中正确连接了 WidgetTVC 的插座,我知道图像数据正在从我的服务器正确返回,并且我也分配/初始化了 widget.logo UIImage。为什么我的 tableViewCell 中的图像总是空白?提前致谢。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    Widget *theWidget = [widgetArray objectAtIndex:indexPath.row];

    static NSString *CellIdentifier = @"WidgetCell";
    WidgetTVC *cell = (WidgetTVC*)[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if(cell == nil)
    {
        [[NSBundle mainBundle] loadNibNamed:@"WidgetTVC" owner:self options:nil];
        cell = self.widgetTVC;
        self.widgetTVC = nil;
    }

    [cell configureWithWidget:theWidget];

    return cell;
}

在我的 WidgetTVC 类中,我有以下方法:

- (void)configureWithWidget:(Widget*)aWidget {
    self.widget = aWidget;
    self.nameLbl.text = aWidget.name;
    [self.logoIvw setImage:aWidget.logo]; // logoIvw is the image view for the logo
}

最后 - 我有回调方法,用于异步设置 Widget 模型对象上的徽标 UIImage 属性(简化):

 (void)didReceiveImage:(ASIHTTPRequest *)request {
    // I pass a ref to the Widget's logo UIImage in the userInfo dict
    UIImage *anImage = (UIImage*)[request.userInfo objectForKey:@"image"];      
    UIImage *newImage = [UIImage imageWithData:[request responseData]];
    anImage = newImage;
 }

I've got a custom UITableViewCell class whose model object performs an asynchronous download of an image which is to be displayed in the cell. I know I've got the outlets connected properly in IB for WidgetTVC, I know that image data is being properly returned from my server, and I've alloc/init'd the widget.logo UIImage too. Why is the image always blank then in my tableViewCell? Thanks in advance.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    Widget *theWidget = [widgetArray objectAtIndex:indexPath.row];

    static NSString *CellIdentifier = @"WidgetCell";
    WidgetTVC *cell = (WidgetTVC*)[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if(cell == nil)
    {
        [[NSBundle mainBundle] loadNibNamed:@"WidgetTVC" owner:self options:nil];
        cell = self.widgetTVC;
        self.widgetTVC = nil;
    }

    [cell configureWithWidget:theWidget];

    return cell;
}

In my WidgetTVC class, I have the following method:

- (void)configureWithWidget:(Widget*)aWidget {
    self.widget = aWidget;
    self.nameLbl.text = aWidget.name;
    [self.logoIvw setImage:aWidget.logo]; // logoIvw is the image view for the logo
}

Finally- I've got the callback method that sets the logo UIImage property on the Widget model object asynchronously (simplified):

 (void)didReceiveImage:(ASIHTTPRequest *)request {
    // I pass a ref to the Widget's logo UIImage in the userInfo dict
    UIImage *anImage = (UIImage*)[request.userInfo objectForKey:@"image"];      
    UIImage *newImage = [UIImage imageWithData:[request responseData]];
    anImage = newImage;
 }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

兮子 2024-10-01 08:50:24

didReceiveImage: 中,您仅修改本地指针 anImage。您需要设置 UIImageViewimage 属性才能更新显示的内容。不要隐藏对小部件的 UIImage 的引用,而是传递对 UIImageView 的引用,并在 didReceiveImage: 中执行类似的操作

UIImageView *imageView = (UIImageView*)[request.userInfo objectForKey:@"imageView"]; 
UIImage *newImage = [UIImage imageWithData:[request responseData]];
imageView.image = newImage;

In didReceiveImage:, you're only modifying the local pointer anImage. You need to set the image property of your UIImageView in order to update what gets displayed. Instead of stashing a reference to your widget's UIImage, pass a reference to the UIImageView, and in didReceiveImage: do something like

UIImageView *imageView = (UIImageView*)[request.userInfo objectForKey:@"imageView"]; 
UIImage *newImage = [UIImage imageWithData:[request responseData]];
imageView.image = newImage;
望笑 2024-10-01 08:50:24

也许最好的解决方案是让模型对象将图像作为属性,并且显示对象通过 KVO 订阅图像属性的更改,并在图像属性发生更改时更新自身。

Perhaps the best solution would be to have your model object have the image as a property and the display object subscribe to the image property's changes through KVO and update itself whenever the image property changes.

后来的我们 2024-10-01 08:50:24

好吧-这里有一些问题。感谢 bosmacs 和 Ed Marty,你们的评论都被用来找到解决方案。

首先,我向 Widget 对象添加了一个方法来异步获取徽标:

- (void)asyncImageLoad {
    ...
    // logo is a UIImage
    [AsyncImageFetch fetchImage:&logo fromURL:url];
}

我自己的 AsyncImageFetch 类如下所示:

+ (void)fetchImage:(UIImage**)anImagePtr fromURL:(NSURL*)aUrl {     
    ASIHTTPRequest *imageRequest = [ASIHTTPRequest requestWithURL:aUrl];    
    imageRequest.userInfo = [NSDictionary dictionaryWithObject:[NSValue valueWithPointer:anImagePtr] forKey:@"imagePtr"];
    imageRequest.delegate = self;
    [imageRequest setDidFinishSelector:@selector(didReceiveImage:)];
    [imageRequest setDidFailSelector:@selector(didNotReceiveImage:)];
    [imageRequest startAsynchronous];
}

+ (void)didReceiveImage:(ASIHTTPRequest *)request {
    UIImage **anImagePtr = [(NSValue*)[request.userInfo objectForKey:@"imagePtr"] pointerValue];    
    UIImage *newImage = [[UIImage imageWithData:[request responseData]] retain];
    *anImagePtr = newImage;
}

最后,根据 Ed,我将其添加到 configureWithWidget 方法中,以帮助设置我的 WidgetTVC:

[aCoupon addObserver:self forKeyPath:@"logo" options:0 context:nil];

当观察到更改时,我更新 imageView 并调用 [self setNeedsDisplay]。就像魅力一样。有什么办法可以给你两点吗?

OK- there were a couple things wrong here. Thanks to bosmacs and Ed Marty as both of your comments were used to get to the solution.

First, I added a method to the Widget object to get the logo asynchronously:

- (void)asyncImageLoad {
    ...
    // logo is a UIImage
    [AsyncImageFetch fetchImage:&logo fromURL:url];
}

And my own AsyncImageFetch class looks like this:

+ (void)fetchImage:(UIImage**)anImagePtr fromURL:(NSURL*)aUrl {     
    ASIHTTPRequest *imageRequest = [ASIHTTPRequest requestWithURL:aUrl];    
    imageRequest.userInfo = [NSDictionary dictionaryWithObject:[NSValue valueWithPointer:anImagePtr] forKey:@"imagePtr"];
    imageRequest.delegate = self;
    [imageRequest setDidFinishSelector:@selector(didReceiveImage:)];
    [imageRequest setDidFailSelector:@selector(didNotReceiveImage:)];
    [imageRequest startAsynchronous];
}

+ (void)didReceiveImage:(ASIHTTPRequest *)request {
    UIImage **anImagePtr = [(NSValue*)[request.userInfo objectForKey:@"imagePtr"] pointerValue];    
    UIImage *newImage = [[UIImage imageWithData:[request responseData]] retain];
    *anImagePtr = newImage;
}

Finally, per Ed, I added this to the configureWithWidget method that helps set up my WidgetTVC:

[aCoupon addObserver:self forKeyPath:@"logo" options:0 context:nil];

And when a change is observed, I update the imageView and call [self setNeedsDisplay]. Works like a charm. Any way I can give you both points?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文