应用程序激活时快速视图重新加载

Posted

技术标签:

【中文标题】应用程序激活时快速视图重新加载【英文标题】:Swift view reload when app becomes active 【发布时间】:2019-03-24 20:23:23 【问题描述】:

我有从 firebase 更新的值,我正在调用更新 viewdidload() 中的值的函数,当安装应用程序时,值会更新,然后我发送一个基本上要求我关闭的更新app 两次,直到值被更新,不确定 iphone 是否即使在 1 次关闭后仍将其保存在内存中?

我尝试添加 viewWillAppear 和 viewDidAppear 来尝试解决这个问题,但什么都没做。有没有办法在应用打开时重新加载视图,即使它没有关闭并且在后台。

这是否可以通过应用委托进行?我如何从那里更新视图控制器?

谢谢。

【问题讨论】:

【参考方案1】:

最好听UIApplication.didBecomeActiveNotification 当应用程序从后台转到前台时,ios 会发送此通知。

您可以为该通知安装处理程序,例如在控制器的 viewDidLoad 方法中。

override func viewDidLoad() 
   super.viewDidLoad()

   NotificationCenter.default.addObserver(self,
                                          selector: #selector(handleAppDidBecomeActiveNotification(notification:)),
                                          name: UIApplication.didBecomeActiveNotification,
                                          object: nil)

您的处理程序将只是同一视图控制器中的一个方法,以便在收到此通知时调用。在该方法中,您可以重新加载数据或做任何您想做的事情

@objc func handleAppDidBecomeActiveNotification(notification: Notification) 
    reloadData()

当然不要忘记在视图控制器关闭时取消注册UIApplication.didBecomeActiveNotification。比如在控制器的deinit方法中

deinit 
   NotificationCenter.default.removeObserver(self)

这样,重新加载的逻辑和触发重新加载的内容将被封装在每个视图控制器中,而应用程序委托将不知道哪个更好。

【讨论】:

感谢您的帮助,我是这样实现的。有没有理由比应用程序委托更好?两种方式似乎都可以正常工作【参考方案2】:

您可以从 AppDelegate 处理它。

使用可选应用程序确实成为了主动方法。

func applicationDidBecomeActive(_ application: UIApplication)

调用此方法是为了让您的应用知道它已从非活动状态变为活动状态。您应该使用此方法重新启动在应用处于非活动状态时暂停(或尚未启动)的所有任务。

已编辑以显示如何获得所需的控制器。 检查里面的控制器:

func applicationDidBecomeActive(_ application: UIApplication) 
   let appDelegate: AppDelegate? = UIApplication.shared.delegate as? AppDelegate
   if let controller = appDelegate?.window?.rootViewController 
      if let navigationController: UINavigationController = controller as? UINavigationController 
         let viewControllers: [UIViewController] = navigationController.viewControllers
         for viewController in  viewControllers 
             // Check for your view controller here
         
       else if let viewController: UIViewController = controller as? UIViewController 
          // Check for your view controller here
       else if let tabController: UITabBarController = controller as? UITabBarController 
         // Narrow the hierarchy and check for your view controller here
     
   

【讨论】:

感谢您的帮助,我将如何从那里调用 viewcontroller 中的函数。我尝试调用一个函数,它导致错误“致命错误:在展开可选值时意外发现 nil”。抱歉,我是 swift 新手,不确定我是否应该做其他事情来调用那里的某个函数?【参考方案3】:

从firebase加载数据后,您必须在viewDidLoad()中调用方法tableView.reloadData()

例如看看我的例子:

// no matter what you have collectionView or tableView
@IBOutlet private weak var cardsCollectionView: UICollectionView!
// data from firebase stored in the array
private var cards: [Card]?

    override func viewDidLoad() 
    super.viewDidLoad()

    DatabaseService.shared.loadDataFromDb  (cards) in
        DispatchQueue.main.async 
            // update of array with new data
            self.cards = cards
            // update of view
            self.cardsCollectionView.reloadData()
        
    

【讨论】:

以上是关于应用程序激活时快速视图重新加载的主要内容,如果未能解决你的问题,请参考以下文章

如何在快速向上和向下滚动表格时停止自动重新加载表格视图? [关闭]

如何快速从另一个视图控制器重新加载表格视图

Swift:重新加载视图控制器

CollectionView 标题在滚动时停止刷新/重新加载数据

应用程序激活时呈现模态视图

集合视图不会重新加载(Swift)