SwiftUI高手之路:View組件複用List分頁Generics

SwiftUI高級之View組件複用List分頁Generics

寫了80餘篇SwiftUI相關的文章,總算對SwiftUI有初步瞭解。因而想本身是否可以也寫個開源項目,讓本身代碼也能夠複用。

目標

  • 實現針對不一樣數據結構的自動分頁
  • 可以自定義界面效果

實現路徑

須要用到Swift語言的高級特性Generics(範型)。Generics能夠讓咱們的項目變得靈活,避免重複編寫相同的代碼,並以清晰抽象的方式提供代碼表達力。數據結構

遇到問題

    1. 如何經過參數給範型初始化
U.init(item: item.getShowDict())

U是一個範型,經過協議實現了init,經過where明確了U是個Viewide

    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來解決spa

代碼實現

讓主頁面代碼變得簡潔

import SwiftUI

struct ContentView: View {
    var body: some View {
         ListPageViewG<Author,AuthorPageRow2>()
       // ListPageViewG<Author,AuthorPageRow>()
    }
}

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

咱們經過範型ListPageViewG能夠自由控制顯示數據結構和效果code

struct ListPageViewG<T:PageModelProtocal,U:PageRowProtocal>: View  where U:View

例如設置一下基礎效果blog

struct ListPageViewG<T:PageModelProtocal,U:PageRowProtocal>: View  where U:View

Jietu20200131-220511@2x.jpg

還能夠設置一下複雜效果教程

ListPageViewG<Author,AuthorPageRow2>()

Jietu20200131-220652@2x.jpg

Generics製做分頁List

  1. List頁面
struct ListPageViewG<T:PageModelProtocal,U:PageRowProtocal>: View  where U:View{
    var pageMgr:PageMgrG<T> = PageMgrG<T>()
    @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<T:PageModelProtocal>: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...ci

相關文章
相關標籤/搜索