最近在学 ArkTS UI 发现其与 Swift UI 非常像,于是做了一下对比,发现可探索性很强。
Hello World 代码对比
从 Hello World 来看两者就非常像。
鸿蒙 ArtTs UI 的 Hello World 如下:
ts
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
build() {
RelativeContainer() {
Text(this.message)
.id('HelloWorld')
.fontSize(50)
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
}
.height('100%')
.width('100%')
}
}
Swift UI 的 Hello World 如下:
swift
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
}
.padding()
}
}
#Preview {
ContentView()
}
同样的 struct 开头,同样的 声明方式,同样的 Text,同样的设置外观属性方法。 不同的是 ArkTS 按照 Typescript 的写法,以装饰器起头,以 build 方法作为初始化的入口,build 里面才是元素;而 Swift UI 整个 ContentView 就是一个大元素,然后开始潜逃内部元素。
声明式 UI 描述
显然,两者都是用了 声明式的 UI 描述。
个人总结声明式 UI 的公式如下:
scss
Element(props) {
SubElement...
}.attribute(value)
元素(元素属性配置) {
子元素
}.元素外观属性(元素外观)
因为 ArkTS 本质上是 Typescript / Javascript ,所以其写法要符合 TS/JS 的写法,引入的属性、变量必须有明确指示。
Typescript
Text(this.message) // message 是当前页面引入的,要有 this
.id('HelloWorld')
.fontSize(50)
.fontWeight(FontWeight.Bold) // Bold 是公共常量 FontWeight 的其中一值
对于前端来说,简单易读。这里的 Text 传入一个 message,然后标记 id 为 HelloWorld,设置字体为 50,字重为粗体。
而 Swift 或许更符合苹果以前 Obj C 迁移过来的人的写法。
swift
Image(systemName: "globe") // 公共库名:公共库的值
.imageScale(.large) // .large 是公共常量的一个值
.foregroundStyle(.tint)// .tint 是公共常量的一个值
这里的 Image 引入了公共图标库的一个 globe 的图标,然后设置图片大小为大,前景样式为系统主题的颜色,Image(systemName: "globe")
明显不符合 new 一个类的定义方法,.imageScale(.large)
和 .foregroundStyle(.tint)
也不符合参数的使用,按以前的解读会有点让人懵圈。
如果转换成 Typescipt 应该是这样的:
Typescript
new Image(SystemIcon.globe)
.imageScale(CommonSize.large)
.foregroundStyle(CommonColor.tint)
显然 ArkTS 更符合前端人的阅读、书写习惯。但其实掌握 Swift UI 也并不难,只需要记住 Swift UI 的这些细小差别,写两次也能顺利上手了。
声明式 UI 的耦合性争议
也许不少人会对声明式 UI 的耦合性(M和V耦合在一起)反感。但是在前端来说,除了以前的 的 MVC 框架 Angular.js 外,其余框架即使是 MVVM,也很少能做到解耦合的,特别是单功能内和业务数据交互的耦合。
所以,前端耦合性,还是需要自行处理。
swift
Button({
action: handleGoButton
}).{
Text("Go")
}
// 自行决定 handleGoButton 是否需要放在外部文件中
private func handleGoButton() {
...
}
如果你想将数据层和视图层完全脱离,那可以自行将 handleGoButton
放在外部的文件中,然后再自行引入。
前端的解耦合最终还是需要靠组件化、高阶函数来完成:
- 组件化:通过将 UI 分解为独立的组件,每个组件都有自己的功能和状态,可以进一步降低耦合性。组件化使得开发者可以独立地开发和测试组件,而不需要关心其他部分的实现。
- 高阶函数:在某些声明式 UI 框架中,可以使用高阶函数来复用共有逻辑,同时允许替换独有逻辑。这种方式可以减少代码的重复,并提高组件的可重用性。
组件差异
SwiftUI 和鸿蒙操作系统的 ArtTS UI 框架都提供了多种组件,按前端使用情况,其实同样有很多相同之处。
基础组件
基础组件基本相同:
- Text 用于显示文本;
- Image 用于显示图片;
- Button 用户可以点击执行操作;
布局组件
Swift UI 使用了 如下组件来做布局:
- HStack:水平堆栈,用于水平排列子视图。
- VStack:垂直堆栈,用于垂直排列子视图。
- ZStack:堆栈视图,用于堆叠多个视图。
- Spacer:空白组件,用于占据剩余空间。
- ScrollView:滚动视图,允许用户滚动内容。
- TabsView:标签视图,用于创建标签式导航。
- NavigationView:导航视图,用于创建导航结构。
而 ArtTS 也有类似对应:
- Row行组件:用于水平排列子视图。
- Column列组件:用于垂直排列子视图。
- Stack堆叠组件:用于堆叠多个视图。
- Blank组件:用于占据剩余空间。
- Scroll滚动组件:用于创建滚动视图。
- Tab组件:用于实现标签页的切换功能。
- Navigation组件:路由导航根视图容器,一般作为Page页面的根容器使用。
可以看出,两者基本上的布局都可以通用,当然细节上肯定会有很多不同。不过做一个转译应该不难,可以尝试使用 AI 来完成。
不同的地方在于 Flex 和 Grid 布局:
- Swift UI 仅有懒加载的组件:LazyVGrid 和 LazyHGrid:懒加载的网格视图,用于展示大量数据。
- Ark TS UI有的组件:Flex以弹性方式容器组件 :用于灵活布局;Grid网格布局组件:用于创建网格布局。
SwiftUI的布局系统非常灵活,可以通过调整alignment
、spacing
、padding
等属性来实现复杂的布局需求。虽然它不完全等同于CSS中的Flexbox和Grid,但是通过组合使用不同的布局视图,创建出丰富多样的布局效果。
个人在实际开发 iOS 中,通过基础的布局组件搭配,就能完美的实现弹性布局和网格布局。
表单组件
Ark TS UI 提供了一系列的组件,更接近于 html 同名的组件:
- TextInput:用于文本输入。
- CheckBox 和 Switch:用于布尔值的选择。
- Radio:用于单选按钮组,类似于 HTML 中的单选按钮。
- Picker :用于选择器,可以用于日期选择、时间选择或简单的选项选择,类似于 HTML 中的
<select>
。
Ark TS UI 表单组件的特点在于它们与数据绑定紧密集成,可以通过 @State
、@Link
和 @Prop
等装饰器来管理表单的状态和数据流。
而 Swift UI 也有类似的表单组件,但是大部分都不相同:
- TextField:用于文本输入,可以包含占位符文本。
- SecureField:用于密码输入,隐藏输入内容。
- Picker:用于选择器,可以用于选择单个值或多个值。
- Toggle:用于布尔值的选择,类似于开关。
- DatePicker:用于日期和时间选择。
- Slider 和 Stepper :用于数值选择,
Slider
提供连续值选择,而Stepper
提供步进值选择。 - Form:一个容器视图,用于组织输入表单数据,使得表单的创建和管理更为方便。
总结 - 可运用 AI 转译
通过这次对比学习,可以得出以下结论:
- 声明式 UI 是前端更容易配置与阅读,尤其是 ArkTS ;
- 解耦合需要运用组件化、高阶函数等知识进行自行处理;
- ArkTS UI 和 Swift UI 的基础组件、布局组件相似度非常高,基本能一一对应,可以对照学习使用;
- 鉴于两者相似度高,可以尝试开发一个 app,然后另一个 app 使用 AI 来完成转译。
第四点,个人觉得难度不大,本人用代码差异非常大的 android app 转译 iOS app 的也能成功,只是一个个页面进行调试花了不少时间。
至于先开发哪个 app 看你个人习惯,如果你是老 iOS 开发,可以使用先开发 iOS 再进行鸿蒙 OS 开发。如果你没有之前的负担,完全可以学习 ArkTS,更快地入手,然后通过转译 iOS app 来学习 Swift。