在 SwiftUI 中显示行/分隔符视图
Show line / separator view in SwiftUI
我想在我的 SwiftUI 应用程序中显示分隔线。为此,我尝试创建一个具有固定框架和背景颜色/边框的空视图:
EmptyView()
.frame(width: 200, height: 2)
.background(Color.black) // or:
.border(Color.black, width: 2)
遗憾的是,我看不到任何暗视图。
有没有办法显示分隔符/行视图?
使用Divider:
A visual element that can be used to separate other content.
示例:
struct ContentView : View {
var body: some View {
VStack {
Text("Hello World")
Divider()
Text("Hello Another World")
}
}
}
输出:
如果有人对分隔线、文本、分隔线感兴趣,如下所示:
LabelledDivider
代码
struct LabelledDivider: View {
let label: String
let horizontalPadding: CGFloat
let color: Color
init(label: String, horizontalPadding: CGFloat = 20, color: Color = .gray) {
self.label = label
self.horizontalPadding = horizontalPadding
self.color = color
}
var body: some View {
HStack {
line
Text(label).foregroundColor(color)
line
}
}
var line: some View {
VStack { Divider().background(color) }.padding(horizontalPadding)
}
}
有点难看,但我必须将 Divider
放入 VStack
中才能使它们水平,否则,由于 HStack
,它们将是垂直的。如果您设法简化了这一点,请告诉我 :)
也可能使用和存储 LabelledDivider
的属性可能不是最 SwiftUI
-y 的解决方案,所以我愿意改进。
用法示例
这是生成上面屏幕截图的代码:
struct GetStartedView: View {
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: SignInView()) {
Text("Sign In").buttonStyleEmerald()
}
LabelledDivider(label: "or")
NavigationLink(destination: SignUpView()) {
Text("Sign up").buttonStyleSaphire()
}
}.padding(20)
}
}
}
按钮样式
为了完整起见,我还包括 buttonStyle
视图修饰符:
struct ButtonStyle: ViewModifier {
private let color: Color
private let enabled: () -> Bool
init(color: Color, enabled: @escaping () -> Bool = { true }) {
self.color = color
self.enabled = enabled
}
dynamic func body(content: Content) -> some View {
content
.padding()
.frame(minWidth: 0, maxWidth: .infinity, alignment: .center)
.foregroundColor(Color.white)
.background(enabled() ? color : Color.black)
.cornerRadius(5)
}
}
extension View {
dynamic func buttonStyleEmerald(enabled: @escaping () -> Bool = { true }) -> some View {
ModifiedContent(content: self, modifier: ButtonStyle(color: Color.emerald, enabled: enabled))
}
dynamic func buttonStyleSaphire(enabled: @escaping () -> Bool = { true }) -> some View {
ModifiedContent(content: self, modifier: ButtonStyle(color: Color.saphire, enabled: enabled))
}
}
编辑:请注意 Color.saphire
和 Color.emerald
是自定义声明的颜色:
extension Color {
static var emerald: Color { .rgb(036, 180, 126) }
static var forest: Color { .rgb(062, 207, 142) }
}
extension Color {
static func rgb(_ red: UInt8, _ green: UInt8, _ blue: UInt8) -> Color {
func value(_ raw: UInt8) -> Double {
return Double(raw)/Double(255)
}
return Color(
red: value(red),
green: value(green),
blue: value(blue)
)
}
}
您可以只使用颜色画一条线。如果你想改变线宽或填充,你可以像其他 SwiftUI 组件一样使用 frame
或 padding
。
//Horizontal Line in VStack
VStack{
Color.gray.frame(height:CGFloat(1) / UIScreen.main.scale)
}
//Vertical Line in HStack
HStack{
Color.gray.frame(width:CGFloat(1) / UIScreen.main.scale)
}
如果您正在寻找一种自定义分隔线的方法,那么这里没有。您必须提供自定义实现:
struct CustomDivider: View {
let height: CGFloat = 1
let color: Color = .white
let opacity: Double = 0.2
var body: some View {
Group {
Rectangle()
}
.frame(height: height)
.foregroundColor(color)
.opacity(opacity)
}
}
我想在我的 SwiftUI 应用程序中显示分隔线。为此,我尝试创建一个具有固定框架和背景颜色/边框的空视图:
EmptyView()
.frame(width: 200, height: 2)
.background(Color.black) // or:
.border(Color.black, width: 2)
遗憾的是,我看不到任何暗视图。
有没有办法显示分隔符/行视图?
使用Divider:
A visual element that can be used to separate other content.
示例:
struct ContentView : View {
var body: some View {
VStack {
Text("Hello World")
Divider()
Text("Hello Another World")
}
}
}
输出:
如果有人对分隔线、文本、分隔线感兴趣,如下所示:
LabelledDivider
代码
struct LabelledDivider: View {
let label: String
let horizontalPadding: CGFloat
let color: Color
init(label: String, horizontalPadding: CGFloat = 20, color: Color = .gray) {
self.label = label
self.horizontalPadding = horizontalPadding
self.color = color
}
var body: some View {
HStack {
line
Text(label).foregroundColor(color)
line
}
}
var line: some View {
VStack { Divider().background(color) }.padding(horizontalPadding)
}
}
有点难看,但我必须将 Divider
放入 VStack
中才能使它们水平,否则,由于 HStack
,它们将是垂直的。如果您设法简化了这一点,请告诉我 :)
也可能使用和存储 LabelledDivider
的属性可能不是最 SwiftUI
-y 的解决方案,所以我愿意改进。
用法示例
这是生成上面屏幕截图的代码:
struct GetStartedView: View {
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: SignInView()) {
Text("Sign In").buttonStyleEmerald()
}
LabelledDivider(label: "or")
NavigationLink(destination: SignUpView()) {
Text("Sign up").buttonStyleSaphire()
}
}.padding(20)
}
}
}
按钮样式
为了完整起见,我还包括 buttonStyle
视图修饰符:
struct ButtonStyle: ViewModifier {
private let color: Color
private let enabled: () -> Bool
init(color: Color, enabled: @escaping () -> Bool = { true }) {
self.color = color
self.enabled = enabled
}
dynamic func body(content: Content) -> some View {
content
.padding()
.frame(minWidth: 0, maxWidth: .infinity, alignment: .center)
.foregroundColor(Color.white)
.background(enabled() ? color : Color.black)
.cornerRadius(5)
}
}
extension View {
dynamic func buttonStyleEmerald(enabled: @escaping () -> Bool = { true }) -> some View {
ModifiedContent(content: self, modifier: ButtonStyle(color: Color.emerald, enabled: enabled))
}
dynamic func buttonStyleSaphire(enabled: @escaping () -> Bool = { true }) -> some View {
ModifiedContent(content: self, modifier: ButtonStyle(color: Color.saphire, enabled: enabled))
}
}
编辑:请注意 Color.saphire
和 Color.emerald
是自定义声明的颜色:
extension Color {
static var emerald: Color { .rgb(036, 180, 126) }
static var forest: Color { .rgb(062, 207, 142) }
}
extension Color {
static func rgb(_ red: UInt8, _ green: UInt8, _ blue: UInt8) -> Color {
func value(_ raw: UInt8) -> Double {
return Double(raw)/Double(255)
}
return Color(
red: value(red),
green: value(green),
blue: value(blue)
)
}
}
您可以只使用颜色画一条线。如果你想改变线宽或填充,你可以像其他 SwiftUI 组件一样使用 frame
或 padding
。
//Horizontal Line in VStack
VStack{
Color.gray.frame(height:CGFloat(1) / UIScreen.main.scale)
}
//Vertical Line in HStack
HStack{
Color.gray.frame(width:CGFloat(1) / UIScreen.main.scale)
}
如果您正在寻找一种自定义分隔线的方法,那么这里没有。您必须提供自定义实现:
struct CustomDivider: View {
let height: CGFloat = 1
let color: Color = .white
let opacity: Double = 0.2
var body: some View {
Group {
Rectangle()
}
.frame(height: height)
.foregroundColor(color)
.opacity(opacity)
}
}