zoukankan      html  css  js  c++  java
  • SwiftUI 九

    让不同类型支持ForEach

    什么是ForEach

    SwiftUI的ForEach类型使我们能够通过转换集合中的每个元素来创建一系列视图。但是,由于ForEach重用了它创建的视图以优化性能(就像其他基于列表的视图一样,如UITableView和UICollectionView一样),它要求我们提供一种方法来标识我们所基于的每个元素它对

    当我们要转换的元素符合Identifiable协议时,这种标识就会自动处理,我们可以将值的集合直接传递给ForEach。例如,在这里,我们将一组用户值转换为垂直排列的UserView实例的列表:

    struct User: Identifiable {
        let id: UUID
        var name: String
    }
    
    struct UserList: View {
        var users = [User]()
    
        var body: some View {
            VStack {
                ForEach(users) { user in
                    UserView(user: user)
                }
            }
        }
    }

    但是,有时我们可能希望将ForEach基于更简单的原始值(例如字符串)的集合。这样做一开始似乎很困难,因为我们不想让String无条件地符合Identifiable。幸运的是,有一种方法可以做到这一点,方法是使用 .self键路径来计算每个元素的标识符-就像这样

    struct TagList: View {
        var tags: [String]
    
        var body: some View {
            HStack {
                // Using '.self', we can refer to each element directly,
                // and use the element's own value as its identifier:
                ForEach(tags, id: .self) { tag in
                    Text(tag)
                        .padding(3)
                        .background(Color.secondary)
                        .cornerRadius(5)
                }
            }
        }
    }

    当然,另一种选择是使用可识别类型包装原始值,例如这样

    truct Tag: Identifiable {
        var id: String { name }
        var name: String
    }
    
    struct TagList: View {
        var tags: [Tag]
    
        var body: some View {
            HStack {
                ForEach(tags) { tag in
                    Text(tag.name)
                        .padding(3)
                        .background(Color.secondary)
                        .cornerRadius(5)
                }
            }
        }
    }
    使用以上两种技术中的任何一种时,首先要确保我们处理的值都是唯一的(至少在该集合中),这很重要,因为否则ForEach可能会错误地重用结果视图。
    
    

    如果我们计划在整个代码库中的多个位置使用原始值的ForEach,则可能需要创建一个简单的便捷API来执行此操作,以避免在所有这些位置重复使用 .self键路径参数:

    extension ForEach where Data.Element: Hashable, ID == Data.Element, Content: View {
        init(values: Data, content: @escaping (Data.Element) -> Content) {
            self.init(values, id: .self, content: content)
        }
    }

    通过上述扩展,我们现在可以轻松地将任何原始值的集合(例如字符串和整数)传递给ForEach,如下所示:

    struct TagList: View {
        var tags: [String]
    
        var body: some View {
            HStack {
                ForEach(values: tags) { tag in
                    Text(tag)
                        .padding(3)
                        .background(Color.secondary)
                        .cornerRadius(5)
                }
            }
        }
    }

    • SwiftUI - init

    SwiftUI 中init方法,会在编译期进行预加载

    init() {
     }
    • List样式设置init方法中预onAppear中的区别
    // 全局生效,以项目中最后加载的init方法中的设置为准
     init() {
                UITableView.appearance().sectionFooterHeight = 10
                UITableView.appearance().backgroundColor = UIColor.red
                UITableViewCell.appearance().backgroundColor = UIColor.red
    
            }
    
    
    // 当前页面生效
    .onAppear() {
                    UITableView.appearance().sectionFooterHeight = 10
                    UITableView.appearance().backgroundColor = UIColor.red
                    UITableViewCell.appearance().backgroundColor = UIColor.red
                }
    • List自定义组尾视图
    struct Footer: View {
        var body: some View {
            Rectangle()
                .foregroundColor(.white)
                .listRowInsets(EdgeInsets())
        }
    }
    
    struct Timeline : View {
        var body: some View {
            List {
                Section(footer: Footer()) {
                    Text("Item 1")
                    Text("Item 2")
                    Text("Item 3")
                }
            }
        }
    }
    
    
    List {
             Section(footer: Text(""))) {
                    Text("One")
                    Text("Two")
                    Text("Three")
                }
         }
    
    
    List {
        Section(footer: Text("")) {
            Text("My text")
        }
        EmptyView()
    }
    
    List {
        Text("Item 1")
        Text("Item 2")
    
        // Adding empty section with footer
        Section(footer:
            Rectangle()
                .foregroundColor(.clear)
                .background(Color(.systemBackground))){EmptyView()}
                .padding(.horizontal, -15)
    }
     
  • 相关阅读:
    Hadoop(十六)之使用Combiner优化MapReduce
    Hadoop(十五)MapReduce程序实例
    Hadoop(十四)MapReduce原理分析
    STM32新的IDE -- stm32cubeIde 点亮个LED灯
    resin+spring-websocket 深坑
    spring Websocket 报 No suitab le default RequestUpgradeStrategy found
    nginx代理内网域名碰到的坑
    Showing Recent Issues clang: error: linker command failed with exit code 1 (use -v to see invocatio
    sublime安装插件步骤
    tomcat7 ajax请求服务中文乱码
  • 原文地址:https://www.cnblogs.com/liuxiaokun/p/12680011.html
Copyright © 2011-2022 走看看