注册
web

对比Swift和ArkTS,鸿蒙开发可以这样做

最近在学 ArkTS UI 发现其与 Swift UI 非常像,于是做了一下对比,发现可探索性很强。


Hello World 代码对比


从 Hello World 来看两者就非常像。


鸿蒙 ArtTs UI 的 Hello World 如下:


@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 如下:


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 的公式如下:


Element(props) {
SubElement...
}.attribute(value)

元素(元素属性配置) {
子元素
}.元素外观属性(元素外观)

因为 ArkTS 本质上是 Typescript / Javascript ,所以其写法要符合 TS/JS 的写法,引入的属性、变量必须有明确指示。


Text(this.message)  // message 是当前页面引入的,要有 this
.id('HelloWorld')
.fontSize(50)
.fontWeight(FontWeight.Bold) // Bold 是公共常量 FontWeight 的其中一值

对于前端来说,简单易读。这里的 Text 传入一个 message,然后标记 id 为 HelloWorld,设置字体为 50,字重为粗体。


而 Swift 或许更符合苹果以前 Obj C 迁移过来的人的写法。


Image(systemName: "globe") // 公共库名:公共库的值
                .imageScale(.large) // .large 是公共常量的一个值
                .foregroundStyle(.tint)// .tint 是公共常量的一个值

这里的 Image 引入了公共图标库的一个 globe 的图标,然后设置图片大小为大,前景样式为系统主题的颜色,Image(systemName: "globe") 明显不符合 new 一个类的定义方法,.imageScale(.large).foregroundStyle(.tint) 也不符合参数的使用,按以前的解读会有点让人懵圈。


如果转换成 Typescipt 应该是这样的:


new Image(SystemIcon.globe)
                .imageScale(CommonSize.large)
                .foregroundStyle(CommonColor.tint)

显然 ArkTS 更符合前端人的阅读、书写习惯。但其实掌握 Swift UI 也并不难,只需要记住 Swift UI 的这些细小差别,写两次也能顺利上手了。


声明式 UI 的耦合性争议


也许不少人会对声明式 UI 的耦合性(M和V耦合在一起)反感。但是在前端来说,除了以前的 的 MVC 框架 Angular.js 外,其余框架即使是 MVVM,也很少能做到解耦合的,特别是单功能内和业务数据交互的耦合。


所以,前端耦合性,还是需要自行处理。


Button({
action: handleGoButton
}).{
Text("Go")
}

// 自行决定 handleGoButton 是否需要放在外部文件中
private func handleGoButton() {
...
}

// 数据耦合在 UI 中,无解
ZStack {
Color(selectedImageIndex == index ?
Color.hex("808080") : Color.hex("585857")) // 选中的背景颜色区别一般的
...
}

前端的解耦合最终还是需要靠组件化、高阶函数来完成:



  1. 组件化:通过将 UI 分解为独立的组件,每个组件都有自己的功能和状态,可以进一步降低耦合性。组件化使得开发者可以独立地开发和测试组件,而不需要关心其他部分的实现。
  2. 高阶函数:在某些声明式 UI 框架中,可以使用高阶函数来复用共有逻辑,同时允许替换独有逻辑。这种方式可以减少代码的重复,并提高组件的可重用性。

组件差异


SwiftUI 和鸿蒙操作系统的 ArtTS UI 框架都提供了多种组件,按前端使用情况,其实同样有很多相同之处。


基础组件


基础组件基本相同:



  • Text 用于显示文本;
  • Image 用于显示图片;
  • Button 用户可以点击执行操作;

布局组件


Swift UI 和 ArkTS 相同/相似的布局组件有:


Swift UIArkTS说明
HStackRow水平堆栈,用于水平排列子视图
VStackColumn垂直堆栈,用于垂直排列子视图
ZStackStack堆栈视图,用于堆叠多个视图
SpacerBlank空白组件,用于占据剩余空间
ScrollViewScroll滚动视图,允许用户滚动内容
TabsViewTab标签视图,用于创建标签式导航
NavigationViewNavigation导航视图,用于创建导航结构

可以看出,两者基本上的布局都可以通用,当然细节上肯定会有很多不同。不过做一个转译应该不难,可以尝试使用 AI 来完成。


不同的地方在于 Flex 和 Grid 布局:



  1. Swift UI 仅有懒加载的组件:LazyVGridLazyHGrid:懒加载的网格视图,用于展示大量数据。
  2. Ark TS UI有的组件:Flex以弹性方式容器组件:用于灵活布局;Grid网格布局组件:用于创建网格布局。

SwiftUI的布局系统非常灵活,可以通过调整alignmentspacingpadding等属性来实现复杂的布局需求。虽然它不完全等同于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:一个容器视图,用于组织输入表单数据,使得表单的创建和管理更为方便。

虽然不能一一对应,但像日期选择器那样,目前大部分用户已经基本适应了 android 和 iOS 的差异。


总结 - 可运用 AI 转译


通过这次对比学习,可以得出以下结论:



  1. 声明式 UI 是前端更容易配置与阅读,尤其是 ArkTS ;
  2. 解耦合需要运用组件化、高阶函数等知识进行自行处理;
  3. ArkTS UI 和 Swift UI 的基础组件、布局组件相似度非常高,基本能一一对应,可以对照学习使用;
  4. 鉴于两者相似度高,可以尝试开发一个 app,然后另一个 app 使用 AI 来完成转译。

第四点,个人觉得难度不大,本人用代码差异非常大的 android app 转译 iOS app 的也能成功,只是一个个页面进行调试花了不少时间。


至于先开发哪个 app 看你个人习惯,如果你是老 iOS 开发,可以使用先开发 iOS 再进行鸿蒙 OS 开发;甚至 react native 开发生成 iOS 之后,通过生成的 iOS 代码进行转译鸿蒙 OS app。如果你没有之前的负担,完全可以学习 ArkTS,更快地入手,然后通过转译 iOS app 来学习 Swift。


作者:陈佬昔的编程人生
来源:juejin.cn/post/7449173391443329078

0 个评论

要回复文章请先登录注册