SwiftUI - 聊一下View

View简介

A type that represents part of your app’s user interface and provides modifiers that you use to configure views.

View代表应用程序用户界面的一部分并提供用于配置视图的修饰符

public protocol View : _View {
    associatedtype Body : View
    var body: Self.Body { get }
}

View 协议有一个关联的类型 Body,它被限制为任何符合 View协议的类型。body中是在屏幕上呈现的实际内容。 SwiftUI 将通过 body计算属性的实现来推断关联的类型。

You create custom views by declaring types that conform to the View protocol. Implement the required body computed property to provide the content for your custom view.

你可以通过声明符合View协议的类型来创建自定义视图。实现所需的 body 计算属性以为您的自定义视图提供内容,如下:

struct MyView: View {
    var body: some View {
        Text("Hello, World!")
    }
}

some View 这种写法使用了 Swift 5.1 的 Opaque return types 特性。它向编译器作出保证,每次 body 得到的一定是某一个确定的,遵守 View 协议的类型,告诉编译器“不要再细究具体的类型"

Assemble the view’s body by combining one or more of the built-in views provided by SwiftUI, like the Text instance in the example above, plus other custom views that you define, into a hierarchy of views. For more information about creating custom views, see Declaring a custom view.

通过将 SwiftUI 提供的一个或多个内置视图(如上例中的 Text 实例)以及你定义的其他自定义视图组合到视图层次结构中来组装视图的body。有关创建自定义视图的更多信息, 可以看Declaring a custom view.

The View protocol provides a set of modifiers — protocol methods with default implementations — that you use to configure views in the layout of your app. Modifiers work by wrapping the view instance on which you call them in another view with the specified characteristics, as described in Configuring views. For example, adding the opacity(_:) modifier to a text view returns a new view with some amount of transparency:

View 协议提供了一组修饰符 - 具有默认实现的协议方法 - 您可以使用它们来配置应用布局中的视图。修饰符通过将调用它们的视图实例包装在具有指定特征的另一个视图中来工作,如配置视图 中所述。例如,将 opacity(_:) 修饰符添加到文本视图会返回一个包含一定数量的新视图透明度:

Text("Hello, World!")
    .opacity(0.5) // Display partially transparent text.

Why is View a struct and not a class anymore?

One of the fundamental principles of SwiftUI is to have a single source of truth in your code. A traditional UIKit approach of having a base UIView class and all other views inherit from it has a demerit wherein we have multiple stored properties in our view inherited from parent UIView. You only define properties that you want to use unlike in UIKit where you inherit a number of properties from your parent view.

SwiftUI 的基本原则之一是在你的代码中拥有单一的事实来源。传统 UIKit 方法有一个基类 UIView ,所有从它继承而来视图都有一个缺点,即我们的视图中有多个存储属性,这些属性是从父 UIView继承的。而在SwiftUI 中你只定义你想使用的属性,不像在UIKit中你从父视图继承许多属性

SwiftUI tends to make views pretty lightweight and what better option than a value type with no headache of reference counting and retain cycles. Reference types are messier to maintain. You can alter your properties from anywhere in your code.

Swift UI also makes you be responsible for any views and their own state. Views are independent and isolated from one another. Any changes to a particular view will not affect any other unless they are binded by some common source of truth. It’s allocated on the stack, and it’s passed by value.

SwiftUI 倾向于使视图变得非常轻量级,并且有什么比值类型是更好的选择,无需担心引用计数和循环引用。引用类型更难维护,因为你可以从代码中的任何位置更改属性。

SwiftUI让你对任何视图和它们自己的状态负责。视图是独立的并且彼此隔离。对特定视图的任何更改都不会影响任何其他视图,除非它们受到某些共同事实来源的约束。它在堆栈上分配,并按值传递。

Simple Example

屏幕上展示一个文本内容,直接使用Text即可

import SwiftUI

// 定义结构体ContentView,遵守View协议
struct ContentView: View {
    //  计算属性body
    // some View:表示返回的内容将遵守View协议
    var body: some View {
        // 返回一个具体类型的View
        Text("Hello, World!")
    }
}

// 仅仅是用于预览界面效果,最终不会被打包
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

可以在右侧的预览页面看到效果:

截屏2022-11-02 13.50.24.png

self is immutable in View body

struct ContentView: View {
    var title: String
    
    var body: some View {
        VStack {
            Button(action: {
                self.title = "I am changing this"
            }) {
                Text("Hit me")
            }
        }
    }
}

上面代码,我们尝试修改title,将会得到编译错误提示:


截屏2022-11-02 14.35.24.png

这个错误是因为body是一个计算属性,我们不能从计算属性中改变 self。那么如何解决?可以使用@State修饰,将title 作为 @State 属性,那么 SwiftUI 框架会负责对其存储并且可以修改。

@State var title: String

参考

  • View - Apple documentation
  • Why does SwiftUI use “some View” for its view type?
  • What Is a View
  • Understanding SwiftUI View

你可能感兴趣的:(SwiftUI - 聊一下View)