reloadRowsAtIndexPaths后,自定义UITableViewCell外观不会改变

时间:2015-01-06 16:07:06

标签: ios objective-c uitableview

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

当我调试时,我看到调用了cellForRowAtIndexPath-methode并且模型已更新。这意味着取消按钮和进度视图设置隐藏= YES;但他们并没有消失。将单元格滚出视图并返回后,将隐藏进度视图,但取消按钮不会。

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

因此,如果有人可以告诉我,除了重新加载单元格以更新视图之外还要做些什么我会非常感激。感谢。

2 个答案:

答案 0 :(得分:0)

当您重新加载单元格时,您的代码如下...

MGPodcastListBodyCell *cell = (MGPodcastListBodyCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifierBodyCell];
if (cell == nil) {
  ....
}

使用- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 方法。由于该单元格正在重复使用,cell第二次不会为零,因此无法使用任何新信息进行更新。

cell不是零时,您需要做一些事情来刷新它。

答案 1 :(得分:0)

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

所以,谢谢大家的帮助。