停止 UITableView 在方向更改时重新加载数据
Posted
技术标签:
【中文标题】停止 UITableView 在方向更改时重新加载数据【英文标题】:Stop a UITableView from reloading data on orientation change 【发布时间】:2013-12-19 09:48:27 【问题描述】:当设备的方向发生变化时,我的uitableview
调用reloaddata
(这是有道理的,因为显示的单元格数量发生了变化,据我从文档中可以理解,在布局子视图中调用),但是这是有问题的对我来说,因为我在后台执行下载,我不希望某些文件突然出现。有没有办法停止默认行为并让我在需要时手动重新加载?
编辑:
我会尽力解释得更好。在我的 tableview 顶部,我有一个名为“sync”的按钮,它从服务器启动一个同步请求,这个同步请求首先得到一个 JSON 对象,它包含我想在 tableview 中显示的信息,但是每个uitableview
items 代表我从 Internet 下载的文件。
在下载文件时,屏幕上有一个活动指示器,只有在文件下载完成后,我才想重新加载表格。问题是,UITableview
在用户改变方向时会自动调用reloaddata
,所以在下载的文件完成下载之前,单元格会填充来自 json 的信息。
代码:
@implementation BIDManageFilesViewController
- (id)initWithStyle:(UITableViewStyle)style
self = [super initWithStyle:style];
if (self)
// Custom initialization
return self;
- (void)viewDidLoad
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(newDataFinishedDownloading) name:kBIDContentManagerContentDidChangeNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(newDataStartedDownloading:) name:kBIDContentManagerStartedDownloadingContent object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contentAlreadyUpToDate) name:kBIDContentUpToDate object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contentStartingSync) name:kBIDContentStartingSync object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contentEndingSync) name:kBIDContentEndingSync object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(singleDownloadFinished) name:kBIDFinishedDownloadingSingleContent object:nil];
self.navigationController.navigationBarHidden = NO;
UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithTitle:@"Sync"
style:UIBarButtonItemStyleDone target:self action:@selector(Sync)];
self.navigationItem.leftBarButtonItem = leftButton;
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithTitle:@"Display Mode"
style:UIBarButtonItemStyleDone target:self action:@selector(dismissSelf)];
self.navigationItem.rightBarButtonItem = rightButton;
self.navigationItem.title = @"Content Manager";
self.navigationBar = [[UINavigationBar alloc] initWithFrame:CGRectZero];
[self.view addSubview:_navigationBar];
[self.navigationBar pushNavigationItem:self.navigationItem animated:NO];
-(void)viewWillAppear:(BOOL)animated
[super viewWillAppear:animated];
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationFade];
-(void)layoutNavigationBar
if([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortrait || [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortraitUpsideDown)
self.navigationBar.frame = CGRectMake(0, self.tableView.contentOffset.y, self.view.frame.size.width, self.topLayoutGuide.length + 44);
else
self.navigationBar.frame = CGRectMake(0, self.tableView.contentOffset.y, self.view.frame.size.height, self.topLayoutGuide.length + 44);
NSLog(@"width: %f", self.view.frame.size.width);
NSLog(@"height: %f", self.view.frame.size.height);
self.tableView.contentInset = UIEdgeInsetsMake(self.navigationBar.frame.size.height, 0, 0, 0);
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
//no need to call super
[self layoutNavigationBar];
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
[self layoutNavigationBar];
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
-(void)viewDidLayoutSubviews
[super viewDidLayoutSubviews];
[self layoutNavigationBar];
- (void)didReceiveMemoryWarning
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
/*
#pragma mark - Navigation
// In a story board-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
*/
-(void)viewDidDisappear:(BOOL)animated
[super viewDidDisappear:animated];
self.navigationController.navigationBarHidden = YES;
-(void)newDataStartedDownloading: (NSNotification *)notif
self.hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
_hud.labelText = @"Downloading...";
_hud.detailsLabelText = [NSString stringWithFormat:@"1/%@",[notif.userInfo objectForKey:@"downloadFileNumber"]];
-(void)singleDownloadFinished
NSString *currentText = _hud.detailsLabelText;
NSArray *subStrings = [currentText componentsSeparatedByString:@"/"];
NSInteger downloadsPlusOne = [[subStrings objectAtIndex:0] integerValue]+1;
NSString *newTextForLabel = [NSString stringWithFormat:@"%d/%@", downloadsPlusOne, [subStrings objectAtIndex:1]];
_hud.detailsLabelText = newTextForLabel;
-(void)newDataFinishedDownloading
_thereIsNewInfo = TRUE;
[MBProgressHUD hideHUDForView:self.view animated:YES];
[self.tableView reloadData];
[[NSNotificationCenter defaultCenter] postNotificationName:kBIDnewDownloadedContentReadyToBeDispayedNotification object:nil userInfo:nil];
-(void)contentAlreadyUpToDate
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Sync Alert"
message:@"Files Are Already Up To Date"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles: nil];
[alert show];
-(void)contentStartingSync
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.labelText = @"Syncing...";
-(void)contentEndingSync
[MBProgressHUD hideHUDForView:self.view animated:YES];
-(void)Sync
[AppDelegate.appContentManager downloadContent];
-(void)dismissSelf
if (![AppDelegate.appContentManager subsetArrayFromFileArrayWithNonVidContentThatShouldDisplay] && ![AppDelegate.appContentManager subsetArrayFromFileArrayWithVideoContentThatShouldDisplay])
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"No Files to Display"
message:@"Please update or enable content"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles: nil];
[alert show];
return;
else if ([AppDelegate.appContentManager subsetArrayFromFileArrayWithNonVidContentThatShouldDisplay])
[self dismissViewControllerAnimated:YES completion:Nil];
else
[self performSegueWithIdentifier:@"goToVideos" sender:self];
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
if ([segue.identifier isEqualToString:@"goToVideos"])
((BIDViewController *)segue.destinationViewController).stackedByManager = TRUE;
@end
【问题讨论】:
我不明白表格视图与下载文件有什么关系。您能否更好地解释问题或显示一些代码? 【参考方案1】:没有必要在方向改变时重新加载数据,但是如果你想重新加载表格,请在后台下载完成后尝试调用 [myTable reloadData] 并且只有在方向改变时(你可以在 orient.改变)。
【讨论】:
反之,我不希望它重新加载方向变化的数据。 tableview 不会在方向改变时自动重新加载数据。也许你将它设置在 didRotateFromInterfaceOrientation 上。请粘贴您的代码,以便我提供更好的帮助!以上是关于停止 UITableView 在方向更改时重新加载数据的主要内容,如果未能解决你的问题,请参考以下文章
当我动态更改其框架时,即使重新加载后 UITableView 内容大小也不会更新
Jerk当用户位于UITableView的底部时重新加载UITableView