75142913在线留言
【SwiftUI基础篇】7 几种分组显示Group、GroupBox、DisclosureGroup、OutlineGroup_IOS开发_网络人

【SwiftUI基础篇】7 几种分组显示Group、GroupBox、DisclosureGroup、OutlineGroup

Kwok 发表于:2021-04-02 12:02:54 点击:60 评论: 0

很多时候我们需要对视图合并起来处理样式,SwiftUI里提供了几种Group,为了很好的区别他们的关系,我整理了带Group单词的放到一起来说。方便记忆与区分。

一、Group 视图分组

如果您需要多个视图作为一个视图(例如,一起过渡),则应使用SwiftUI的Group视图。这一点特别重要,因为出于根本的技术原因,一次最多只能将10个视图添加到父视图

超过10个视图,编译器就会开始报错了Extra argument in call:

VStack {
    Text("第一行")
    Text("第二行")
    Text("第三行")
    Text("第四行")
    Text("第五行")
    Text("第六行")
    Text("第七行")
    Text("第八行")
    Text("第九行")
    Text("第十行")
    Text("第十一行")//报错:Extra argument in call
}

这是因为SwiftUI的视图构建系统具有各种代码,旨在让我们添加1个视图,2个视图,3个视图或4、5、6、7、8、9和10个视图,但不能添加11个或更多视图。

这时候Group就派上用场了:

VStack {
    Group {
        Text("第一行")
        Text("第二行")
        Text("第三行")
        Text("第四行")
        Text("第五行")
    }
    .font(.title)//批量设置Text的字号
    Group {
        Text("第六行")
        Text("第七行")
        Text("第八行")
        Text("第九行")
        Text("第十行")
        Text("第十一行")
    }.foregroundColor(.blue)//设置Group的颜色
}

这样编辑器就不会再报错了,我们可以超出10个视图的限制,因为VStack现在只能包含两个视图(两个Group组)。

Group与 Section(分组) 都有分组功能,他们也是有一些区别的,Group可以做为一个空视图返回给一个View,而Section主要用于List与From,自动设置一些样式,所以可以根据情况选择不同的分组。

 二、GroupBox 带标题的组

是一个带有可选标签的程式化视图,该标签与内容的逻辑分组相关联。GroupBox 由两部分组成:可选的标签部分和主题的内容部分。

GroupBox(label: Label("完成事项",systemImage: "checkmark.circle.fill")) {
    Text("跑步10仅是~ok")
    Text("看书2小时~ok")
    Text("调戏女同事被开除~ok")
}

其label是可选项,不设置则不会显示。GroupBox在不设置label的情况下与Group的差别就是它自带了显示的样式。

SwiftUI会自动为GroupBox设置边框与背景等,如果需要自己定义这些需要我们就需要使用到 .groupBoxStyle()。自己定义的样式需要符合protocol 协议 GroupBoxStyle。

//定义一个符合GroupBoxStyle协议的结构体用于用户按下时的样式设置
struct customStyle: GroupBoxStyle {
    func makeBody(configuration: Configuration) -> some View {
        //返回VStack与自己定义的样式
        VStack(alignment: .leading) {
            configuration.label //设置标题样式
                .font(.title)
            configuration.content//设置内容样式
                .foregroundColor(.blue)
        }
        .padding()
        .background(Color.red)
        .clipShape(RoundedRectangle(cornerRadius: 8, style: .continuous))
    }
}

然后在GroupBox的后面加上参数:

.groupBoxStyle(customStyle())

即可完成了一个自定义的GroupBox样式。灵活性还是很不错的。

三、DisclosureGroup 分组显示内容

SwiftUI具有专用DisclosureGroup视图来呈现公开指示器并在其中包含内容。这可以绑定到某种布尔型属性,该布尔型属性确定内容当前是否可见,可以在其中放置许多视图以在展开时显示。

DisclosureGroup根据显示控件的状态(isExpanded)显示或隐藏另一个内容视图的视图。可用来分组显示内容,并可以通过 isExpanded 参数来控制内容默认是展开的还是折叠起来的,默认是折叠起来的。

例如,下面代码将创建一个DisclosureGroup内部包含大量文本的,默认情况下该文本将被隐藏的,需要用户将需要打开显示它:

struct ContentView: View {
    @State private var revealDetails = false
    var body: some View {
        DisclosureGroup("显示介绍", isExpanded: $revealDetails) {
            Text("这可能是一个很长的文本介绍内容,我在这里之所以没有写这么长,是因为我打字太累了,真的不想写这么多,我写了这么多废话你都还在看,你说你也够无聊的,看了这么多无聊的内容你为啥不给我点个赞,收藏、转发之类的。。。")
        }
        .frame(width: 300)
    }
}

当然我们可以实现一个联动的开关(这是官方代码翻译后的样子):

struct ContentView: View {
    struct ToggleStates {
        var oneIsOn: Bool = true //第一个初始状态
        var twoIsOn: Bool = false//第二个状态
    }
    @State private var toggleStates = ToggleStates()
    @State private var topExpanded: Bool = true
    var body: some View {
        DisclosureGroup("项目展示", isExpanded: $topExpanded) {
            Toggle("切换项目1", isOn: $toggleStates.oneIsOn)
            Toggle("详情的开关", isOn: $toggleStates.twoIsOn)
            DisclosureGroup("下面是详情哦~" , isExpanded: $toggleStates.twoIsOn) {
                Text("没有详细")
            }
        }
    }
}

四、OutlineGroup 树状结构组

OutlineGroup是一种类似于树的结构,根据需要从树状结构的识别数据的基础集合中计算视图和公开组。是用来显示树形结构的数据的空间。在下面例子中,我们的数据类型是描述的文件,有文件和文件夹的区别OutlineGroup 会自动遍历文件夹的所有子文件,从而绘制出嵌套的树形 UI。

1、先定义一个数据结构,用于目录信息:

//符合哈希、ID、自定义字符串转换协议
struct FileItem: Hashable, Identifiable, CustomStringConvertible {
    var id: Self { self }//Identifiable协议
    var name: String
    var children: [FileItem]? = nil
    var description: String {
        switch children {
        case nil:
            return "文件:(name)"
        case .some(let children):
            return children.isEmpty ? "目录:(name)" : "目录:(name)"
        }
    }
}

然后准备我们要使用OutlineGroup展示的一组数据:

let data =FileItem(name: "主目录", children:
       [FileItem(name: "用户文件夹", children:
       [FileItem(name: "照片文件夹", children:
          [FileItem(name: "照片.jpg"),
          FileItem(name: "照片2.jpg")]),
       FileItem(name: "电视文件夹", children:
       [FileItem(name: "视频.mp4")]),
          FileItem(name: "文档", children: [])
       ]),
       FileItem(name: "新文件夹", children:
         [FileItem(name: "子文档夹", children: [])
       ])
])

最后使用 OutlineGroup 展示上面的数据。即是一个可展开的偏历所有目录与文件夹:

OutlineGroup(data, children: .children) { item in
    Text("(item.description)")
}

注意,OutlineGroup 和 DisclosureGroup 的区别:OutlineGroup是传入的数据为树形接口,自动生成 UI,而DisclosureGroup 则是我们设计的树形 UI。

除非注明,网络人的文章均为原创,转载请以链接形式标明本文地址:https://www.55mx.com/post/121
标签:Group分组Kwok最后编辑于:2021-04-03 12:03:11
0
感谢打赏!

《【SwiftUI基础篇】7 几种分组显示Group、GroupBox、DisclosureGroup、OutlineGroup》的网友评论(0)

本站推荐阅读

热门点击文章