【问题标题】:SwiftUI view is in the middle instead of in the topSwiftUI 视图位于中间而不是顶部
【发布时间】:2019-10-24 23:17:29
【问题描述】:

我正在尝试在 SwiftUI 中创建一个视图。在预览中,它看起来应该,但是在我的 iPhone(或实时预览)上运行时,它看起来像是偏移了。

我尝试将填充设置为 -150,但 TextField 不响应触摸。

VStack {
    Text("Name:")
        .padding(.bottom, 1)
    TextField($name)
        .padding(.horizontal, 25.0)
        .textFieldStyle(.roundedBorder)
        .frame(maxWidth: 500)
    Text("Image:")
        .padding(.top, 1)
    Image(uiImage: image!)
        .resizable(capInsets: EdgeInsets(), resizingMode: .stretch)
        .scaledToFit()
        .frame(width: 250, height: 250)
        .clipShape(RoundedRectangle(cornerRadius: 10))
        .padding(.top, 5)
    Button(action: {
        withAnimation {
            self.showImagePicker = true
        }
    }) {
        Text("Select Image")
            .color(.init(red: 20/255, green: 146/255, blue: 81/255))
    }
    Button(action: {
        let list = LSList( title: self.name,
                                           image: self.image!,
                                           id: 0)
        list.add()
        self.userData.listsData.append(list)
    }) {
        Text("Add List")
            .color(.white)
            .font(.system(size: 25))
            .bold()
            .padding(.horizontal, 7)
            .frame(height: 35)
            .background(Color.green)
            .clipShape(RoundedRectangle(cornerRadius: 3))
    }
    Spacer()
} .navigationBarTitle(Text("Add List"))

预览中的视图:

我的 iPhone 上的视图:

【问题讨论】:

  • 您的 VStack 是否包含在 NavigationView 中?
  • @MoRezaFarahani 是的

标签: ios swift swiftui


【解决方案1】:
  1. 要使预览中的导航项正确可见(即使对于子视图),您需要将视图包装到 NavigationView { } 中,因为 Canvas 是一个空的干净环境,它不知道视图可能是推入NavigationView
  2. 要在 iPhone 上修复它,请确保您正确推送子视图。应该是NavigationButton(destination: AddList()) {}

RowView 实现示例:

   NavigationButton(destination: CarDetail(car: car)) {
      HStack {
        VStack(alignment: .leading) {
          Text(car.name)
          Text(car.isAvailable ? "Is Available" : "Out of stock")
            .font(.subheadline)
            .foregroundColor(.secondary)
        }
      }
    }

【讨论】:

  • NavigationView { }里面,列表里面的NavigationButton:NavigationButton(destination: AddList().environmentObject(self.userData)) { Text("Add List") }
【解决方案2】:

假设您的VStack 包含在NavigationView 中,这就是它在模拟器中无法正确呈现的原因。它在预览中显示良好的原因是它没有显示导航栏(也包括后退按钮),因为画布不知道这个视图可能会被推送,但在运行时导航栏会在您同时添加也使用额外的 NavigationView。

要修复它,从NavigationView 解包 VStack,然后从子视图中删除此 NavigationView。

【讨论】:

  • 我试图从 VStack 中删除它,但没有任何改变。我将堆栈的背景更改为蓝色,看看它的高度是否正常,就是这样:imgur.com/a/76vQIkG
  • @Shahar 导航栏问题已在您的屏幕截图中修复!它固定在顶部。现在问题可能出在 VStack 上。我会更新我的帖子。
  • @Shahar 删除您添加的任何额外填充/偏移。只需尝试您在问题中提供的代码即可。它对我来说很好用!
  • 如果不想去掉NavigationView,可以在VStack上设置.navigationBarHidden(true)
【解决方案3】:

我有同样的问题,但发现我遇到的问题是多次使用 navigationView。

我认为我们应该在每个视图中都有 NavigationView,但显然,我们应该只将 navigationView 放在应用程序的主视图中,而我们通过 navigationLink 进入的所有其他视图,自动获得后退选项,无需提及再次导航视图。

因此请检查您是否在代码中多次使用 navigationView。

奇怪的是,我们甚至可以在没有提到 navigationView 的视图中指定 navigationBarTitle,这是因为 navigationView 在父视图。 使用“displayMode: .inline”,使导航区域尽可能小,这样可以节省你的空间。

另一件事是使用 Spacer()。 如果您希望所有项目都在顶部,只需将 Spacer() 作为 VStack 中的最后一项,它会将所有项目推到顶部。

看这个例子:

VStack {
    // What you care about displaying
    Text("Something to Show 1")
    Text("Something to Show 2")
    Text("Something to Show 3")

    // This should be the last, put everything to the top
    Spacer()             
}
.navigationBarTitle(Text("The Title"), displayMode: .inline)

【讨论】:

  • 您好 iSpain,我的代码中有 navigationLink,它正在工作,您能分享您的代码吗?
  • 哦,天哪,谢谢。我在子视图作为导航视图时遇到了同样的问题。我没有找到任何说明您应该只使用堆栈顶部的导航视图的文档,但看起来确实是必需的。
  • 这应该是 SwiftUI 添加 VStack(alignment: .leading) { Spacer() } 并将 Spacer() 添加为 VStack 中的最后一个元素的公认答案。
  • 谢谢@Juan Ricardo。我没有提到 (alignment: .leading) 因为它实际上取决于开发人员想要对齐的内容,对齐到 .center 也可以是一个有效的解决方案,这取决于需求。
【解决方案4】:
 ScrollView(.vertical){
   VStack {
    Text("Name:")
        .padding(.bottom, 1)
    TextField($name)
        .padding(.horizontal, 25.0)
        .textFieldStyle(.roundedBorder)
        .frame(maxWidth: 500)
    Text("Image:")
        .padding(.top, 1)
    Image(uiImage: image!)
        .resizable(capInsets: EdgeInsets(), resizingMode: .stretch)
        .scaledToFit()
        .frame(width: 250, height: 250)
        .clipShape(RoundedRectangle(cornerRadius: 10))
        .padding(.top, 5)
    Button(action: {
        withAnimation {
            self.showImagePicker = true
        }
    }) {
        Text("Select Image")
            .color(.init(red: 20/255, green: 146/255, blue: 81/255))
    }
    Button(action: {
        let list = LSList( title: self.name,
                                           image: self.image!,
                                           id: 0)
        list.add()
        self.userData.listsData.append(list)
    }) {
        Text("Add List")
            .color(.white)
            .font(.system(size: 25))
            .bold()
            .padding(.horizontal, 7)
            .frame(height: 35)
            .background(Color.green)
            .clipShape(RoundedRectangle(cornerRadius: 3))
    }
    Spacer()
} .navigationBarTitle(Text("Add List"))
}

【讨论】:

  • 您能否详细说明并向 OP 解释为什么您的代码有效/应该有效?
【解决方案5】:

我有一个类似的问题,我想要一个 VStack 将其内容对齐在屏幕顶部,并且只在父级中使用 NavigationView,但 VStack 显示居中。为我解决的问题是使用 Spacer(),如下所示:

    VStack(alignment: .leading, spacing: 10){
        HStack(alignment: .center, spacing: 5.0) {
            ...
        }
        Group{
            ...
        }
        Spacer() //<-- This solved my problem
   }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-27
    • 2018-04-09
    • 1970-01-01
    • 2015-03-06
    • 1970-01-01
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    相关资源
    最近更新 更多