8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

SwiftUI 中编号列表的布局问题

user6685121 1月前

15 0

我正在开发一个 NumberedList 组件,其工作原理类似于

    HTML 中的标签。我希望能够提供任意数量的元素,这些元素将自动编号和布局。

    我正在开发一个 NumberedList 组件,其功能类似于 <ol> HTML 中的标签。我希望能够提供任意数量的元素,这些元素将自动编号和布局。但是布局方面有一个方面我不太清楚。

    我已经创建了一个 OrderedList 视图(相当于 <ol> HTML 标签),它使用了一个 _VariadicView.Tree 自定义 _VariadicView_UnaryViewRoot 布局。

    public struct OrderedList<Content: View>: View {
        let content: Content
        
        @Environment(\.listLevel)
        var level
        
        public init(@ViewBuilder content: () -> Content) {
            self.content = content()
        }
        
        public var body: some View {
            let layout = OrderedListLayout(level: level)
            
            _VariadicView.Tree(layout) {
                content
            }
        }
    }
    
    struct OrderedListLayout: _VariadicView_UnaryViewRoot {
        let level: ListLevel
        
        @ViewBuilder
        func body(children: _VariadicView.Children) -> some View {
            let padding: Double = switch level {
            case .first:
                8
            case .second, .third:
                -6
            }
            
            VStack(alignment: .leading, spacing: 8) {
                ForEach(Array(children.enumerated()), id: \.element.id) { index, child in
                    HStack(alignment: .centerOfFirstLine, spacing: 8) {
                        Text(verbatim: "\(index + 1).")
                        
                        child
                    }
                }
            }
            .frame(maxWidth: .infinity, alignment: .leading)
            .padding(.leading, padding)
        }
    }
    

    视图(相当于 ListElement 一起使用 <li> ,它可以包含任意标签和可选子视图。

    public struct ListElement<Label: View, Child: View>: View {
        let label: Label
        
        let child: Child?
        
        @Environment(\.listLevel)
        var level
        
        public init(@ViewBuilder label: () -> Label, @ViewBuilder child: () -> Child) {
            self.label = label()
            self.child = child()
        }
        
        public var body: some View {
            VStack(alignment: .leading, spacing: 8) {
                label
                
                if let child {
                    child
                        .environment(\.listLevel, level.next())
                }
            }
        }
    }
    
    public extension ListElement where Child == EmptyView {
        init(@ViewBuilder label: () -> Label) {
            self.label = label()
            self.child = nil
        }
    }
    

    此屏幕截图 显示了当前结果。我为编号文本添加了绿色边框,为列表元素添加了蓝色边框,以更好地显示它们未对齐的情况。我希望能够布局元素,以便同一列表级别中所有元素的前导都对齐。本质上,我希望所有编号文本具有相同的宽度。

    从技术上讲,我可以使用 来 Grid 帮助实现这种布局。但是,我认为这行不通,因为我希望能够在需要时嵌套多个列表。我认为解决方案可能是使用自定义 HorizontalAlignment 指南或自定义 Layout ,但我不太明白。

帖子版权声明 1、本帖标题:SwiftUI 中编号列表的布局问题
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由user6685121在本站《swift》版块原创发布, 转载请注明出处!
最新回复 (0)
返回
作者最近主题: