UITableView细胞奇怪地消失了

时间:2013-12-08 23:05:54

标签: ios uitableview

来自Marko团队

我们是一个令人难以置信的奇怪问题,我们的表格查看单元格,通常看起来像这样:

enter image description here

看起来像这样:

enter image description here

经过审核,当您将iPhone置于睡眠状态时,该错误似乎就会发生,然后重新打开应用程序并转到放置了tableview的uiviewcontroller。不知何故,这使得不再调用cellForRowAtIndexPath,即使委托和数据源仍设置为self。我们的部分和行号仍然正常,我们可以在tableview上向下滚动。但由于未调用cellForRowAtIndexPath,因此会隐藏tableviewcells。

enter image description here

这是我们的tableview设置(我从这个与tableview无关的巨大文件中取出了东西:

//
//  SPHomeViewController.m
//  Spek

@interface SPHomeViewController () <UITableViewDataSource, UITableViewDelegate, MKMapViewDelegate, SPCreationViewDelegate, UIAlertViewDelegate, CLLocationManagerDelegate>
@property (nonatomic, strong) UITableView* tableView;
@property (nonatomic, strong) NSMutableArray* tableDatasource;
@property (nonatomic, strong) NSMutableArray* datasource;
@property (nonatomic, strong) NSMutableArray* friendsDatasource;
@property (nonatomic, strong) UISegmentedControl* userFilterSegment;
@property (nonatomic) BOOL isLoadingData;
@end

@implementation SPHomeViewController

@synthesize datasource = _datasource;
@synthesize friendsDatasource = _friendsDatasource;
@synthesize tableDatasource = _tableDatasource;



- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    //[[SPLocationManager locationManager] startUpdatingLocationForSig];
    [self setNeedsStatusBarAppearanceUpdate];
    self.view.backgroundColor = [UIColor colorWithRed:230.0f/255.0f green:230.0f/255.0f blue:230.0f/255.0f alpha:1.0];
    self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height - kTopBarHeight)];
    self.tableView.separatorColor = [UIColor clearColor];
    self.tableView.backgroundColor = [UIColor clearColor];
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    [self.view addSubview:self.tableView];


}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.

    if (self.creationView.center.y > self.view.frame.size.height) {
        self.creationView = nil;
    }
    NSLog(@"Mem warning");
}


//****************************************
//****************************************
#pragma mark - UITableViewDelegate/DataSource
//****************************************
//****************************************

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"INDEX PATH ROW: %d AND SECTION: %d", indexPath.row, indexPath.section);
    if (indexPath.section == 0) {
        UITableViewCell* cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"SPMapCellSpace"];
        cell.backgroundColor = [UIColor clearColor];
        cell.backgroundView = [[UIView alloc] init];
        cell.selectedBackgroundView = [[UIView alloc] init];
        return cell;
    } else if (indexPath.section == self.tableDatasource.count + 1) {
        UITableViewCell* cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"SPBottomCellSpace"];
        cell.backgroundColor = [UIColor clearColor];
        cell.backgroundView = [[UIView alloc] init];
        cell.selectedBackgroundView = [[UIView alloc] init];

        return cell;
    }
    SPMark* mark = self.tableDatasource[indexPath.section - 1];
    NSString* reuseId = [SPHomeViewController cellIdentifierFromData:mark];
    SPTableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:reuseId];
    if (cell == nil) {
        cell = [SPTableViewCell cellFromMark:mark reuseID:reuseId];
        [cell updateView:YES];
    }
    [cell addDataToCell:mark];
    if (indexPath.section >= self.tableDatasource.count - 2 && !self.isLoadingData && self.pageNumber != -1) {
        self.fetchNextPage = YES;  // When the scrollview stops it will load more data if available.
    }

    return cell;
}

- (unsigned int)getPageNumber {
    return (self.userFilterSegment.selectedSegmentIndex == 0) ? self.pageNumber : self.friendsPageNumber;
}

- (void)setCurrentPageNumber:(unsigned int)page {
    if (self.userFilterSegment.selectedSegmentIndex == 0) {
        self.pageNumber = page;
    } else {
        self.friendsPageNumber = page;
    }
}

- (void)incrementCurrentPageNumber {
    if (self.userFilterSegment.selectedSegmentIndex == 0) {
        self.pageNumber++;
    } else {
        self.friendsPageNumber++;
    }
}

// Every cell has a section header so this should be equal to the number of speks returned from the server
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    NSLog(@"section count is: %d",self.tableDatasource.count + 2 );
    return self.tableDatasource.count + 2;  // Add two because the mapview needs to go on the top and extra spacing at the bottom.
}

