• 首页
        • 更多产品

          客户为中心的产品管理工具

          专业的软件研发项目管理工具

          简单易用的团队知识库管理

          可量化的研发效能度量工具

          测试用例维护与计划执行

          以团队为中心的协作沟通

          研发工作流自动化工具

          账号认证与安全管理工具

          Why PingCode
          为什么选择 PingCode ?

          6000+企业信赖之选,为研发团队降本增效

        • 行业解决方案
          先进制造(即将上线)
        • 解决方案1
        • 解决方案2
  • Jira替代方案
目录

为什么 SwiftUI 用 “some View” 作为视图类型

因为wiftUI 高度依赖 Swift 5.1 引入的一个强大特性,它叫 “opaque return types” ,它可以用于函数、方法和属性返回一些值,无需向调用API的客户端揭示该值的具体类型。每一次你看到 some View 的地方就是它了。

一、为什么 SwiftUI 用 “some View” 作为视图类型

SwiftUI 高度依赖 Swift 5.1 引入的一个强大特性,它叫 “opaque return types” ,它可以用于函数、方法和属性返回一些值,无需向调用API的客户端揭示该值的具体类型。每一次你看到 some View 的地方就是它了。它表示 “某个遵循View协议的特定类型,但我们不必说具体是什么”

返回 some View 相较只返回 View 有两个重要的区别:

  1. 我们必须总是返回相同的类型。
  2. 尽管我们并不知道返回的 view 的类型,但编译器知道。

名列前茅个区别对于性能至关重要:SwiftUI 需要能够监视我们正在展示的视图并理解它们如何变化,以便它能正确地更新用户接口。如果我们允许随机地改变视图(类型),对于 SwiftUI 来说,搞清楚究竟发生了什么变化会变得很慢 —— 基本上需要从头开始。

第个区别也很重要,因为 SwiftUI 用 ModifiedContent 构建起数据。之前我们向你展示过下面这份代码:

Button(“Hello World”) {

    print(type(of: self.body))

}

.frame(width: 200, height: 200)

.background(Color.red)

这个代码创建了一个按钮,如果打印它的 Swift 类型,会给出一组由 ModifiedContent 构成的很长的输出。

View 协议有一个与之关联的类型。以 Swift 的方式,我们说 View本身没有任何含义—— 我们需要指出它精确的类型。就如果 Swift 不让我们说 “这个变量是个数组”,相反,它要求我们说数组里有什么:“这个变量是个字符串数组。”

因此,如下代码是不被允许的:

struct ContentView: View {

    var body: View {

        Text(“Hello World”)

    }

}

但下面的代码则是完全合法的:

struct ContentView: View {

    var body: Text {

        Text(“Hello World”)

    }

}

返回 View 没有意义,因为 Swift 希望知道视图里有什么 —— 它内心的空洞没被填满。另一方面,返回 Text 就是 OK 的,因为我们填补了这个空洞,Swift 知道视图是什么了。

现在我们回到早期的代码:

Button(“Hello World”) {

    print(type(of: self.body))

}

.frame(width: 200, height: 200)

.background(Color.red)

如果我们想要在body 属性里返回上面任何一个视图类型,我们应该怎么书写代码?你可能会尝试搞清楚这些 ModifiedContent 泛型组合的结果,但这实际上太痛苦了,事实上我们根本不用关系,这些都是 SwiftUI 的活。

some View 说的是:“它将返回一个特定的 view 类型,比如Button 或者 Text,但我不想说具体是啥。” 因此,视图的空洞会被一个真实的视图填充,但不要求我们精确地写出这个冗长的类型。

延伸阅读:

二、SwiftUI生命周期

SwiftUI同UIKit和AppKit的主要区别之一是,SwiftUI的视图(View)是值类型,并不是对屏幕上绘制内容的具体引用。在SwiftUI中,开发者为视图创建描述,而并不实际渲染它们。

在UIKit(或AppKit)中,视图(或视图控制器)有明确的生命周期节点,比如vidwDidload、loadView、viewWillAppear、didAddSubView、didMoveToSuperview等方法,它们本质上充当了钩子的角色,让开发者能够通过执行一段逻辑来响应系统给定的事件。

SwiftUI的视图,本身没有清晰(可适当描述)的生命周期,它们是值、是声明。SwiftUI提供了几个修改器(modifier)来实现类似UIKit中钩子方法的行为。比如onAppear同viewWillAppear的表现很类似。同UIKit的钩子方法的位置有很大的不同, onAppear和onDisappear是在当前视图的父视图上声明的。

将UIKit视图包装成SwiftUI的视图时,我们需要了解两者生命周期之间的不同,不要强行试图找到完全对应的方法,要从SwiftUI的角度来思考如何调用UIKit视图。

相关文章