Swift 禁用导航控制器按钮直到 viewDidLoad 完成
Swift Disable Navigation Controller buttons Until viewDidLoad is completed
VC1 是我在项目中的主页,我可以从 VC1 转到 5 个不同的视图控制器。在 VC1 viewDidLoad 中,我正在从我的 Firestore 数据库下载数据,我需要将它们全部加载到 phone,然后才能允许用户与导航栏中的按钮进行交互。这是我的 VC1 的样子(底部 3 个按钮,顶部 2 个按钮):
但目前用户可以在 viewDidLoad 中的数据未完全加载到 phone 时单击 VC1 中的按钮并让它们从 VC1 转到 VC2(如果它们足够快,它们可以完成此操作).
除非 viewDidLoad 中的所有功能都已完成,否则如何防止用户与导航栏中的按钮进行交互?
override func viewDidLoad() {
super.viewDidLoad()
func1()
func2()
func3()
}
不确定这是否相关,但在我的 AppDelegate 中,这是我定义 rootViewController 的方式:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
let storyboard = UIStoryboard(name: "Main", bundle: .main)
window?.rootViewController = storyboard.instantiateViewController(withIdentifier: "TabBarController")
}
这就是我在主情节提要中的内容:
这是我的家庭故事板:
当 viewDidLoad
处于 运行ning 时,用户无法触摸任何按钮。或者更准确地说:当 viewDid...
、viewWill...
函数处于 运行 状态时,按钮不会对事件做出反应。这是因为所有这些方法都在主线程中执行,并且会阻止任何用户交互。
我假设您的“问题”是因为 func1()
,2 或 3 正在调用网络服务,通常是在任意工作线程中 运行。因此,func1
returns 在所有数据被提取之前,因此 viewDidLoad
returns 对你来说太早了。
因为你不应该 运行 主线程中的网络调用(Firestore 调用也不会这样做),你需要做一些额外的工作,例如:
- 在
viewDidLoad
中,禁用您不希望用户与之交互的所有按钮
- 在 Firestore 处理程序中,检查是否已收到所有数据,然后再次启用按钮(在主线程中,您可能需要为此调用
DispatchQueue.main.async
)
- 如果您有多个后台作业 运行ning 并且您需要等待所有作业,您可以使用
DispatchGroup
VC1 是我在项目中的主页,我可以从 VC1 转到 5 个不同的视图控制器。在 VC1 viewDidLoad 中,我正在从我的 Firestore 数据库下载数据,我需要将它们全部加载到 phone,然后才能允许用户与导航栏中的按钮进行交互。这是我的 VC1 的样子(底部 3 个按钮,顶部 2 个按钮):
但目前用户可以在 viewDidLoad 中的数据未完全加载到 phone 时单击 VC1 中的按钮并让它们从 VC1 转到 VC2(如果它们足够快,它们可以完成此操作).
除非 viewDidLoad 中的所有功能都已完成,否则如何防止用户与导航栏中的按钮进行交互?
override func viewDidLoad() {
super.viewDidLoad()
func1()
func2()
func3()
}
不确定这是否相关,但在我的 AppDelegate 中,这是我定义 rootViewController 的方式:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
let storyboard = UIStoryboard(name: "Main", bundle: .main)
window?.rootViewController = storyboard.instantiateViewController(withIdentifier: "TabBarController")
}
这就是我在主情节提要中的内容:
这是我的家庭故事板:
当 viewDidLoad
处于 运行ning 时,用户无法触摸任何按钮。或者更准确地说:当 viewDid...
、viewWill...
函数处于 运行 状态时,按钮不会对事件做出反应。这是因为所有这些方法都在主线程中执行,并且会阻止任何用户交互。
我假设您的“问题”是因为 func1()
,2 或 3 正在调用网络服务,通常是在任意工作线程中 运行。因此,func1
returns 在所有数据被提取之前,因此 viewDidLoad
returns 对你来说太早了。
因为你不应该 运行 主线程中的网络调用(Firestore 调用也不会这样做),你需要做一些额外的工作,例如:
- 在
viewDidLoad
中,禁用您不希望用户与之交互的所有按钮 - 在 Firestore 处理程序中,检查是否已收到所有数据,然后再次启用按钮(在主线程中,您可能需要为此调用
DispatchQueue.main.async
) - 如果您有多个后台作业 运行ning 并且您需要等待所有作业,您可以使用
DispatchGroup