学计算机的那个

不是我觉到、悟到,你给不了我,给了也拿不住;只有我觉到、悟到,才有可能做到,能做到的才是我的.

0%

Stanford CS193p - [1-3]

Developing Applications for iOS using SwiftUI

Total Lecture: 15

current: [1-3]

Getting Started with SwiftUI

behaves like a …

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import SwiftUI

struct ContentView: View {
var body: some View {
VStack() {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.orange)

Text("Hello CS193P!")
}
.padding()
}
}

ContentView结构体的行为类似于View,函数式编程关注的是功能、行为,而不是数据。面向对象编程的根源(root)是数据封装。函数式编程更像是行为封装。

1
2
3
4
5
6
7
8
9
10

struct ContentView: View {

var i: Int
var s: String

var body: some View {
...
}
}

IntString都是结构体,View不是一个结构体,是一种可以表现的东西,称为协议。

Computed Property

1
2
3
4
5
6
struct ContentView: View {

var body: some View {
...
}
}

变量的值没有存储在某个地方,是只读变量,是计算出来的。bodyvar,因为这里可能有变量,导致它在每次调用它时返回不同的东西。

some View

意味着这个变量的类型必须是世界上的任何结构,只要它的行为像View一样

creating instances of structs

1
2
3
Image(systemName: "globe")

Text("Hello CS193P!")

named parameters

systemName

parameter defaults

1
2
3
4
5
6
7
8
VStack(alignment: .leading, spcing: 20) {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.orange)

Text("Hello CS193P!")
}

1
2
3
4
5
6
7
8
VStack(){
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.orange)

Text("Hello CS193P!")
}

VStack() 后面大括号里实际上是一个函数。该函数返回一个View,完整的调用代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import SwiftUI

struct ContentView: View {
var body: some View {
VStack(content: {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.orange)

Text("Hello CS193P!")
})
.padding()
}
}

VStack是一个接受这个参数的试图。函数里面返回的是一个打包为TupleView

函数式编程,函数始终作为参数传递给其他事物

@ViewBuilder

View列表转换为TupleView的东西称为@ViewBuilder

TupleView(bag of Lego)

View modifier

.imageScale(),.foregroundColor(),.padding(),这些是函数,也叫View modifier,因为它的作用是在View上调用它,Image是一个行为类似于View的结构体,因此可以在其上调用这些函数。

More SwiftUI

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import SwiftUI

struct ContentView: View {
var body: some View {
HStack {
CardView(isFaceUp: true)
CardView()
CardView()
CardView()
}
.foregroundColor(.orange)
.padding()
}
}

struct CardView: View {
var isFaceUp: Bool = false
var body: some View {
ZStack(content:{
if isFaceUp {
RoundedRectangle(cornerRadius: 12).foregroundColor(.white)
RoundedRectangle(cornerRadius:12).strokeBorder(lineWidth:2)
Text("👻").font(.largeTitle)
}
else{
RoundedRectangle(cornerRadius:12).fill()
}
})

}

}

some View

1
2
3
4
5
6
7
8
struct ContentView: View {
var body: Text {
HStack {
Text("hello")
Text("there")
}
}
}

Cannot convert return expression of type VStack<TupleView<Text,Text>> to return type Text

trailing closure syntax

1
2
3
ZStack(alignment: .center , content:{
...
})

ZStack是一个行为类似于View的结构体,有两个参数。任何创建对象或函数的最后一个参数是函数本身,这里是一个返回视图(TupleView)的函数,可以省略掉它的标签content

1
2
  ZStack(alignment:. center) {
}

alignment 默认值为center所以上面可简写成

1
2
3
4
5
6
7
8
9
10
11
ZStack {
if isFaceUp {
RoundedRectangle(cornerRadius: 12).foregroundColor(.white)
RoundedRectangle(cornerRadius:12).strokeBorder(lineWidth:2)
Text("👻").font(.largeTitle)
}
else{
RoundedRectangle(cornerRadius:12).fill()
}
}

locals in @ViewBilder

1
2
3
4
5
6
7
8
9
10
11
12
ZStack {
var base: RoundedRectangle = RoundedRectangle(cornerRadius: 12)
if isFaceUp {
base.foregroundColor(.white)
base.strokeBorder(lineWidth:2)
Text("👻").font(.largeTitle)
}
else{
base.fill()
}
}

Views are immutable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

struct CardView: View {
var isFaceUp: Bool = false
var body: some View {
ZStack{
var base: RoundedRectangle = RoundedRectangle(cornerRadius: 12)
if isFaceUp {
base.foregroundColor(.white)
base.strokeBorder(lineWidth:2)
Text("👻").font(.largeTitle)
}
else{
base.fill()
}
}
.onTapGesture {
isFaceUp = !isFaceUp
}
}
}

Cannot assign to property:’self’ is immutable

@State

@State var isFaceUp = false

创建一个指向保存isFaceUp的指针,指针本身不会改变,它指向的东西可以改变,所以它满足View不能改变但isFaceUp可以改变

ViewBuilder can do

ViewBuilder中不能使用for,可以做三件事,条件、列表、局部变量

1
2
3
ForEach(0..<4, is: \.self) { index in

}

ForEach有一个ViewBuilder作为参数,这个ViewBuilder将拥有这四件事中每一个ViewViewBuilder是一个函数,函数可以有参数index

implicit return

1
2
3
4
5
6
7
8
var cards: some View {
return HStack {
ForEach(0..<cardCount,id: \.self) { index in
CardView(content: emojis[index])
}
}
.foregroundColor(.orange)
}

为什么这里可以省略returncards是一个计算属性,它返回HStack{},它不是ViewBuilderHStack中的内容是ViewBuilder,但是HStack本身不是,这里只是一个普通的函数,它只有一行代码,所以不需要return,这种称为隐式返回(适用于函数和计算属性)。

internal VS external parameter names

1
2
3
4
5
6
7
func cardCountAdjuster(by offset: Int, symbol:String) -> some View{
Button (action: {
cardCount += offset
}, label: {
Image(systemName: symbol)
})
}

有两个标签时by offset,第一个by是调用者使用的标签,第二个offset是在函数中使用,symbol既是外部名称又是内部名称

MVVM

MVVM

Separating “Logic and Data” from “UI”

Swift Type System

struct and class

struct是函数式编程的基础

函数式编程 VS 面向对象编程

面向对象编程: 数据封装,封装现实世界概念或事物的数据,然后将功能与该数据相关联,将其全部封装到一个具有与该数据相关的函数的结构中,它增加了继承

函数式编程: 行为封装,在函数式编程中,我们真正想要的东西之一是可证明性(计算机科学中的概念),面向对象编程中无法实现,因为你不知道谁将拥有一个指向你的类的指针,而在函数式编程中,你可以,因为你总是传递其中的内容的副本,没人可以从外部干扰该功能,

函数式编程:behaves like a …

可证明性: 你希望能够获取一段代码并证明它无论发生什么,无论它处于什么环境或其他什么情况下都会做它会做的事情。