// There is a section for every cell, so there is only one cell per section
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 1;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0) {
        return kMapHeight+2;
    } else if (indexPath.section == self.tableDatasource.count + 1) {
        return kExtraSpaceBelowHomeView;
    }
    SPMark* mark = self.tableDatasource[indexPath.section - 1];
    return [SPTableViewCell cellHeightForMark:mark];
}

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0 || indexPath.section == self.tableDatasource.count + 1) {
        cell.backgroundColor = [UIColor clearColor];
    }
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0 || indexPath.section == self.tableDatasource.count + 1)
        return;
    SPMark* mark = self.datasource[indexPath.section - 1 ];
    SPMarkViewController* markVC = [SPMarkViewController withMark:mark];
    [markVC displayData];
    [self.navigationController pushViewController:markVC animated:YES];
}

-(void)reloadTableview {
    [self.tableView setDelegate:self];
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.tableView reloadData];
        [self.tableView setNeedsDisplay];
    });
}

- (void)showNoItems {
    if (self.tableDatasource.count == 0 && self.accuracyBad == NO) {
        self.opaqueIcon.hidden = NO;
        self.noItems.hidden = NO;
        self.beTheFirst.hidden = NO;
        self.downArrow.hidden = NO;
        self.noItemsBackround.hidden = NO;
        [self.view bringSubviewToFront:self.noItemsBackround];
        [self.view bringSubviewToFront:self.downArrow];
        [self.view bringSubviewToFront:self.beTheFirst];
        [self.view bringSubviewToFront:self.noItems];
        [self.view bringSubviewToFront:self.opaqueIcon];

    }
}

- (void)showTableView {
    if (self.tableDatasource.count != 0) {
        self.noItems.hidden = YES;
        self.beTheFirst.hidden = YES;
        self.downArrow.hidden = YES;
        self.noItemsBackround.hidden = YES;
        self.opaqueIcon.hidden = YES;

        [self.view sendSubviewToBack:self.noItemsBackround];
        [self.view sendSubviewToBack:self.downArrow];
        [self.view sendSubviewToBack:self.beTheFirst];
        [self.view sendSubviewToBack:self.noItems];
        [self.view sendSubviewToBack:self.opaqueIcon];
    }
}

//****************************************
//****************************************
#pragma mark - Setters/Getters
//****************************************
//****************************************

- (NSMutableArray*)datasource {
    if (!_datasource) {
        _datasource = [NSMutableArray array];
        if (!self.firstLoad) {
            [self loadDataForPagination:NO];
        }
    }
    return _datasource;
}

- (NSMutableArray*)friendsDatasource {
    if (!_friendsDatasource) {
        _friendsDatasource = [NSMutableArray array];
        if (!self.firstLoad) {
            [self loadDataForPagination:NO];
        }
    }
    return _friendsDatasource;
}

- (NSMutableArray*)tableDatasource {
    if (!_tableDatasource) {
        _tableDatasource = (self.userFilterSegment.selectedSegmentIndex == 0) ? self.datasource : self.friendsDatasource;
    }
    return _tableDatasource;
}

- (SPCreationView*)creationView {
    if (!_creationView) {
        UIView* window = [SPUtils getAppDelegate].window;
        CGSize viewSize = window.frame.size;
        CGRect startFrame = CGRectMake(0, viewSize.height, [SPUtils screenWidth], [SPUtils screenHeight]);
        _creationView = [SPCreationView creationView:startFrame delegate:self];
        [window insertSubview:_creationView belowSubview:self.creationButton];
        _creationView.frame = startFrame;
    }
    return _creationView;
}

- (void)setTableDatasource:(NSMutableArray *)tableDatasource {
    _tableDatasource = tableDatasource;
    [self preFetchImages];
    dispatch_async(dispatch_get_main_queue(), ^{
        if(_tableDatasource == nil || _tableDatasource.count == 0) {
            [self showNoItems];
        } else {
            [self showTableView];
        }
        [self reloadTableview];
    });
}

- (void)setDatasource:(NSMutableArray *)datasource {
    _datasource = datasource;
}

- (void)setFriendsDatasource:(NSMutableArray *)friendsDatasource {
    _friendsDatasource = friendsDatasource;
}


@end

最后,如果您认为它与我们的委托有关,我们不会触及那里的视图控制器,所以我不知道这可能是一个什么问题。可能是内存问题还是后台线程问题?

2 个答案:

答案 0 :(得分:1)

这是很多代码,问题可能出在您的自定义SPTableViewCell课程中,甚至不是您提供的内容。

为了加快速度,重现问题时请进入调试器并转储视图层次结构。您可以通过在视图控制器上调用[self.view recursiveDescription]来执行此操作。这将导致整个子视图层次结构被打印到控制台,这将让您看到应该 - 但不是 - 显示的单元格正在发生什么。如果没有给你带来任何快乐,请将输出发布在此处。

  

但是,更奇怪的是,tableview仍然存在,并且它不是子视图问题,因为你仍然可以滚动:

它可能仍然是一个子视图问题 - tableview从单独的调用中获取单元格的高度,因此它独立于单元格本身。尝试打印出层次结构,看看发生了什么。

答案 1 :(得分:1)

问题是有太多后台线程同时发生。当我们停止尝试预取图像时,问题就消失了。