视图中不可变的某些视图主体变量/不透明返回
Posted
技术标签:
【中文标题】视图中不可变的某些视图主体变量/不透明返回【英文标题】:Immutable some view body variable/opaque return in View 【发布时间】:2019-06-05 21:52:32 【问题描述】:在 Swift 5.1 中存在不透明类型。我看到了,例如body
是必需的协议变量。它的合约定义如下:
var body: Self.Body get
这意味着我们应该能够将 body 标记为不可变(没有 set
)。这必须怎么做?不透明的变量类型是否可能是不可变的?我试过了:
import SwiftUI
struct ContentView : View
init()
body = AnotherView(body: Text(""))
let body: some View
struct AnotherView: View
var body: Text
但我得到AnotherView
必须强制转换为some View
的错误。这样做之后,我得到了错误:
'some' 类型仅针对声明的属性类型实现 和下标以及函数的返回类型
我是否能够使用 some View
类型的不可变 body
变量来遵守 View
(未将其显式标记为 AnotherView
)? AnotherView
是some View
,我不明白为什么我不能将AnotherView
的实例分配给body
。我想保持灵活性并且不暴露结构体外部的实际实现类型,但我想直接在初始化器内部初始化它(因为我在初始化器内部传递值,制作更多属性并在 body 属性中使用它们是详细)。
【问题讨论】:
【参考方案1】:因为没有 setter,任何作为值类型的 body
实现都将是不可变的。 var
只是意味着 body
被延迟评估,而不是它是可变的。你可以声明let body
,但是,正如你所指出的,这暴露了底层View
的实现:
public struct StaticTextView : View
public let body: Text
public init(string: String)
self.body = Text(string)
解决此问题的一种方法是让body
只返回一个内部私有值,如下所示:
public struct StaticTextView : View
private let textView: Text
public var body: some View textView
public init(string: String)
self.textView = Text(string)
但是,您应该记住,body
被设计为在任何绑定状态更改时动态运行,如果您想将视图分配给常量,则该视图层次结构中的任何内容都不能绑定到任何动态状态。例如,这是不可能的:
struct DynamicStepperView : View
@State var stepperValue = 1
var body: some View
Stepper(value: $stepperValue, in: 1...11, label: Text("Current Value: \(stepperValue)") )
如果您主要关心的是防止视图层次结构的实现细节泄漏,请注意some View
的不透明返回类型对于代码的任何客户端确实是不透明的,他们将无法看到任何除了它是一些符合View
协议的东西之外的底层实现的细节。
【讨论】:
以上是关于视图中不可变的某些视图主体变量/不透明返回的主要内容,如果未能解决你的问题,请参考以下文章