我有这个实现:
View_1:包含一个navigationView和2个按钮,如下所示
NavigationView {
GeometryReader { gr in
ZStack {
VStack(alignment: HorizontalAlignment.center, spacing: 10) {
HStack{
Spacer()
}
Text("1").foregroundColor(.white).padding(EdgeInsets(top: 30, leading: 0, bottom: 0, trailing: 0))
Text("2").foregroundColor(.white)
Spacer()
HStack {
NavigationLink(destination: SigninScreen()){
Text("Button 1")
}
Button(action: {}){
Text("Button 2")
}
}.padding()
}.background(Image("bg-welcome")
.resizable()
.aspectRatio(contentMode: .fill)).edgesIgnoringSafeArea(.all)
}.navigationBarHidden(true)
}
然后显示目标屏幕(SigninScreen):
struct SigninScreen: View {
@State private var email: String = ""
@State private var password: String = ""
var body: some View {
VStack {
Spacer()
HStack {
Spacer()
}
Text("SigninScreen")
VStack {
TextField("Email", text: self.$email)
.padding()
.background(Color.white)
.overlay(RoundedRectangle(cornerRadius: 1).stroke(Color.white, lineWidth: 2))
SecureField("Password", text: self.$password)
.padding()
.background(Color.white)
.overlay(RoundedRectangle(cornerRadius: 1).stroke(Color.white, lineWidth: 2))
Button(action: {}){
NavigationLink(destination: MainScreen()){
Text("Sign in").foregroundColor(.white)
}
.padding(EdgeInsets(top: 10, leading: 40, bottom: 10, trailing: 40))
.border(Color.white)
}
}.padding()
Spacer()
}.background(Color.red).edgesIgnoringSafeArea(Edge.Set.all).navigationBarHidden(true)
}
}
struct SigninScreen_Previews: PreviewProvider {
static var previews: some View {
SigninScreen()
}
}
最后是最后一个视图:
struct MainScreen: View {
var body: some View {
TabView(){
HomeScreen()
.tabItem {
Image(systemName: "house")
Text("Home")
}
EventsScreen()
.tabItem {
Image(systemName: "calendar")
Text("Events")
}
NewsScreen()
.tabItem {
Image(systemName: "info")
Text("News")
}
}
}
}
struct MainScreen_Previews: PreviewProvider {
static var previews: some View {
MainScreen()
}
}
homeview的实现方式如下
struct HomeScreen: View {
var body: some View {
VStack {
HStack{
Spacer()
}
Text("cacaca")
Spacer()
}.background(Color.yellow).padding(EdgeInsets(top: -150, leading: 0, bottom: 0, trailing: 0))
}
}
struct HomeScreen_Previews: PreviewProvider {
static var previews: some View {
HomeScreen()
}
}
我的问题是导航栏在视图顶部占用了我想使用的空间 而且,例如,如果不添加新的Navigationview,就无法将标题附加到homeview。在我要显示的内容之前,这会在顶部添加更多空间。
关于如何解决此问题的任何想法?
答案 0 :(得分:0)
听起来好像您正在使用NavigationView
在视图之间进行切换,但实际上您并不需要NavigationView
的功能(顶部的标题,后退按钮,后退按钮等) )
因此,我建议您不要具有三个未堆叠的视图:NavigationView
,WelcomeScreen
和SigninScreen
,而不是使主视图深入MainScreen
中的两个层次。然后,您的内容视图应根据您应用的状态在这些视图之间显示/转换。
如何在它们之间进行转换有很多可能性(使视图的不透明性淡入和淡出,使视图在屏幕中滑入和滑出,等等。)有关图片的完整示例,请参见this answer ,但看起来可能像这样:
class LoginStateModel: ObservableObject {
enum CurrentView {
case welcome, login, home
}
@Published var currentView = CurrentView.login
}
struct StackOverflowTests: View {
@ObservedObject var model = LoginStateModel()
var body: some View {
ZStack {
if model.currentView == .welcome {
WelcomeScreen()
} else if model.currentView == .login {
SigninScreen()
} else {
MainScreen()
}
}
.environmentObject(model)
}
}
该模型通过.environmentObject
传递给子视图,以便他们可以对其进行修改(例如,SigninScreen
在成功登录时将模型设置为.home
或MainScreen
设置模型到.login
退出)。
作为附录,您实际上可以为MainScreen
设置新标题,只需在其.navigationBarTitle
属性(例如body
)的某个地方添加另一个TabView
修饰符即可。但如上所述,我仍然建议您摆脱NavigationView
。
答案 1 :(得分:0)
使用此扩展程序隐藏导航栏
extension View {
func hideNavigationBar() -> some View {
self
.navigationBarTitle(Text(""))
.navigationBarHidden(true)
}
}