SwiftUI - 列表行分隔符插入,如 iOS 设置应用程序

Posted

技术标签:

【中文标题】SwiftUI - 列表行分隔符插入,如 iOS 设置应用程序【英文标题】:SwiftUI - List Line Separator Inset like iOS Settings App 【发布时间】:2022-01-16 08:40:54 【问题描述】:

我正在尝试实现在 ios 设置应用程序或例如 Roborock 应用程序中也可以看到的行为(请参见下面的屏幕截图)。我想选择一个图标,然后在行分隔符中插入一个。

我已经试过了

UITableView.appearance().separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 80)

但这不适用于 SwiftUI 3.0 / iOS 15.1

这是完整的代码:

import SwiftUI

struct ListTest: View 
    var body: some View 
        List 
            
            Button(action: 
                print("Test")
            ) 
                SettingsCell2(title: "Test", iconName: "bell.badge.fill")
            
            
            Button(action: 
                print("Test")
            ) 
                SettingsCell2(title: "Test", iconName: "bell.badge.fill")
            
        
    


struct SettingsCell2: View 
    
    var title : String
    var iconName : String
    
    var body: some View 
        HStack 
            
            ZStack 

                RoundedRectangle(cornerRadius: 8, style: .continuous)
                    .fill(Color.red)
                
                Image(systemName: iconName)
                    .foregroundColor(.white)

            
            .frame(width: 30, height: 30, alignment: .center)

            Text(title)
                .foregroundColor(.primary)
            
            Spacer()
            
            Image(systemName: "chevron.right")
                .font(.headline)
                .foregroundColor(.gray)

        

    


struct ListTest_Previews: PreviewProvider 
    static var previews: some View 
        ListTest()
    


有什么想法可以实现吗?

非常感谢!

【问题讨论】:

你试过答案了吗? 【参考方案1】:

在 iOS 15 中,您可以隐藏 listRowSeparator 并创建自己的 listRowBackground

import SwiftUI
@available(iOS 15.0, *)
struct SettingsDuplicateView: View 
    let symbols = [ "camera": Color.gray, "hand.raised.fill": Color.blue, "antenna.radiowaves.left.and.right": Color.green, "speaker.wave.2": Color.red]
    var body: some View 
        NavigationView
            Form 
                ForEach(Array(symbols.keys), id: \.self)  item in
                    GeometryReader geo in
                        NavigationLink(destination: 
                            Text(item)
                        , label: 
                            HStack
                                SettingsIconView(imageSystemName: item, color: symbols[item] ?? .gray )
                                    .frame(width: geo.size.height)
                                Text(item)
                            
                        )
                        
                    
                    //Create your own background
                    .listRowBackground(
                        ZStack
                            Color(UIColor.systemBackground)
                            //Use a custom shape to create the divider
                            MyDivider().stroke(Color.gray)
                        
                    )
                
                //Hide the built-in separator
                .listRowSeparator(.hidden)
            
        
    

struct SettingsIconView: View
    let imageSystemName: String
    let color: Color
    @ScaledMetric(relativeTo: .body) var imageSize: CGFloat = 6
    var body: some View
        RoundedRectangle(cornerSize: CGSize(width: 5, height: 5))
            .foregroundColor(color)
            .overlay(
                Image(systemName: imageSystemName)
                    //Keep the symbol proportional
                    .scaledToFit()
                    //The padding will adjust for the different screen sized
                    .padding(imageSize)
            )
            .aspectRatio(1, contentMode: .fit)
    


struct MyDivider: Shape
    //You can create a custom variable so it can come from the parent
    let offset: CGFloat = 60
    func path(in rect: CGRect) -> Path 
        var path = Path()
        //Adjust the offset here as needed
        //Add the desired offset.
        path.move(to: CGPoint(x: rect.minX + rect.maxY * 1.25, y: rect.maxY))
        path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))
        return path
    

@available(iOS 15.0, *)
struct SettingsDuplicateView_Previews: PreviewProvider 
    static var previews: some View 
        SettingsDuplicateView()
    

【讨论】:

以上是关于SwiftUI - 列表行分隔符插入,如 iOS 设置应用程序的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI隐藏List分隔符的不同方法

iOS 16 SwiftUI列表(List)项包含 Label 视图导致分隔线变短的解决

iOS 16 SwiftUI列表(List)项包含 Label 视图导致分隔线变短的解决

iOS 16 SwiftUI 4.0 列表(List)项分隔线变短的原因及解决

iOS 16 SwiftUI 4.0 列表(List)项分隔线变短的原因及解决

iOS 16 SwiftUI 4.0 列表(List)项分隔线变短的原因及解决