SwiftUI - NavigationView 和标签栏的屏幕位置问题
SwiftUI - Screen Position Problem with NavigationView and Tab Bar
我正在将 SwiftUI 屏幕集成到 tvOS 的 UIKit 应用程序中。我在屏幕顶部有一个标签栏。当应用程序首先 运行 并且我切换到 SwiftUI 屏幕时,它看起来就像我想要的那样。但是,当我离开然后再回来时,整个屏幕向上移动,导航标题隐藏在标签栏下方,内容都在屏幕上。 SwiftUI 如下所示:
struct SettingsVC: View {
var body: some View {
NavigationView {
HStack {
Image("fullLogo")
.resizable()
.scaledToFit()
.frame(width: 800, height: 450)
.padding()
.offset(y: -75)
List {
NavigationLink(destination: Text("Test")) {
HStack {
Image(systemName: "link")
.font(.headline)
Text("Link Account")
.font(.headline)
}
}
}
.navigationBarTitle("Settings")
}
}
}
}
如果我注释掉 NavigationView
,当切换到另一个选项卡并再次返回时,屏幕位置保持在同一个位置。但是,我需要标题的导航并移动到列表中。我曾尝试删除其他元素(例如图像)以查看它是否会导致问题,但事实并非如此。似乎在此屏幕的后续选择中不再考虑导航栏。这种行为的原因可能是什么?
这是 UIKit 中的标签栏部分。
private func setup() {
self.view.insetsLayoutMarginsFromSafeArea = false
let tvSelectionVC = TVSelectionVC()
tvSelectionVC.screenType = .live
tvSelectionVC.isFirstRun = true
let onDemandVC = TVSelectionVC()
onDemandVC.screenType = .demand
onDemandVC.isFirstRun = false
let settingsVC = SettingsVC()
let settingsHostController = UIHostingController(rootView: settingsVC)
let config = UIImage.SymbolConfiguration(pointSize: 50, weight: .bold)
tvSelectionVC.tabBarItem = UITabBarItem(title: "Live", image: nil, tag: 0)
onDemandVC.tabBarItem = UITabBarItem(title: "OnDemand", image: nil, tag: 1)
settingsHostController.tabBarItem.image = UIImage(systemName: "gear",withConfiguration: config)
let logoView = UIImageView(image: UIImage(named: "logo"))
logoView.translatesAutoresizingMaskIntoConstraints = false
tabBar.leadingAccessoryView.addSubview(logoView)
logoView.topAnchor.constraint(equalTo: tabBar.leadingAccessoryView.topAnchor).isActive = true
logoView.leadingAnchor.constraint(equalTo: tabBar.leadingAccessoryView.leadingAnchor, constant: 0).isActive = true
logoView.heightAnchor.constraint(equalToConstant: 40).isActive = true
logoView.widthAnchor.constraint(equalToConstant: 140).isActive = true
viewControllers = [tvSelectionVC,onDemandVC,settingsHostController]
}
更新:我可以从 SwiftUI 视图中删除所有内容,并且只有 Text
在 NavigationView
中,但问题仍然存在。我也可以将第一个和第二个选项卡更改为空的 UIViewControllers,并且在第一次切换到 SwiftUI 后问题仍然存在。
我能够通过将 NavigationView
标记包装在 VStack
标记内并添加解决此问题所需的 Spacer
来解决问题。有趣的是,作为测试,我创建了一个 SwiftUI 选项卡,前两个选项卡用于空视图,第三个选项卡用于上面的设置。这也表现出与上述相同的问题,这表明此问题与将 SwiftUI 包装在 UIKit 选项卡中无关。我不清楚为什么需要这个解决方案,但它确实解决了问题。这里又是那个SwiftUI,完整解决了这个问题。
struct SettingsVC: View {
var body: some View {
VStack {
Spacer()
NavigationView {
HStack {
Image("fullLogo")
.resizable()
.scaledToFit()
.frame(width: 800, height: 450)
.padding()
.offset(y: -75)
List {
NavigationLink(destination: Text("Test")) {
HStack {
Image(systemName: "link")
.font(.headline)
Text("Link Account")
.font(.headline)
}
}
}
.padding()
.navigationBarTitle("Settings")
}
}
}
}
}
我正在将 SwiftUI 屏幕集成到 tvOS 的 UIKit 应用程序中。我在屏幕顶部有一个标签栏。当应用程序首先 运行 并且我切换到 SwiftUI 屏幕时,它看起来就像我想要的那样。但是,当我离开然后再回来时,整个屏幕向上移动,导航标题隐藏在标签栏下方,内容都在屏幕上。 SwiftUI 如下所示:
struct SettingsVC: View {
var body: some View {
NavigationView {
HStack {
Image("fullLogo")
.resizable()
.scaledToFit()
.frame(width: 800, height: 450)
.padding()
.offset(y: -75)
List {
NavigationLink(destination: Text("Test")) {
HStack {
Image(systemName: "link")
.font(.headline)
Text("Link Account")
.font(.headline)
}
}
}
.navigationBarTitle("Settings")
}
}
}
}
如果我注释掉 NavigationView
,当切换到另一个选项卡并再次返回时,屏幕位置保持在同一个位置。但是,我需要标题的导航并移动到列表中。我曾尝试删除其他元素(例如图像)以查看它是否会导致问题,但事实并非如此。似乎在此屏幕的后续选择中不再考虑导航栏。这种行为的原因可能是什么?
这是 UIKit 中的标签栏部分。
private func setup() {
self.view.insetsLayoutMarginsFromSafeArea = false
let tvSelectionVC = TVSelectionVC()
tvSelectionVC.screenType = .live
tvSelectionVC.isFirstRun = true
let onDemandVC = TVSelectionVC()
onDemandVC.screenType = .demand
onDemandVC.isFirstRun = false
let settingsVC = SettingsVC()
let settingsHostController = UIHostingController(rootView: settingsVC)
let config = UIImage.SymbolConfiguration(pointSize: 50, weight: .bold)
tvSelectionVC.tabBarItem = UITabBarItem(title: "Live", image: nil, tag: 0)
onDemandVC.tabBarItem = UITabBarItem(title: "OnDemand", image: nil, tag: 1)
settingsHostController.tabBarItem.image = UIImage(systemName: "gear",withConfiguration: config)
let logoView = UIImageView(image: UIImage(named: "logo"))
logoView.translatesAutoresizingMaskIntoConstraints = false
tabBar.leadingAccessoryView.addSubview(logoView)
logoView.topAnchor.constraint(equalTo: tabBar.leadingAccessoryView.topAnchor).isActive = true
logoView.leadingAnchor.constraint(equalTo: tabBar.leadingAccessoryView.leadingAnchor, constant: 0).isActive = true
logoView.heightAnchor.constraint(equalToConstant: 40).isActive = true
logoView.widthAnchor.constraint(equalToConstant: 140).isActive = true
viewControllers = [tvSelectionVC,onDemandVC,settingsHostController]
}
更新:我可以从 SwiftUI 视图中删除所有内容,并且只有 Text
在 NavigationView
中,但问题仍然存在。我也可以将第一个和第二个选项卡更改为空的 UIViewControllers,并且在第一次切换到 SwiftUI 后问题仍然存在。
我能够通过将 NavigationView
标记包装在 VStack
标记内并添加解决此问题所需的 Spacer
来解决问题。有趣的是,作为测试,我创建了一个 SwiftUI 选项卡,前两个选项卡用于空视图,第三个选项卡用于上面的设置。这也表现出与上述相同的问题,这表明此问题与将 SwiftUI 包装在 UIKit 选项卡中无关。我不清楚为什么需要这个解决方案,但它确实解决了问题。这里又是那个SwiftUI,完整解决了这个问题。
struct SettingsVC: View {
var body: some View {
VStack {
Spacer()
NavigationView {
HStack {
Image("fullLogo")
.resizable()
.scaledToFit()
.frame(width: 800, height: 450)
.padding()
.offset(y: -75)
List {
NavigationLink(destination: Text("Test")) {
HStack {
Image(systemName: "link")
.font(.headline)
Text("Link Account")
.font(.headline)
}
}
}
.padding()
.navigationBarTitle("Settings")
}
}
}
}
}