How to decide what view to display based on global variable

时间:2019-03-17 22:48:23

标签: swift xcode navigation

I'm trying to implement an IOS swift app which starts off with a tab bar controller, and in one of the tab bar controllers is an item called "account".

When a user presses the account item, I want the app to decide (onclick event) whether the view that contains sign up/login is displayed or the profile view is displayed based on a global variable "loggedIn" (bool type).

(I've tried navigation controller but what I've understood from that is that it is a sequence of views which can't decide between views)

I want to know how can this be implemented, maybe some kind of "router" if you may that can switch between views...

If you didn't understand here's a picture of what I'm trying to implement

Basic Map of what I'm trying to explain

If you can suggest a more professional way of doing such design please don't hesitate to express your opinion.

1 个答案:

答案 0 :(得分:0)

我相信当loggedIn状态更改时,更新视图控制器是一种好方法。如果还没有,请创建一个继承自UITabBarController的类来管理标签。这是代码:

class TabController: UITabBarController {}

在情节提要中,选择选项卡控制器,转到Identity Inspector并将TabController设置为自定义类。现在TabController将管理选项卡栏中的所有视图控制器。

使用全局变量通常不是一种好方法,因此让我们在loggedIn的范围内添加TabController并监听其中的任何更改并更新相应的视图控制器:

class TabController: UITabBarController {
  var loggedIn = true {
    didSet {
      updateProfileTab()
    }
  }
}

现在,每当您更改loggedIn时,所做的更改都会更新相应的标签。现在让我们写updateProfileTab()

class TabController: UITabBarController {
  func updateProfileTab() {
    let viewController: UIViewController
    if loggedIn {
      viewController = makeProfileViewController()
    } else {
      viewController = makeLoginViewController()
    }
    setViewController(viewController, at: 2)
  }

  func makeProfileViewController() -> ProfileViewController {
    // create and return the profile view controller
  }

  func makeLoginViewController() -> LoginViewController {
    // create and return the profile view controller
  }
}

自然地,您可能想同时编写makeProfileViewControllermakeLoginViewController方法的主体。 TabController的最后一件事是编写setViewController(_:at:)方法:

class TabController: UITabBarController {
  ...
  func setViewController(_ viewController: UIViewController, at index: Int) {
    let tabBarItem = viewControllers?[index].tabBarItem
    viewController.tabBarItem = tabBarItem
    viewControllers?[index] = viewController
  }
  ...
}

现在,由于TabController管理着标签栏,因此您可以从其任何子视图控制器中访问它:

guard let tabController = tabBarController as? TabController else { return }
tabController.loggedIn = ...

此外,选择初始状态也很重要。因此,在其中一个选项卡式视图控制器的viewDidLoad中,您应该执行上面的代码。第一个选项卡(最先显示的选项卡)可能是执行此操作的最佳位置。希望这会有所帮助!

编辑

要创建登录和注册视图控制器,最简单的方法是在情节提要中分配ID。为此,请转到情节提要,选择视图控制器,然后在Identity Inspector中设置一个Storyboard ID,您将使用该实例化视图控制器:

func makeProfileViewController() -> ProfileViewController {
    let controller = self.storyboard!.instantiateViewController(withIdentifier: "theStoryboardID")
    return controller as! ProfileViewController
}

请注意,我在此处使用强制解包(!)。这只是为了简洁。在实际情况下,您将需要使用一些if letguard let语句来处理nil值。