对比Swift和ArkTS,也许以后可以这样做开发

最近在学 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 放在外部的文件中,然后再自行引入。

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

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

组件差异

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

基础组件

基础组件基本相同:

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

布局组件

Swift UI 使用了 如下组件来做布局:

  1. HStack:水平堆栈,用于水平排列子视图。
  2. VStack:垂直堆栈,用于垂直排列子视图。
  3. ZStack:堆栈视图,用于堆叠多个视图。
  4. Spacer:空白组件,用于占据剩余空间。
  5. ScrollView:滚动视图,允许用户滚动内容。
  6. TabsView:标签视图,用于创建标签式导航。
  7. NavigationView:导航视图,用于创建导航结构。

而 ArtTS 也有类似对应:

  1. Row行组件:用于水平排列子视图。
  2. Column列组件:用于垂直排列子视图。
  3. Stack堆叠组件:用于堆叠多个视图。
  4. Blank组件:用于占据剩余空间。
  5. Scroll滚动组件:用于创建滚动视图。
  6. Tab组件:用于实现标签页的切换功能。
  7. Navigation组件:路由导航根视图容器,一般作为Page页面的根容器使用。

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

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

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

SwiftUI的布局系统非常灵活,可以通过调整alignmentspacingpadding等属性来实现复杂的布局需求。虽然它不完全等同于CSS中的Flexbox和Grid,但是通过组合使用不同的布局视图,创建出丰富多样的布局效果。

个人在实际开发 iOS 中,通过基础的布局组件搭配,就能完美的实现弹性布局和网格布局。

表单组件

Ark TS UI 提供了一系列的组件,更接近于 html 同名的组件:

  • TextInput:用于文本输入。
  • CheckBoxSwitch:用于布尔值的选择。
  • Radio:用于单选按钮组,类似于 HTML 中的单选按钮。
  • Picker :用于选择器,可以用于日期选择、时间选择或简单的选项选择,类似于 HTML 中的 <select>

Ark TS UI 表单组件的特点在于它们与数据绑定紧密集成,可以通过 @State@Link@Prop 等装饰器来管理表单的状态和数据流。

而 Swift UI 也有类似的表单组件,但是大部分都不相同:

  • TextField:用于文本输入,可以包含占位符文本。
  • SecureField:用于密码输入,隐藏输入内容。
  • Picker:用于选择器,可以用于选择单个值或多个值。
  • Toggle:用于布尔值的选择,类似于开关。
  • DatePicker:用于日期和时间选择。
  • SliderStepper :用于数值选择,Slider 提供连续值选择,而 Stepper 提供步进值选择。
  • Form:一个容器视图,用于组织输入表单数据,使得表单的创建和管理更为方便。

总结 - 可运用 AI 转译

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

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

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

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

相关推荐
m0_7482309427 分钟前
Redis 通用命令
前端·redis·bootstrap
陈无左耳、1 小时前
HarmonyOS学习第4天: DevEco Studio初体验
学习·华为·harmonyos
YaHuiLiang1 小时前
一切的根本都是前端“娱乐圈化”
前端·javascript·代码规范
ObjectX前端实验室2 小时前
个人网站开发记录-引流公众号 & 谷歌分析 & 谷歌广告 & GTM
前端·程序员·开源
CL_IN2 小时前
企业数据集成:实现高效调拨出库自动化
java·前端·自动化
月未央3 小时前
HarmonyOS Next 开发系列:Local 状态管理实践
harmonyos
浪九天4 小时前
Vue 不同大版本与 Node.js 版本匹配的详细参数
前端·vue.js·node.js
qianmoQ4 小时前
第五章:工程化实践 - 第三节 - Tailwind CSS 大型项目最佳实践
前端·css
椰果uu4 小时前
前端八股万文总结——JS+ES6
前端·javascript·es6
微wx笑5 小时前
chrome扩展程序如何实现国际化
前端·chrome