当应用程序变为活动状态时刷新 tableView

Posted

技术标签:

【中文标题】当应用程序变为活动状态时刷新 tableView【英文标题】:Refresh tableView when app becomes active 【发布时间】:2011-09-10 22:46:30 【问题描述】:

我知道有几个类似的问题被问到,但我认为我的问题有点不同,所以请耐心等待。

我有一个选项卡式视图应用程序,其中 3 个选项卡中的 2 个设置了表格视图。当应用程序唤醒时,我希望能够仅刷新所选选项卡的表格视图。我曾尝试使用通知中心告诉我的选项卡刷新,但它使另一个选项卡崩溃,因为它正在从我的进度面板中窃取视图。我会在这里放一些代码,希望我能找到适合我的解决方案。

标签 1 视图控制器

- (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];


选项卡 2 视图控制器

- (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 并从我的进度面板下窃取视图,因此当我尝试调用 viewDidAppear 方法时,视图为空并且应用程序崩溃.我要么需要弄清楚如何更好地实现通知中心,这样它就不会使另一个选项卡崩溃,或者需要一种更好的方式来在应用程序激活时刷新。期待一个好的答案。提前致谢。

编辑 当我使用此设置运行时,它会在 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;

【问题讨论】:

【参考方案1】:

这里的主要问题是所有视图都会收到通知,无论它们是否会出现。好的做法是只通知那些将出现在屏幕上的视图

您可以使用应用程序委托的(void)applicationWillEnterForeground:(UIApplication *)application 方法来处理应用程序中的更改而不是通知。

    如果问题完全在于刷新屏幕上的选项卡,那么跟踪 AppDelegate 中选项卡的变化并在应用程序进入前台时使用它会比通知更好。

    其他选项是在 tabbarcontroller 中使用 viewWillAppear 方法。调用此方法时,您可以刷新当前选项卡。

【讨论】:

您的选项 2 给了我一个尝试的想法,这很有效,但是当您的应用程序返回前台时不会调用 viewWillAppear。我将发布我自己的答案,以展示我所做的工作。感谢您的帮助。【参考方案2】:

真的没有多少可以帮助回答这个问题。 @Learner 给了我一个想法,最终导致我如何解决这个问题。

由于我拥有的所有逻辑都有效,因此问题是防止 HUD 窃取另一个视图的视图,因为它们在响应通知事件时都会被调用。因此,在两个选项卡的-becomeActive 事件中,我添加了一个检查 selectedIndex 是否与当前选项卡匹配,如果不是,则不刷新。像魅力一样工作。

-(void)becomeActive:(NSNotification *)notification 
    // only respond if the selected tab is our current tab
    if (self.tabBarController.selectedIndex == 1)  // just set the number to your tab index
        [self viewDidAppear:YES];
    


【讨论】:

以上是关于当应用程序变为活动状态时刷新 tableView的主要内容,如果未能解决你的问题,请参考以下文章

当 iOS 应用程序从非活动/挂起状态被召回时,何时刷新视图

当 UISearchBar 变为活动状态时,UISearchResultsTableView 不会出现

为啥当其他 textField 变为活动状态时,scrollView 会向下滚动?

当实际的活动名称节点关闭时,HDFS HA 集群备用节点不会变为活动状态

如何使用图像而不是活动指示器?

显示视图时 UITableView 变为非活动状态