SwiftUI高手之路:View组件复用List分页Generics

SwiftUI高级之View组件复用List分页Generics

写了80余篇SwiftUI相关的文章,总算对SwiftUI有初步了解。于是想自己是否能够也写个开源项目,让自己代码也可以复用。

目标

  • 实现针对不同数据结构的自动分页
  • 能够自定义界面效果

实现路径

需要用到Swift语言的高级特性Generics(范型)。Generics可以让我们的项目变得灵活,避免重复编写相同的代码,并以清晰抽象的方式提供代码表达力。

遇到问题

    1. 如何通过参数给范型初始化
    U.init(item: item.getShowDict())

U是一个范型,通过协议实现了init,通过where明确了U是个View

    1. 协议如何用范型
protocol PageModelProtocal:Identifiable{
    associatedtype T
    static func row_page() ->[T]
    // 获取下一页
    var id:UUID { get set }
    var name:String { get set }
    func next() ->[T]
    func getShowDict() ->[String:Any]
}

可以用associatedtype来解决

代码实现

让主页面代码变得简洁

import SwiftUI

struct ContentView: View {
    var body: some View {
         ListPageViewG()
       // ListPageViewG()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

我们通过范型ListPageViewG可以自由控制显示数据结构和效果

struct ListPageViewG: View  where U:View

例如设置一下基础效果

struct ListPageViewG: View  where U:View

SwiftUI高手之路:View组件复用List分页Generics_第1张图片

还可以设置一下复杂效果

ListPageViewG()

SwiftUI高手之路:View组件复用List分页Generics_第2张图片

Generics制作分页List

  1. List页面
struct ListPageViewG: View  where U:View{
    var pageMgr:PageMgrG = PageMgrG()
    @State var items:[T] = []
    @State  var isLoading: Bool = false
    @State  var page: Int = 0
    
    init() {
        _items = State(initialValue: pageMgr.next())
        
    }
    
    var body: some View {
        List(items){ item in
            //self.pageRow
            VStack{
                U.init(item: item.getShowDict())
            }.onAppear {
                // self.myInit()
                self.listItemAppears(item)
            }
            
            
        }
    }
    
}
  1. 设置协议
protocol PageRowProtocal {
    
    var item:[String:Any] { get set }
    init(item:[String:Any])
}

protocol PageModelProtocal:Identifiable{
    associatedtype T
    static func row_page() ->[T]
    // 获取下一页
    var id:UUID { get set }
    var name:String { get set }
    func next() ->[T]
    func getShowDict() ->[String:Any]
}
class PageMgrG:NSObject{
    var page = 0
    var pageSize = 0
    
    func next() -> [T]{
        return   T.row_page() as! [T]
    }
   
}
  1. 数据实例化
// 遵守协议的struct
struct Author:PageModelProtocal {
    var id = UUID()
    var name = ""
    
    func getShowDict() ->[String:Any]{
        return ["id":id,"name":name]
    }
    func next() -> [Self] {
        return  Author.row_page()
    }
    static func row_page() ->[Self]{
        return [
            Author(name:"tom"),
            Author(name:"jack"),
            Author(name:"mary")
        ]
    }
}
  1. 界面实例化
import SwiftUI

struct AuthorPageRow: View ,PageRowProtocal{
    var item:[String:Any]
    var body: some View {
        Text("\(item["id"] as! UUID) \(item["name"] as! String)")
    }
}

struct AuthorPageRow2: View ,PageRowProtocal{
    var item:[String:Any]
    var body: some View {
        CircleText(name: item["name"] as! String)
        
    }
}

参考文献

更多SwiftUI教程和代码关注专栏

https://www.jianshu.com/c/7b3...

你可能感兴趣的:(ios,swift)