首页 > 解决方案 > 在可选 UIViewController 数组上操作时如何避免嵌套过多?

问题描述

我有一个UIPageViewController,它有一个可选的UIViewController数组。

pageViewController.viewControllers

我注意到,每当我需要对其执行一些操作时,我都需要编写许多级别(4)的if检查。

  // TODO: How can we improve this code?
  //
  // Logic: We will call setViewControllers, if viewControllers is null, or empty, or 1st element of
  // viewControllers.pageIndex is not equal to self.selectedTabIndex
  if let viewControllers = self.pageViewController.viewControllers {
      if viewControllers.count > 0 {
          if let pageIndexable = viewControllers[0] as? PageIndexable {
              if pageIndexable.pageIndex != self.selectedTabIndex {
                  self.pageViewController.setViewControllers([viewController(At: self.selectedTabIndex)!], direction: direction, animated: true, completion: nil)
                  self.tabCollectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
              }
          }
      } else {
          self.pageViewController.setViewControllers([viewController(At: self.selectedTabIndex)!], direction: direction, animated: true, completion: nil)
          self.tabCollectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
      }
  } else {
      self.pageViewController.setViewControllers([viewController(At: self.selectedTabIndex)!], direction: direction, animated: true, completion: nil)
      self.tabCollectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
  }

我有一种感觉,由于声明级别太多,我可能以错误的方式使用optionalif

你能建议我改进代码的方法吗?

标签: iosswift

解决方案


想想你什么时候不想打电话setViewControllers。那是当以下情况为假时:

viewControllers为 nil,或为空,或viewControllers[0].pageIndex != self.selectedTabIndex

使用德摩根定律,我们可以看到它的否定是:

viewControllers不为零,也不为空,并且viewControllers[0].pageIndex == self.selectedTabIndex

在 if 语句中连接它,我们得到:

if let vcs = self.pageViewController.viewControllers,
   let firstVC = vcs.first as? PageIndexable, // this checks for non-empty
   firstVC.pageIndex == self.selectedTabIndex {
   // do stuff
} else {
  self.pageViewController.setViewControllers([viewController(At: self.selectedTabIndex)!], direction: direction, animated: true, completion: nil)
  self.tabCollectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
}
// do other stuff

如果该方法会在执行setViewControllersand之后立即返回scrollToItem(即您没有任何代码在该// do other stuff位置),那么您可以使用guard语句来代替:

guard let vcs = self.pageViewController.viewControllers,
   let firstVC = vcs.first as? PageIndexable,
   firstVC.pageIndex == self.selectedTabIndex else {
   self.pageViewController.setViewControllers([viewController(At: self.selectedTabIndex)!], direction: direction, animated: true, completion: nil)
   self.tabCollectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
   return
}
// do stuff

正如 Alexander 在评论中所说,您也可以在单个表达式中执行此操作:

if !((self.pageViewController.viewControllers?.first as? PageIndexable)?.pageIndex == self.selectedTabIndex) {

   self.pageViewController.setViewControllers([viewController(At: self.selectedTabIndex)!], direction: direction, animated: true, completion: nil)
   self.tabCollectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)

}

但我认为这种方式的意图不太清楚。


推荐阅读