当应用程序激活时刷新 tableView
我知道有人问了一些与此类似的问题,但我认为我的问题有点不同,所以请耐心等待。
我有一个选项卡式视图应用程序,其表视图设置在 3 个选项卡中的 2 个中。我希望能够在应用程序唤醒时仅刷新所选选项卡的表格视图。我尝试使用通知中心告诉我的选项卡刷新,但它使另一个选项卡崩溃,因为它正在窃取我的进度平视显示器的视图。我将在这里放置一些代码,所以希望我能找到适合我的解决方案。
Tab 1 ViewController
- (void)viewDidLoad {
// becomeActive just calls viewDidAppear:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(becomeActive:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
[super viewDidLoad];
}
-(void)viewDidAppear:(BOOL)animated {
HUD = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:HUD];
HUD.delegate = self;
HUD.labelText = @"Updating";
HUD.detailsLabelText = @"Please Wait";
[HUD showWhileExecuting:@selector(refreshData) onTarget:self withObject:nil animated:YES];
}
Tab 2 ViewController
- (void)viewDidLoad
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
self.navigationItem.title = [defaults valueForKey:@"companyName"];
self.view.backgroundColor = background;
tableView.backgroundColor = [UIColor clearColor];
tableView.opaque = YES;
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
// becomeActive just calls viewDidAppear
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(becomeActive:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
if (_refreshHeaderView == nil) {
EGORefreshTableHeaderView *view = [[EGORefreshTableHeaderView alloc] initWithFrame:CGRectMake(0.0f, 0.0f - self.tableView.bounds.size.height, self.view.frame.size.width, self.tableView.bounds.size.height)];
view.delegate = self;
[self.tableView addSubview:view];
_refreshHeaderView = view;
[view release];
}
// update the last update date
[_refreshHeaderView refreshLastUpdatedDate];
}
-(void)viewDidAppear:(BOOL)animated {
HUD = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:HUD];
HUD.delegate = self;
HUD.labelText = @"Updating";
HUD.detailsLabelText = @"Please Wait";
[HUD showWhileExecuting:@selector(updateBoard) onTarget:self withObject:nil animated:YES];
// update the last update date
[_refreshHeaderView refreshLastUpdatedDate];
}
通过此设置,我的应用程序将很好地刷新选项卡 2,假设选项卡 2 是您关闭应用程序之前打开的最后一个选项卡。如果我在关闭时切换到选项卡 1,则在重新启动应用程序时,通知会首先调用选项卡 2,并从我的进度 hud 下窃取视图,因此当我尝试调用 viewDidAppear 方法时,视图为 null 并且应用程序崩溃。我要么需要弄清楚如何更好地实现通知中心,以便它不会使其他选项卡崩溃,要么需要找到一种更好的方法,以便在应用程序变为活动状态时刷新。期待一个好的答案。提前致谢。
编辑 当我使用此设置运行时,它会在 MBProgressHUD 内中止
- (id)initWithView:(UIView *)view {
// Let's check if the view is nil (this is a common error when using the windw initializer above)
if (!view) {
[NSException raise:@"MBProgressHUDViewIsNillException"
format:@"The view used in the MBProgressHUD initializer is nil."]; // <-- Aborts on this line, so they know it can happen
}
id me = [self initWithFrame:view.bounds];
// We need to take care of rotation ourselfs if we're adding the HUD to a window
if ([view isKindOfClass:[UIWindow class]]) {
[self setTransformForCurrentOrientation:NO];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange:)
name:UIDeviceOrientationDidChangeNotification object:nil];
return me;
}
I know there have been a couple questions asked similar to this, but I think my issues is a little different, so bear with me.
I have a tabbed view app with table views set in 2 of the 3 tabs. I want to be able to refresh just the table view of the selected tab when the app wakes back up. I have tried using the notification center to tell my tab to refresh, but it makes the other tab crash because it is stealing the view from my progress hud. I will put some code here, so hopefully I can find a solution that will work for me.
Tab 1 ViewController
- (void)viewDidLoad {
// becomeActive just calls viewDidAppear:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(becomeActive:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
[super viewDidLoad];
}
-(void)viewDidAppear:(BOOL)animated {
HUD = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:HUD];
HUD.delegate = self;
HUD.labelText = @"Updating";
HUD.detailsLabelText = @"Please Wait";
[HUD showWhileExecuting:@selector(refreshData) onTarget:self withObject:nil animated:YES];
}
Tab 2 ViewController
- (void)viewDidLoad
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
self.navigationItem.title = [defaults valueForKey:@"companyName"];
self.view.backgroundColor = background;
tableView.backgroundColor = [UIColor clearColor];
tableView.opaque = YES;
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
// becomeActive just calls viewDidAppear
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(becomeActive:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
if (_refreshHeaderView == nil) {
EGORefreshTableHeaderView *view = [[EGORefreshTableHeaderView alloc] initWithFrame:CGRectMake(0.0f, 0.0f - self.tableView.bounds.size.height, self.view.frame.size.width, self.tableView.bounds.size.height)];
view.delegate = self;
[self.tableView addSubview:view];
_refreshHeaderView = view;
[view release];
}
// update the last update date
[_refreshHeaderView refreshLastUpdatedDate];
}
-(void)viewDidAppear:(BOOL)animated {
HUD = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:HUD];
HUD.delegate = self;
HUD.labelText = @"Updating";
HUD.detailsLabelText = @"Please Wait";
[HUD showWhileExecuting:@selector(updateBoard) onTarget:self withObject:nil animated:YES];
// update the last update date
[_refreshHeaderView refreshLastUpdatedDate];
}
With this setup, my application will refresh tab 2 just fine, assuming that tab 2 was the last tab open before you closed the application. If I switch to tab 1 when I close, upon restarting the app, the notification calls tab 2 first and steals the view out from under my progress hud, so when I try to call the viewDidAppear method, the view is null and the app crashes. I either need to figure out how to implement the notification center better so it doesn't crash the other tab, or a better way overall to just refresh when the app becomes active. Looking forward to a good answer. Thanks in advance.
EDIT
When I run with this setup, it aborts inside the MBProgressHUD
- (id)initWithView:(UIView *)view {
// Let's check if the view is nil (this is a common error when using the windw initializer above)
if (!view) {
[NSException raise:@"MBProgressHUDViewIsNillException"
format:@"The view used in the MBProgressHUD initializer is nil."]; // <-- Aborts on this line, so they know it can happen
}
id me = [self initWithFrame:view.bounds];
// We need to take care of rotation ourselfs if we're adding the HUD to a window
if ([view isKindOfClass:[UIWindow class]]) {
[self setTransformForCurrentOrientation:NO];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange:)
name:UIDeviceOrientationDidChangeNotification object:nil];
return me;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这里的主要问题是所有视图都会收到通知,无论它们是否会出现。好的做法是仅通知将出现在屏幕中的视图,
您可以使用应用程序委托的
(void)applicationWillEnterForeground:(UIApplication *)application
方法来处理应用程序中的更改而不是通知。如果问题全部与刷新屏幕上的选项卡有关,那么跟踪 AppDelegate 中选项卡的更改并在应用程序进入前台时使用它会比通知更好。
另一个选项是使用 tabbarcontroller 中的 viewWillAppear 方法。当调用此方法时,您可以刷新当前选项卡。
Main problem here that notifications are received by all views, whether they will appear or not. Good practice would be to notify only those views which will appear in screen
you can use application delegate's
(void)applicationWillEnterForeground:(UIApplication *)application
method to handle change in application instead of notification.if problem is all about refreshing tab that is on screen then keeping track of change in tab in AppDelegate and using that when application enters foreground would be better idea over notification.
Other option is to use viewWillAppear method in tabbarcontroller. When this method gets called, you can refresh current tab.
确实没有太多东西可以帮助回答这个问题。 @Learner 给了我一个想法,最终导致我如何解决这个问题。
由于我的所有逻辑都有效,所以问题是防止 HUD 窃取另一个 HUD 的视图,因为它们在响应通知事件时都会被调用。因此,在两个选项卡的
-becomeActive
事件中,我添加了一个检查 selectedIndex 是否与当前选项卡匹配的检查,如果不匹配,则不刷新。工作起来就像一个魅力。There really isn't much out there to help answer this question. @Learner gave me an idea that ultimately led to how I resolved this issue.
Since all of the logic I have works, the issue was to prevent the HUD from stealing the view from the other one since they both get called when they respond to the notification event. So in my
-becomeActive
event for both tabs, I added a check if the selectedIndex was a match for the current tab, if not, no refresh. Worked like a charm.