本文介绍了reloadRowsAtIndexPaths 后自定义 UITableViewCell 外观不会改变的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 .xib 中创建了一个自定义 UITableViewCell 并将其添加到 TableView.该单元格包含一个用于下载一些数据的按钮.在按钮上单击下载开始,按钮消失以显示取消按钮和带有下载进度的自定义视图.下载完成后,我更新我的模型并重新加载应用程序可见区域中的行.

I have a custom UITableViewCell created in a .xib and add it to a TableView. The cell contains a Button to download some data. On Button click the download starts and the Button disappears to show a cancel Button and a custom View with a download progress. After the download is finished I update my model and reload the rows in the visible area of the app.

当我调试时,我看到 cellForRowAtIndexPath 方法被调用并且模型被更新.这意味着取消按钮和进度视图被设置为 hidden = YES;但它们不会消失.在我将单元格滚动出视图并返回后,进度视图被隐藏,但取消按钮没有.

When I debug, I see that the cellForRowAtIndexPath-methode get called and the model got updated. This means the cancel-Button and the progress-View get set hidden = YES; But they don't disappear. After I scroll the cell out of view and back in, the progress-View is hidden but the cancel-Button not.

TableView 方法:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath   *)indexPath{
 static NSString *cellIdentifierHeaderCell = @"PodcastListHeaderCell";
 static NSString *cellIdentifierBodyCell = @"PodcastListBodyCell";


// Convert string to date object
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"EEE, d MMM yyyy HH:mm:ss Z"];



if(indexPath.row == 0) {
    MGPodcastListHeaderCell *cell = (MGPodcastListHeaderCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifierHeaderCell];
    if (cell == nil)
    {
          ...

    }
    return cell;
}
else {
    MGPodcastListBodyCell *cell = (MGPodcastListBodyCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifierBodyCell];
    if (cell == nil) {
        UIViewController *controller = [[UIViewController alloc] initWithNibName:@"MGPodcastListBodyCell" bundle:nil];
        cell = (MGPodcastListBodyCell *)controller.view;
        NSMutableDictionary *mediaIntem = self.mediaData[(NSUInteger) (indexPath.row-1)];
        cell.mediaTitleLabel.text = mediaIntem[@"title"];
        NSDate *date = [dateFormat dateFromString:mediaIntem[@"pubDate"]];
        cell.pubDateLabel.text = [date descriptionWithLocale:[NSLocale currentLocale]];
        cell.durationLabel.text = mediaIntem [@"duration"];
        cell.accessoryType = UITableViewCellAccessoryDetailButton;
        cell.podcastId = (NSInteger) (indexPath.row-1);
        cell.cellPlayState = [[MGPlayState alloc] initWithPlayState:(NSInteger) [mediaIntem[@"playState"] integerValue]];
        [cell setPodcastCellDelegate:self];
    }
    return cell;
  }
}


-(void) downloadButtonPressedOfCell:(NSInteger)podcastId {

APConnection *con = [[APConnection alloc] init];
BOOL reachable = [con reachableHost];
if (reachable)
{


    //============Get Media Item =============================
    NSMutableDictionary *mediaDict = self.mediaData[(NSUInteger)podcastId];

    MGPlayState *pl_state = [[MGPlayState alloc] initWithPlayState:[[mediaDict objectForKey:@"playState"] integerValue]];

    NSString *urlString = [mediaDict objectForKey:@"mediaLink"];

    /// Finde Pathname
    NSString *fileName = [urlString lastPathComponent];
    NSLog(@"LastFileComponent: %@", fileName);
    NSString *pathName = [NSString stringWithFormat:@"%@/%@",
                                                    [APFilePath getMediaContentFolder],
                                                    fileName];

    /// Request und Operation
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    operation.outputStream = [NSOutputStream outputStreamToFileAtPath:pathName
                                                               append:NO];


    //// save Operation for cancle
    NSMutableDictionary *operationDict = [[NSMutableDictionary alloc] init];
    [operationDict setObject:operation
                      forKey:@"operation"];
    [operationDict setObject:[NSNumber numberWithInt:podcastId]
                      forKey:@"myIndexPath"];
    [operationDict setObject:[mediaDict objectForKey:@"mediaLink"]
                      forKey:@"mediaLink"];

    [[self operationDictArr] addObject:operationDict];

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
            {
                NSIndexPath *path = [NSIndexPath indexPathForRow:podcastId+1 inSection:0];
                MGPodcastListBodyCell *myCell = (MGPodcastListBodyCell *) [self.podcastListTable cellForRowAtIndexPath:path];

                [pl_state setToPlayState:PlayStateDefaultDownloadFinished];
                myCell.cellPlayState = pl_state;


                //============ Get mediaItem =============================
                self.mediaData[(NSUInteger)podcastId][@"playState"] = @4;


                /// remove operation from dict
                [[self operationDictArr] removeObject:operationDict];

                [self.podcastListTable reloadRowsAtIndexPaths:[self.podcastListTable indexPathsForVisibleRows]
                                 withRowAnimation:UITableViewRowAnimationNone];
                [self.podcastListTable setNeedsDisplay];
            }
                                     failure:^(AFHTTPRequestOperation *operation, NSError *error)
                                     {
                                         NSLog (@"Error downloadMovie: %@", error);
                                     }];

    [operation start];

}

