我们学习Swift UI最大的障碍有一点在于我们并不知道其有多少组件可用,这大大限制了我们对SwiftUI的理解,
如果我们单纯使用UIKit,那么SwiftUI的优势将大打折扣。接下来我们将尝试梳理SwiftUI的各种组件。
基础组件
View
View是一个协议,是视图的基础协议,几乎所有的组件都遵循这个协议。其定义如下。该协议要求实现body的get方法.
body的get方法里面进行视图的自定义,通过自定义视图可以创建各种组件。
public protocol View {
associatedtype Body : View
@ViewBuilder var body: Self.Body { get }
}
Text
Text组件用于显示文本,相当于UIKit的UIlabel。
Image
Image组件用于显示图片,相当于UIKit的UIImageView。
TextField
Textfield组件用于显示输入文本框,相当于UIKit的UITextField。与之相关的还有SecureField,TextEditor。
Button
Button组件用于显示按钮,相当于UIKit的UIButton。与之相关的组件有EditButton,PasteButton,SignInWithAppleButton,MenuButton。
Label
Label组件用于显示标签,其不同于UILabel,它有一个文本和一个图片组成,有点类似于以前带图片和title的UIButton。
toolbar与ToolBarItem
注意,这里的toolbar是小写,toolbar本身是一个方法是view的一个方法,每个view可以支持toolbar方法,toolbar里面需要ToolbarItem进行组合。相当于UIKit的UIToolbarItem。
Slider
Slider是滑竿,类似于UIKit下的UISlider。
Stepper
Stepper类似于UIKit的UIStepper。
Toggle
Toggle是开关组件,其相当于UIKit下的UISwitch。
ProgressView
相当于UIKit的UIProgressView。
Link
Link相当于一个超链接。设置一个title和一个url,可以进行跳转。
NavigationLink
SwiftUI都是view,没有Controller,那么我们如何push一个页面呢,这就需要用到NavigationLink,前提是你有一个NavigationView。
Map
SwiftUI本身没有提供用于显示地图的组件,需要引入MapKit。MapKit中的Map相当于MapKit中的MKMapView。
Gauge
Gague是测量仪,仅限于AppleWatch可用。
特殊组件
Spacer
Spacer相当于一个没有任何页面渲染的空视图,在HStack和VStack中,它可以占面剩余空间,非常适合SwiftUI主导的搭积木式的布局。
Divider
Divider是一个分割线,解决了需要自定义分割线的痛点。
GeometryReader
GeometryReader是非常特殊的一种视图,在SwiftUI中,我们很少关心父视图的怎样,通常是父视图是适应子视图大小变化,但是某些情况,
我们可能需要子视图适应父视图,这时候我们就得拿到父视图的宽高信息,这时候我们可以借助GeometryReader实现。
弹出类组件
Menu
Menu组件用于显示菜单,相当于UIKit的UIMenuController。与之相关的还有ContextMenu。
ActionSheet
ActionSheet相当于UIKit的UIActionSheet。
Picker
Picker相当于UIKit的UIPickerView,不过在SwiftUI里面,它支持多种Style,更像是Segment,PopupOver和PickerView的大杂烩,与之相关的组件还有,ColorPicker,DatePicker。
Alert
Alert相当于UIKit的UIAlertController。
容器类组件
ScrollView
ScrollView相当于UIKit的UIScrollView
List
List相等于UIKit中的UITableView。
LazyVGrid、LazyHGrid、GridItem
GridItem相当于UIKit的UICollectionViewCell,LazyVGrid和LazyHGrid相当于UICollectionView。SwiftUI的CollectionView需要借助ScrollView和LazyHGrid以及LazyVGrid才能实现。HGrid相当于按行分组,VGrid相当于按列分组(比如瀑布流)。
HStack、VStack、ZStack
HStack、VStack相当于UIStackView,H是水平方向,V是竖直方向。ZStack可以理解为相对于屏幕里外方向,也就是相当于以前superView和subView的方式。与之相关的组件LazyHStack、LazyVStack。
Form
Form可以将组件变成一个表单。它与VStack比较相似。比如它与Picker相结合,可以轻松实现设置页面。
TabView、TabbarItem
TabView是选项卡,其相等于UIKit中的TabbarViewController。Tabbar本身不在单独作为一个对象使用。
NavigationView
NavigationView是导航页面,相当于UIKit的UINavigationViewController。NavigationBar本身不在作为一个单独的对象使用。
AnyView
AnyView被称为可擦写视图,它也是一个容器视图。SwiftUI的组件都是一次性渲染,可擦写视图每次都会移除子视图,重新布局渲染,所以转换成AnyView后或被AnyView装饰后性能上会大打折扣。
渲染类组件
Color
Color虽然指的是颜色,但是其也遵循View协议,所以它也是一个View,它可以被理解为UIKit下UIView设置一个背景色。
Shape
Shape是一个协议,用于显示一个形状,其本身遵循View协议。其派如下结构体Capsule(胶囊,类似于button样式),Circle(圆形),ContainerRelativeShape,Ellipse(椭圆),OffsetShape,Path(路径),Rectangle(矩形),RotatedShape,RoundedRectangle(圆角矩形),ScaledShape,TransformedShape。这些结构体都是一个完整的View组件可以直接使用,尤其在mask,overlay,clip等操作时比较常见。
LinearGradient、AngularGradient、RadialGradient
LinearGradient、AngularGradient、RadialGradient这三个都表示渐变色。Color和Shape都被定义成了View,当然也不难理解渐变会被定义成View。Gradient本身不是View,因为Gradient没有定义渐变函数。而LinearGradient(线性渐变)、AngularGradient(角度渐变)、RadialGradient(弧度渐变)是真正的View。以下是一个LinearGradient的例子。
总结
-
跟UIKit的对应关系
- UIView ==> View
- UILabel ==> Text
- UIImageView ==> Image
- UITextField ==> TextField 掩码显示 SecureField
- UITextView ==> TextEditor
- UIButton ==> Button、Label
- UISlider ==> Silder
- UIStepper ==> Stepper
- UISwitch ==> Toggle
- UIProgressView ==> ProgressView
- UIMenuController ==> Menu
- UIActionSheet ==> ActionSheet
- UIAlertController ==> Alert
- UIPickerView、UISegmentedControl、UIPopoverController ==> Picker,DatePicker,ColorPicker
- UIScrollView ==> Scroll
- UITableView ==> List
- UICollectionView ==> LazyVGrid、LazyHGrid、GridItem
- UIStackView ==> HStack、VStack、LazyHStack、LazyVStack
- UITabbarViewController ==> TabView
- UINavigationViewController ==> NavigationView
- 其他:Map ==> MKMapView
-
新增组件
- Spacer
- Divider
- Link
- Color
- Shape
- LinearGradient、AngularGradient、RadialGradient
- ZStack、GeometryReader、AnyView (这三个视图,用于解决渲染问题)
-
方式替换
- push通过NavigationLink的方式实现
- Tabbar和NavigationBar不作为独立对象使用
- Grid需要借助ScrollView实现
-
不支持
- 不支持webView,需要借助WebKit的WKWebView(非SwiftUI体系)