【问题标题】:Accessing functions/variables inside a UITabBarController with or without global variables?访问带有或不带有全局变量的 UITabBarController 中的函数/变量?
【发布时间】:2017-06-12 22:10:04
【问题描述】:

目前我的应用程序有这样的布局。我在应用程序委托中有一个 UITabBarcontroller 作为我的根视图控制器,这很好并且效果很好。

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?


func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    FIRApp.configure()

    window = UIWindow(frame: UIScreen.main.bounds)
    window?.makeKeyAndVisible()

    window?.rootViewController = Tabs()


    UITabBar.appearance().tintColor = UIColor.init(r: 198, g: 214, b: 91)
    UITabBar.appearance().barTintColor = UIColor.init(r: 47, g: 47, b: 47)




    UINavigationBar.appearance().barTintColor = UIColor.init(r: 53, g: 57, b: 77)


    UINavigationBar.appearance().tintColor = UIColor.init(r: 198, g: 214, b: 91)

但是,在我的选项卡控制器布局中,我的布局方式是在顶部有 UITabBar,然后是一个覆盖 didload 函数,它可以像这样布局所有视图。

 class Tabs: UITabBarController{


 override func viewDidLoad() {
    super.viewDidLoad()



    tabBar.isTranslucent = true


    let feed = feedController()
    let feedArray = UINavigationController(rootViewController: feed)
    let feedButton = UITabBarItem(title: nil, image: UIImage(named: "feed.png"), selectedImage: UIImage(named: "selectedimage.png"))
    feedButton.imageInsets = UIEdgeInsets(top: 5, left: 0, bottom: -5, right: 0)
    feedArray.tabBarItem = feedButton



    let messages = messagesController()
    let messagesArray = UINavigationController(rootViewController: messages)
    let messagesButton = UITabBarItem(title: nil, image: UIImage(named: "messages.png"), selectedImage: UIImage(named: "selectedimage.png"))
    messagesButton.imageInsets = UIEdgeInsets(top: 5, left: 0, bottom: -5, right: 0)
    messagesArray.tabBarItem = messagesButton


    let post = postController()
    let postButton = UITabBarItem(title: nil, image: UIImage(named: "post.png"), selectedImage: UIImage(named: "selectedimage.png"))
    postButton.imageInsets = UIEdgeInsets(top: 5, left: 0, bottom: -5, right: 0)
    post.tabBarItem = postButton


    let profile = profileController()


    let profileArray = UINavigationController(rootViewController: profile)
    let profileButton = UITabBarItem(title: nil, image: UIImage(named: "profile.png"), selectedImage: UIImage(named: "selectedimage.png"))

    profileButton.imageInsets = UIEdgeInsets(top: 5, left: 0, bottom: -5, right: 0)
    profile.tabBarItem = profileButton






    let settings = settingsController()
    let settingsArray = UINavigationController(rootViewController: settings)
    let settingsButton = UITabBarItem(title: nil, image: UIImage(named: "settings.png"), selectedImage: UIImage(named: "selectedimage.png"))
    settingsButton.imageInsets = UIEdgeInsets(top: 5, left: 0, bottom: -5, right: 0)
    settingsArray.tabBarItem = settingsButton





    if FIRAuth.auth()?.currentUser?.uid == nil {
        DispatchQueue.main.async {


            self.handleLogout()}
    }


/* all views BOII */    viewControllers = [feedArray, messagesArray, post, profileArray, settingsArray]

但是,当我尝试从内部的另一个视图控制器访问此选项卡控制器内的视图控制器中的函数或任何内容时。像这样

class settingsController: UIViewController{ 

messagesController().removeMessages()

}

.......

class messagesController: UIViewController{
    removeMessages(){
            messages.removeAll()
            messagesDictionary.removeAll()
            tableView.reloadData()


            print("working")

}
}

函数被调用(我在注销时将其放入函数中),我收到打印消息,但我希望在该视图控制器上受到影响的任何内容似乎都不起作用。目前,到目前为止,我已经尝试过这些方法(在设置控制器上)。

我知道这与 swift 中的 tabbarcontroller 相关,与内部视图如何相互平行运行有关。

我所做的并且成功的是将变量的声明放在我的 tabs.swift 文件中的类之前。因此,我采用了设置视图的 let 语句,并将它们放在声明类之前和 import 语句下。这行得通,但这是不好的做法,有没有更好的方法呢?因为这个 let 语句现在是全局的。

真的很感谢大家的帮助,我很抱歉发了这么长的帖子,我只是想让你试着理解我在这里说的话,我是新人。

【问题讨论】:

  • 尝试打开之前的每个标签。也许你的视图控制器还没有加载。
  • 如果所有 viewDidLoad 方法都在之前运行,则表明您调用的方法不在主线程中。
  • @ObranS 尝试了那个伙伴,这与它被声明有关,就像我可以通过让它们让语句作为全局变量来修复它(在类之外声明它们),但我不确定是否这是不好的做法,为了安全,什么不是。不过谢谢。 :)
  • 嗯,我看到了@ObranS。你会建议做什么?
  • 您有几个选择... 1) 使用您的自定义 TabBarController 作为“消息路由器” - 即 SettingsController 告诉 TabBar 告诉 MessagesController.removeMessages(),或 2) 使用委托模式.

标签: ios swift uitabbarcontroller


【解决方案1】:

如果您的 UIKit 对象从当前堆栈进行操作,它将无法工作。由于对象应该从主线程调用。

DispatchQueue.main.async {
    self.handleLogout()
}

我只能建议您使用下一个块作为 UI 元素的快速解决方案:

dispatch_async(dispatch_get_main_queue()) {
    messages.removeAll()
    messagesDictionary.removeAll()
    tableView.reloadData()
}

【讨论】:

  • 这不是我想要做的,但是你为我修复了另一个错误,谢谢! :)
  • 事实上,当我在 UITabBarController 中嵌入了两个控制器时,我永远无法访问函数或变量,这就是我想要解决的问题。尽管我在这里列出了一个问题,但它会影响我尝试构建的应用程序,因为我需要在视图控制器之间共享功能,但由于这个 tabbarcontroller,我也很难做到这一点。
猜你喜欢
  • 2014-02-01
  • 2019-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多