SwiftUI 视图中的间距不正确
Incorrect Spacing in SwiftUI View
Xcode11.2.1,Swift5
我在 SwiftUI 中有一个自定义视图,我一直在摆弄它一段时间,试图摆脱添加的额外 space。我不知道这是 SwiftUI 本身的错误还是我做错了什么。
查看:
struct Field: View {
@Binding var text: String
var title: String
var placeholderText: String
var leftIcon: Image?
var rightIcon: Image?
var onEditingChanged: (Bool) -> Void = { _ in }
var onCommit: () -> Void = { }
private let height: CGFloat = 47
private let iconWidth: CGFloat = 16
private let iconHeight: CGFloat = 16
init(text: Binding<String>, title: String, placeholder: String, leftIcon: Image? = nil, rightIcon: Image? = nil, onEditingChanged: @escaping (Bool) -> Void = { _ in }, onCommit: @escaping () -> Void = { }) {
self._text = text
self.title = title
self.placeholderText = placeholder
self.leftIcon = leftIcon
self.rightIcon = rightIcon
self.onEditingChanged = onEditingChanged
self.onCommit = onCommit
}
var body: some View {
VStack(alignment: .leading, spacing: 3) {
Text(title.uppercased())
.font(.caption)
.fontWeight(.medium)
.foregroundColor(.primary)
.blendMode(.overlay)
Rectangle()
.fill(Color(red: 0.173, green: 0.173, blue: 0.180))
.blendMode(.overlay)
.cornerRadius(9)
.frame(height: height)
.overlay(
HStack(spacing: 16) {
if leftIcon != nil {
leftIcon!
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: iconWidth, height: iconHeight)
.foregroundColor(.secondary)
}
ZStack(alignment: .leading) {
if text.isEmpty {
Text(placeholderText)
.foregroundColor(.secondary)
.lineLimit(1)
.truncationMode(.tail)
}
TextField("", text: $text, onEditingChanged: onEditingChanged, onCommit: onCommit)
.foregroundColor(.white)
.lineLimit(1)
.truncationMode(.tail)
}
Spacer()
if rightIcon != nil {
rightIcon!
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: iconWidth, height: iconHeight)
.foregroundColor(.secondary)
}
}
.padding(.horizontal, 16)
)
}
}
}
当我像这样创建它的实例时:
struct ContentView: View {
@State var text = ""
let backgroundGradient = Gradient(colors: [
Color(red: 0.082, green: 0.133, blue: 0.255),
Color(red: 0.227, green: 0.110, blue: 0.357)
])
var body: some View {
ZStack {
LinearGradient(gradient: backgroundGradient, startPoint: .top, endPoint: .bottom)
.edgesIgnoringSafeArea(.all)
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
Field(text: $text, title: "field", placeholder: "Required", leftIcon: Image(systemName: "square.and.pencil"), rightIcon: Image(systemName: "info.circle"))
.padding(.horizontal, 30)
}
.onAppear {
UIApplication.shared.windows.forEach { window in
window.overrideUserInterfaceStyle = .dark
}
}
}
}
乍一看,它的行为似乎符合预期:
用户尝试在该字段中键入后出现问题。右边的图标和文本之间的间距太大,导致它被提前截断。
如您所见,文本字段与右侧图标之间的间距(多余间距)比文本字段与左侧图标之间的间距(正确间距)大得多。
Field
的所有元素在所有边上的间距应为 16。出于某种原因,TextField
没有占用足够的空间 space,因此它与右侧图标的间距小于所需的 16。
如何修正这个间距?
您有以下内容:
Spacer()
在以下代码部分之前:
if rightIcon != nil {
rightIcon!
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: iconWidth, height: iconHeight)
.foregroundColor(.secondary)
}
删除 Spacer()
将使左图标和右图标之间的像素相同。
*SwiftUI
///For vertical Custom Spaces
.padding(.vertical, 6)
//For Horizontal
.padding(. horizontal, 6)
//For uniform Spacting
Spacer()
///
Xcode11.2.1,Swift5
我在 SwiftUI 中有一个自定义视图,我一直在摆弄它一段时间,试图摆脱添加的额外 space。我不知道这是 SwiftUI 本身的错误还是我做错了什么。
查看:
struct Field: View {
@Binding var text: String
var title: String
var placeholderText: String
var leftIcon: Image?
var rightIcon: Image?
var onEditingChanged: (Bool) -> Void = { _ in }
var onCommit: () -> Void = { }
private let height: CGFloat = 47
private let iconWidth: CGFloat = 16
private let iconHeight: CGFloat = 16
init(text: Binding<String>, title: String, placeholder: String, leftIcon: Image? = nil, rightIcon: Image? = nil, onEditingChanged: @escaping (Bool) -> Void = { _ in }, onCommit: @escaping () -> Void = { }) {
self._text = text
self.title = title
self.placeholderText = placeholder
self.leftIcon = leftIcon
self.rightIcon = rightIcon
self.onEditingChanged = onEditingChanged
self.onCommit = onCommit
}
var body: some View {
VStack(alignment: .leading, spacing: 3) {
Text(title.uppercased())
.font(.caption)
.fontWeight(.medium)
.foregroundColor(.primary)
.blendMode(.overlay)
Rectangle()
.fill(Color(red: 0.173, green: 0.173, blue: 0.180))
.blendMode(.overlay)
.cornerRadius(9)
.frame(height: height)
.overlay(
HStack(spacing: 16) {
if leftIcon != nil {
leftIcon!
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: iconWidth, height: iconHeight)
.foregroundColor(.secondary)
}
ZStack(alignment: .leading) {
if text.isEmpty {
Text(placeholderText)
.foregroundColor(.secondary)
.lineLimit(1)
.truncationMode(.tail)
}
TextField("", text: $text, onEditingChanged: onEditingChanged, onCommit: onCommit)
.foregroundColor(.white)
.lineLimit(1)
.truncationMode(.tail)
}
Spacer()
if rightIcon != nil {
rightIcon!
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: iconWidth, height: iconHeight)
.foregroundColor(.secondary)
}
}
.padding(.horizontal, 16)
)
}
}
}
当我像这样创建它的实例时:
struct ContentView: View {
@State var text = ""
let backgroundGradient = Gradient(colors: [
Color(red: 0.082, green: 0.133, blue: 0.255),
Color(red: 0.227, green: 0.110, blue: 0.357)
])
var body: some View {
ZStack {
LinearGradient(gradient: backgroundGradient, startPoint: .top, endPoint: .bottom)
.edgesIgnoringSafeArea(.all)
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
Field(text: $text, title: "field", placeholder: "Required", leftIcon: Image(systemName: "square.and.pencil"), rightIcon: Image(systemName: "info.circle"))
.padding(.horizontal, 30)
}
.onAppear {
UIApplication.shared.windows.forEach { window in
window.overrideUserInterfaceStyle = .dark
}
}
}
}
乍一看,它的行为似乎符合预期:
用户尝试在该字段中键入后出现问题。右边的图标和文本之间的间距太大,导致它被提前截断。
如您所见,文本字段与右侧图标之间的间距(多余间距)比文本字段与左侧图标之间的间距(正确间距)大得多。
Field
的所有元素在所有边上的间距应为 16。出于某种原因,TextField
没有占用足够的空间 space,因此它与右侧图标的间距小于所需的 16。
如何修正这个间距?
您有以下内容:
Spacer()
在以下代码部分之前:
if rightIcon != nil {
rightIcon!
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: iconWidth, height: iconHeight)
.foregroundColor(.secondary)
}
删除 Spacer()
将使左图标和右图标之间的像素相同。
*SwiftUI
///For vertical Custom Spaces
.padding(.vertical, 6)
//For Horizontal
.padding(. horizontal, 6)
//For uniform Spacting
Spacer()
///