寫了80餘篇SwiftUI相關的文章,總算對SwiftUI有初步瞭解。因而想本身是否可以也寫個開源項目,讓本身代碼也能夠複用。
須要用到Swift語言的高級特性Generics(範型)。Generics能夠讓咱們的項目變得靈活,避免重複編寫相同的代碼,並以清晰抽象的方式提供代碼表達力。數據結構
U.init(item: item.getShowDict())
U是一個範型,經過協議實現了init,經過where明確了U是個Viewide
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
還能夠設置一下複雜效果教程
ListPageViewG<Author,AuthorPageRow2>()
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) } } } }
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] } }
// 遵照協議的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") ] } }
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) } }