我尝试为 MacOS 做一个测试项目,因为我目前正在学习 Swift/SwiftUI 并遇到了表单和切换元素的问题。当我添加一个切换元素时,一切看起来都应该如此,但是一旦我添加 .switch 样式,表单的每个新“行”都会与 Switch 的开头对齐。
我尝试说唱 Groups、VStacks 之类的东西,但没有任何帮助。 这是我的代码:
import SwiftUI
import Foundation`
let serverNameList = ["HTTP Server", "Test", "IOT", "Messenger"]
// view
struct ContentView: View {
// state variables
@State private var companiesExpanded = true
@State private var isHTTPServerOn = true
// body
var body: some View {
VStack {
var serverImage = Image(systemName: "globe")
.padding(10.0)
.imageScale(.large)
.foregroundStyle(.tint)
NavigationSplitView {
DisclosureGroup(isExpanded: $companiesExpanded) {
ForEach(serverNameList, id: \.self) { serverName in
NavigationLink(destination: Text("Destination")) {
Label {
Text(serverName)
} icon: {
Image(systemName: "server.rack")
.foregroundStyle(Color.blue)
}
.frame(minWidth: 100,
idealWidth: 200,
maxWidth: 300,
alignment: .leading)
.padding(5)
}
.buttonStyle(PlainButtonStyle())
.navigationSubtitle("Subtitle")
}
} label: {
Text("Server")
.font(.subheadline)
.fontWeight(.semibold)
}
.padding(.horizontal, 10)
.frame(minWidth: 120,
idealWidth: 180,
maxWidth: 350,
minHeight: 120,
idealHeight: 300,
alignment: .top)
Spacer()
} detail: {
VStack(alignment: .leading) {
HStack(alignment: .top) {
// form 1
Form {
HStack {
Text("Name")
.frame(minWidth: 100,
idealWidth: 100,
maxWidth: 150,
minHeight: 25,
idealHeight: 30,
maxHeight: 40,
alignment: .leading)
Text("HTTP Server")
.frame(minWidth: 120,
idealWidth: 200,
maxWidth: 220,
minHeight: 25,
idealHeight: 30,
maxHeight: 40,
alignment: .trailing)
}
Divider()
HStack {
Text("Version")
.frame(minWidth: 100,
idealWidth: 100,
maxWidth: 150,
minHeight: 25,
idealHeight: 30,
maxHeight: 40,
alignment: .leading)
Text("0.13.2")
.frame(minWidth: 120,
idealWidth: 200,
maxWidth: 220,
minHeight: 25,
idealHeight: 30,
maxHeight: 40,
alignment: .trailing)
}
Divider()
HStack {
Text("Status")
.frame(minWidth: 100,
idealWidth: 100,
maxWidth: 150,
minHeight: 25,
idealHeight: 30,
maxHeight: 40,
alignment: .leading)
HStack {
Image(systemName: "circle.fill")
.foregroundStyle(Color.green)
.frame(width: 8,
height: 8,
alignment: .center)
Text("ONLINE")
}
.frame(minWidth: 120,
idealWidth: 200,
maxWidth: 220,
minHeight: 25,
idealHeight: 30,
maxHeight: 40,
alignment: .trailing)
}
Divider()
HStack {
Text("Domain")
.frame(minWidth: 100,
idealWidth: 100,
maxWidth: 150,
minHeight: 25,
idealHeight: 30,
maxHeight: 40,
alignment: .leading)
Text("IPv4")
.frame(minWidth: 120,
idealWidth: 200,
maxWidth: 220,
minHeight: 25,
idealHeight: 30,
maxHeight: 40,
alignment: .trailing)
}
Divider()
HStack {
Text("Connections")
.frame(minWidth: 100,
idealWidth: 100,
maxWidth: 150,
minHeight: 25,
idealHeight: 30,
maxHeight: 40,
alignment: .leading)
Text("6")
.frame(minWidth: 120,
idealWidth: 200,
maxWidth: 220,
minHeight: 25,
idealHeight: 30,
maxHeight: 40,
alignment: .trailing)
}
Divider()
HStack {
Text("Owner")
.frame(minWidth: 100,
idealWidth: 100,
maxWidth: 150,
minHeight: 25,
idealHeight: 30,
maxHeight: 40,
alignment: .leading)
Text("Max Mustermann")
.frame(minWidth: 120,
idealWidth: 200,
maxWidth: 220,
minHeight: 25,
idealHeight: 30,
maxHeight: 40,
alignment: .trailing)
}
}
.padding(10)
.frame(minWidth: 260,
idealWidth: 300,
maxWidth: 370,
minHeight: 210,
idealHeight: 240,
maxHeight: 300,
alignment: .topLeading)
.overlay(RoundedRectangle(cornerRadius: 6)
.stroke(Color.black.opacity(0.1),
lineWidth: 1))
// form 2
Form {
HStack {
Text(isHTTPServerOn ? "Turn off" : "Turn on")
Toggle("", isOn: $isHTTPServerOn)
.toggleStyle(.switch)
.frame(minWidth: 120,
idealWidth: 200,
maxWidth: 220,
minHeight: 25,
idealHeight: 30,
maxHeight: 40,
alignment: .trailing)
}
Divider()
HStack {
Text("Version")
.frame(minWidth: 100,
idealWidth: 100,
maxWidth: 150,
minHeight: 25,
idealHeight: 30,
maxHeight: 40,
alignment: .leading)
Text("0.13.2")
.frame(minWidth: 120,
idealWidth: 200,
maxWidth: 220,
minHeight: 25,
idealHeight: 30,
maxHeight: 40,
alignment: .trailing)
}
Divider()
HStack {
Text("Status")
.frame(minWidth: 100,
idealWidth: 100,
maxWidth: 150,
minHeight: 25,
idealHeight: 30,
maxHeight: 40,
alignment: .leading)
HStack {
Image(systemName: "circle.fill")
.foregroundStyle(Color.green)
.frame(width: 8,
height: 8,
alignment: .center)
Text("ONLINE")
}
.frame(minWidth: 120,
idealWidth: 200,
maxWidth: 220,
minHeight: 25,
idealHeight: 30,
maxHeight: 40,
alignment: .trailing)
}
Divider()
HStack {
Text("Domain")
.frame(minWidth: 100,
idealWidth: 100,
maxWidth: 150,
minHeight: 25,
idealHeight: 30,
maxHeight: 40,
alignment: .leading)
Text("IPv4")
.frame(minWidth: 120,
idealWidth: 200,
maxWidth: 220,
minHeight: 25,
idealHeight: 30,
maxHeight: 40,
alignment: .trailing)
}
Divider()
HStack {
Text("Connections")
.frame(minWidth: 100,
idealWidth: 100,
maxWidth: 150,
minHeight: 25,
idealHeight: 30,
maxHeight: 40,
alignment: .leading)
Text("6")
.frame(minWidth: 120,
idealWidth: 200,
maxWidth: 220,
minHeight: 25,
idealHeight: 30,
maxHeight: 40,
alignment: .trailing)
}
Divider()
HStack {
Text("Owner")
.frame(minWidth: 100,
idealWidth: 100,
maxWidth: 150,
minHeight: 25,
idealHeight: 30,
maxHeight: 40,
alignment: .leading)
Text("Max Mustermann")
.frame(minWidth: 120,
idealWidth: 200,
maxWidth: 220,
minHeight: 25,
idealHeight: 30,
maxHeight: 40,
alignment: .trailing)
}
}
.padding(10)
.frame(minWidth: 260,
idealWidth: 300,
maxWidth: 370,
minHeight: 210,
idealHeight: 240,
maxHeight: 300,
alignment: .topLeading)
.overlay(RoundedRectangle(cornerRadius: 6)
.stroke(Color.black.opacity(0.1),
lineWidth: 1))
}
}
.padding(1)
.frame(minWidth: 4 * 10 + 220 + 2,
idealWidth: 3*(300+2),
maxWidth: .infinity,
minHeight: 1*(210+2),
idealHeight: 3*(240+2),
maxHeight: .infinity,
alignment: .topLeading)
}
}
}
}
#Preview {
ContentView()
}
这是它大致外观的屏幕截图(这里的toogle 没有.switch 样式):
这是它的实际外观:
提前谢谢大家!
编辑:
@Radioactive 是对的。在我将表单更改为 VStack 后,一切看起来都应该如此。谢谢@Radioactive!尽管如此,表单中的切换以这种方式运行还是很奇怪。是否可以通过任何形式联系 Apple 提及此问题?