让 iPhone 进入睡眠状态会隐藏 tableview 单元格 [重复]
Posted
技术标签:
【中文标题】让 iPhone 进入睡眠状态会隐藏 tableview 单元格 [重复]【英文标题】:Putting iPhone to sleep hides tableview cells [duplicate] 【发布时间】:2013-12-10 16:37:01 【问题描述】:这里的问题很奇怪。
基本上发生的情况是,当我们简单地将应用程序置于睡眠状态然后重新解锁时,我们的 Tableview 单元格在某些情况下会变得隐藏。我们正常的 tableview 是这样的:
然后当我们重新打开应用程序时,它会如下所示:
所有行和部分都设置正确,但单元格被隐藏。:
当这种情况发生时,我们的 cellForRowAtIndexPath 不再被调用。这肯定是问题所在。有没有人见过这样的行为?下面是我们如何设置表格视图。 (抱歉有点长)
//
// 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
如果您认为这是 AppDelegate 问题,我们不会对其中的这个控制器做任何事情,所以我看不出它是怎么回事。
【问题讨论】:
【参考方案1】:我以前只在从后台线程重新加载数据(错误地)时看到过这种情况。我看到您已经在尝试将重新加载推送到主线程上。
您似乎在努力确保主线程上发生更新。您可能应该通过检查 [NSThread isMainThread] 来验证您的操作是否发生在 main 上,而不是让您的代码与主线程异步,进行大量异步流程更改可能会导致意外行为。
也就是说,由于这只发生在从睡眠中唤醒时,也许您打开了一些后台模式并且您没有从那里的正确线程更新 UI?
【讨论】:
你认为我们应该在哪里检查这个? @GabeJacobs 您在哪里与背景模式交互?没有看到你的项目很难说。 后台线程太多,你去吧以上是关于让 iPhone 进入睡眠状态会隐藏 tableview 单元格 [重复]的主要内容,如果未能解决你的问题,请参考以下文章