我正在尝试从 SwiftUI 中删除“行”分隔符(在 SwiftUI 中称为分隔符)List
。
我浏览了List
文档,但我无法找到修改器。
任何帮助,将不胜感激。
今年 Apple 推出了一种新的修饰符.listRowSeparator
,可用于设置分隔符的样式。你可以通过.hidden
隐藏它:
List {
ForEach(items, id:\.self) {
Text("Row \($0)")
.listRowSeparator(.hidden)
}
}
AppleLazyVStack
在 iOS 14 中引入。您可以考虑使用它而不是列表:
ScrollView {
LazyVStack {
ForEach((1...100), id: \.self) {
Text("Placeholder \($0)")
}
}
}
请记住,这LazyVStack
是惰性的,并且不会一直呈现所有行。因此它们的性能非常好,并且是 Apple 自己在 WWDC 2020 中提出的。
iOS的UITableView
SwiftUI有其背后的原因。List
所以要删除
你需要一个tableFooterView
and 删除
你separatorStyle
需要.none
init() {
// To remove only extra separators below the list:
UITableView.appearance().tableFooterView = UIView()
// To remove all separators including the actual ones:
UITableView.appearance().separatorStyle = .none
}
var body: some View {
List {
Text("Item 1")
Text("Item 2")
Text("Item 3")
}
}
虽然此解决方案正常工作,但让我们使用
ViewModifier
public struct ListSeparatorStyleNoneModifier: ViewModifier {
public func body(content: Content) -> some View {
content.onAppear {
UITableView.appearance().separatorStyle = .none
}.onDisappear {
UITableView.appearance().separatorStyle = .singleLine
}
}
}
现在让我们做一个有助于隐藏细节的小扩展
extension View {
public func listSeparatorStyleNone() -> some View {
modifier(ListSeparatorStyleNoneModifier())
}
}
如您所见,我们已将外观设置代码包装到一个简洁的小视图修饰符中。你现在可以直接声明
List {
Text("1")
Text("2")
Text("3")
}.listSeparatorStyleNone()
您可以在没有任何样式的情况下使用ForEach
within aScrollView
而不是动态视图List
使用 . 查看现有答案UITableView.appearance()
。
⚠️ 请注意,在 iOS 14 SDK 中,List
似乎不支持UITableView
. 请参阅下面的替代解决方案:
我确实有一个适用于 iOS 14 的纯 SwiftUI 解决方案,但谁知道它会继续工作多久。它依赖于您的内容与默认列表行的大小相同(或更大)并且具有不透明的背景。
⚠️ 这不适用于 iOS 13 版本。
在 Xcode 12 beta 1 中测试:
yourRowContent
.padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16))
.frame(
minWidth: 0, maxWidth: .infinity,
minHeight: 44,
alignment: .leading
)
.listRowInsets(EdgeInsets())
.background(Color.white)
或者,如果您正在寻找可重复使用的ViewModifier
:
import SwiftUI
struct HideRowSeparatorModifier: ViewModifier {
static let defaultListRowHeight: CGFloat = 44
var insets: EdgeInsets
var background: Color
init(insets: EdgeInsets, background: Color) {
self.insets = insets
var alpha: CGFloat = 0
UIColor(background).getWhite(nil, alpha: &alpha)
assert(alpha == 1, "Setting background to a non-opaque color will result in separators remaining visible.")
self.background = background
}
func body(content: Content) -> some View {
content
.padding(insets)
.frame(
minWidth: 0, maxWidth: .infinity,
minHeight: Self.defaultListRowHeight,
alignment: .leading
)
.listRowInsets(EdgeInsets())
.background(background)
}
}
extension EdgeInsets {
static let defaultListRowInsets = Self(top: 0, leading: 16, bottom: 0, trailing: 16)
}
extension View {
func hideRowSeparator(
insets: EdgeInsets = .defaultListRowInsets,
background: Color = .white
) -> some View {
modifier(HideRowSeparatorModifier(
insets: insets,
background: background
))
}
}
struct HideRowSeparator_Previews: PreviewProvider {
static var previews: some View {
List {
ForEach(0..<10) { _ in
Text("Text")
.hideRowSeparator()
}
}
.previewLayout(.sizeThatFits)
}
}
当前的解决方法是通过以下方式删除它们UIAppearance
:
UITableView.appearance(whenContainedInInstancesOf:
[UIHostingController<ContentView>.self]
).separatorStyle = .none
添加UITableView.appearance().separatorColor = .clear
初始化器
struct SomeView: View {
init() {
UITableView.appearance().separatorColor = .clear
}
}
我希望你能解决这个问题。
来自:Swiftui Views Mastery Book SwiftUI 2.0 Mark Moeykens
.listStyle(SidebarListStyle()) # IOS 14
您可以应用这种新的列表样式,它将删除分隔线。
extension View {
/// 隐藏 List 中的 分割线
func hideRowSeparator(insets: EdgeInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0),
background: Color = .white) -> some View {
modifier(HideRowSeparatorModifier(insets: insets, background: background))
}
}
struct HideRowSeparatorModifier: ViewModifier {
static let defaultListRowHeight: CGFloat = 44
var insets: EdgeInsets
var background: Color
init(insets: EdgeInsets, background: Color) {
self.insets = insets
var alpha: CGFloat = 0
if #available(iOS 14.0, *) {
UIColor(background).getWhite(nil, alpha: &alpha)
assert(alpha == 1, "Setting background to a non-opaque color will result in separators remaining visible.")
}
self.background = background
}
func body(content: Content) -> some View {
content
.padding(insets)
.frame(minWidth: 0, maxWidth: .infinity, minHeight: Self.defaultListRowHeight)
.listRowInsets(EdgeInsets())
.overlay(
VStack {
HStack {}
.frame(maxWidth: .infinity)
.frame(height: 1)
.background(background)
Spacer()
HStack {}
.frame(maxWidth: .infinity)
.frame(height: 1)
.background(background)
}
.padding(.top, -1)
)
}
}
struct ContentView: View {
var body: some View {
List {
ForEach(0 ..< 30) { item in
HStack(alignment: .center, spacing: 30) {
Text("Hello, world!:\(item)").padding()
}
.hideRowSeparator(background: .white)
}
}
.listStyle(PlainListStyle())
}
}
https://github.com/wangrui460/HiddenListLine4SwiftUI
我创建了一个微信iOS技术交流群、SwiftUI技术交流群,欢迎小伙伴们一起加入交流学习~
可以加我微信我拉你进去(备注iOS),我的微信号wr1204607318