侧边栏

初识SwiftUI

发布于 | 分类于 客户端/iOS

最近几年声明式UI的风在客户端也非常流行,Android有jetpack compose,iOS有Swift UI,本文决定尝试使用一下SwiftUI,看看开发体验如何,稍作记录

生命周期

SwiftUI生命周期

  • onAppear组件出现时调用
  • onDisappear组件消失时调用

模板语法

内置组件列表

https://developer.apple.com/documentation/swiftui/views-and-controls

循环

https://medium.com/彼得潘的-swift-ios-app-開發問題解答集/swiftui-的-foreach-7ccd426e53ac

通过索引值

swift
var list:[Int] = [1,2,3,4]

ForEach(0..<list.count) { (index) in
    Text("\(list[index])")
}
// 可以使用 list.indices 代替0..<list.count

直接遍历列表,通过id参数指定每个元素的key

swift
var list:[Int] = [1,2,3,4]
ForEach(list, id:\.self){(item) in
    Text("\(item)")
}

遍历一些复杂的列表数据

swift

struct ListItem {
   var id: Int
   var name: String
}

var list2:[ListItem] = [ListItem(id:1, name:"item1"), ListItem(id:2, name:"item2")]

ForEach(list2, id:\.id){(item) in
    Text("\(item.name)")
}

上面这种方式需要保证id的唯一性,最好的办法是使用系统的Identifiable

swift
struct ListItem:Identifiable {
  var id = UUID()
   var name: String
}

var list3:[ListItem] = [ListItem( name:"item1"), ListItem(name:"item2")]

// 不需要再传入keyPath形式的id来控制了
ForEach(list3){(item) in
    Text("\(item.name)")
}

此外也可以用List来代替ForEach

条件渲染

https://stackoverflow.com/questions/56517610/conditionally-use-view-in-swiftui

swift
var flag = false 

if(flag) {
    Text("yes")
}else {
    Text("no")
}

看起来还可以通过extension View实现一些自定义指令,如.if等等

自定义渲染组件

组件通信

https://my.oschina.net/SwiftOldDriver/blog/4704384

https://www.jianshu.com/p/2bc4af91250a

State与Binding

主要用于子组件通知父组件的场景

参考:

父组件->子组件,可以直接通过 State 和 Binding 来传递数据,类似于props

子组件->父组件,可以通过回调props

swift

struct Test5: View {
    @State var msg:String = "from parent"
    var body: some View {
        VStack {
          Text("Parent")
            SubChild(msg:$msg,function: self.onChildTap).onTapGesture {
                self.msg = "parent click"
            }
        }
      
    }
    func onChildTap(){
        print("test click")
    }
}

struct SubChild: View {
    @Binding var msg: String
     var function: () -> Void
    
    var body: some View {
        Text("sub: \(msg)").onTapGesture {
            self.function()
        }
    }
}

跨级组件通信,Environment,类似于context

方法传递

TODO

页面路由

路由组件

第一种方式是通过NavigationView & NavigationLink

https://medium.com/彼得潘的-swift-ios-app-開發問題解答集/利用-navigationview-navigationlink-切換頁面-3a062833230f

编程式路由

在iOS中使用ViewController来控制视图 参考这个讨论

https://fivestars.blog/swiftui/programmatic-navigation.html

网络请求

https://www.hackingwithswift.com/books/ios-swiftui/sending-and-receiving-codable-data-with-urlsession-and-swiftui

一些工具

日志打印

在XCode查看print的日志

参考:https://www.xspdf.com/resolution/58643513.html

使用command + shift + c

内置图标

参考:解读 WWDC19 - SF Symbols 内置图标库

可以在开发者官网 下载SF Symbols 2App,这个app列举了所有图标

打开之后大概是这个样子的

内置了2400多个图标,根据对应的名字就可以使用了

swift
Image(systemName: "photo")

扩展阅读

感兴趣的可以阅读下,提前知道后续还需要学习哪些东西

从 wwdc 学 SwiftUI——搭建你的第一个 SwiftUI 应用 (系列文章)

你要请我喝一杯奶茶?

版权声明:自由转载-非商用-保持署名和原文链接。

本站文章均为本人原创,参考文章我都会在文中进行声明,也请您转载时附上署名。