else
{
    [EZToastView showToastMessage:NSLocalizedString(@"keineVerbindungKey", "")
                    withAlignment:EZToastViewAlignmentCenter];
}
}

自定义单元格:

////  MGPodcastListBodyCell.h
@protocol MGPodcastCellDelegate <NSObject>
@required
-(void) downloadButtonPressedOfCell: (NSInteger) podcastId;
-(void) cancleDownloadButtonPressedOfCell: (NSInteger) podcastId;
@end


@interface MGPodcastListBodyCell : UITableViewCell
@property (nonatomic, retain) id <MGPodcastCellDelegate> podcastCellDelegate;
@property (weak, nonatomic) IBOutlet UILabel *mediaTitleLabel;
@property (weak, nonatomic) IBOutlet UILabel *durationLabel;
@property (weak, nonatomic) IBOutlet UIButton *downloadMediaButton;
@property (weak, nonatomic) IBOutlet UIButton *cancelMediaDownloadButton;
@property (weak, nonatomic) IBOutlet MGProgressDownloadView *progressDownloadView;
@property (weak, nonatomic) IBOutlet UILabel *pubDateLabel;
@property (strong, nonatomic) MGPlayState *cellPlayState;
@property (nonatomic) NSInteger podcastId;

- (IBAction) downloadButtonPressed:(UIButton *)sender;
- (IBAction) cancleMediaDownloadButonPressed:(UIButton *)sender;
@end



//MGPodcastListBodyCell.m
@implementation MGPodcastListBodyCell

@synthesize cellPlayState = _cellPlayState;

- (void)setCellPlayState:(MGPlayState *) cellPlayState {
    _cellPlayState = cellPlayState;
    [self playStateChanged];
}


- (void)awakeFromNib {
    [self setup];
}

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        [self setup];
    }
    return self;
}

- (void)setup
{
    UIView *customBackgroundView = [[UIView alloc] init];
    customBackgroundView.backgroundColor = [APAppearence sharedInstance].tableCellBackgroundColorMB;
    self.backgroundView = customBackgroundView;

    self.mediaTitleLabel.textColor = [APAppearence sharedInstance].tableCellMainlabelTextColorMB;
    self.durationLabel.textColor = [APAppearence sharedInstance].standardDarkGrayColorMB;
    self.tintColor = [APAppearence sharedInstance].tableCellMainlabelTextColorMB;

    [self playStateChanged];
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

- (void) playStateChanged {
    self.downloadMediaButton.hidden = self.cellPlayState.playButtonHidden;
    [self.downloadMediaButton setNeedsDisplay];
    self.cancelMediaDownloadButton.hidden = self.cellPlayState.cancelButtonHidden;
    [self.cancelMediaDownloadButton setNeedsDisplay];
    self.progressDownloadView.hidden = self.cellPlayState.progressViewHidden;
    [self setNeedsDisplay];
}

- (IBAction) downloadButtonPressed:(UIButton *)sender {
    [self.podcastCellDelegate downloadButtonPressedOfCell: self.podcastId];
}
- (IBAction) cancleMediaDownloadButonPressed:(UIButton *)sender {
    [self.podcastCellDelegate cancleDownloadButtonPressedOfCell: self.podcastId];
}

@end

因此,如果有人能告诉我,除了重新加载单元格以更新视图之外还能做什么,我将不胜感激.谢谢.

So if somebody can tell me, what to do more than reload the cell to update the View I would be very grateful. Thanks.

推荐答案

我发现了这个错误.reloadRowAtIndexPath 方法没有问题.这是一个并发问题.下载完成状态在下载结束时被下载进度线程覆盖,状态重新设置为下载.

I found the bug. It wasn't a problem with the reloadRowAtIndexPath method. It was a concurrency problem. The download finish state got overwritten by the download progress thread just at the end of downloading and the state was set back to download.

所以,谢谢大家的帮助.

So, thank you all for your help.

这篇关于reloadRowsAtIndexPaths 后自定义 UITableViewCell 外观不会改变的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-25 13:02