SwiftUI 是一个声明式的 UI 开发方法,在这之前咱们先看看声明式和指令式开发。

指令式 & 声明式 简略了解

指令式编程:经过一些组合句子例如 运算句子、条件句子、循环句子逐条指示计算机怎么工作,为了更好的了解咱们来看下这个比如:

struct Student {
let name: String
let score: Int
}
let zhangsan = Student(name: "zhangsan", score: 100)
let lisi = Student(name: "lisi", score: 60)
let students = [zhangsan, lisi]
咱们假如想要知道分数最高的学生 如下:
var best: (Student, Int)?
for student in students {
 if let tempBest = best {
       if tempBest.1 < student.score {
     best = (student, student.score)
          } else {
        best = (student, student.score)
      }
  }
}

那么假如咱们想知道了这段代码详细是什么意义,必须要清楚的知道每一行指令详细做了什么,这样关于开发人员的要求非常高,并且代码越多隐藏的问题也会越多。

声明式开发正好和这个是对立的,声明式更像是咱们要告知计算机要做什么,例如咱们平时运用的高阶函数,咱们不用去关怀过程,例如上述咱们找到成果最好的学生

let best = students.sorted{$0.score > $1.score}.first

咱们只需要知道这段代码成果是什么。

SwiftUI中,用户界面是严厉被数据驱动的,在运行时,咱们只能经过修正数据来修正界面,不能直接对界面进行调整和操作,下面咱们会有单独文章介绍,这里咱们先简略看看声明式UI

UI 都是经过 View 来出现的,咱们写个简略的 hello SwiftUI

struct TestUI: View {
  var body: some View {
    Text("hello Swift UI")
    Button("test") {
      print("test")
    }
  }
}
这段代码是能够让咱们来实时的看到UI 咱们在body中修正能够实时看到效果
struct TestUI_Previews: PreviewProvider {
  static var previews: some View {
    TestUI()
  }
}

在预览栏中咱们应该能够实时看到一个界面了

UI Modifier

上述代码你是不是会想咱们平时写界面会控制一些label的特点,色彩、字体色彩等,这样不得不引入到Modifier(个人比较喜欢swift的命名方法,简略、语义精确、简略了解), 下面咱们经过比如来看看Modifier对text的影响

My Initial Impressions of the SwiftUI World -- UI 篇

这些都是 View 的 Modifier,当然还有很多能够看官方文档,从图中能够发现,赤色框中和蓝色框中的modifier 是不同的,像蓝色框里这种 font, 字体色彩对次序要求不高,他们是对 Text 自身的特点修正,对布局也不会产生影响,但是赤色框中的pading, background 是对 View 的 extension,对次序有很高的要求,他们是对 View 进行包装并且返回的 View 的封装类, 能够对比下 橘色框和绿色框的pading。

UI 根本布局

经过上述学习咱们了解到 UI 是经过 View 来出现的,接下来经过比如咱们先看看 Swift 里 View 的封装

示例需求: 布局一个 9 宫格的数字展现 从 1-9

1、先看展现部分 最简略的写法如下:

My Initial Impressions of the SwiftUI World -- UI 篇

作为有寻求的技术人员,一定会想笼统这段代码,恰好小编也对代码有寻求的,咱们先来对 Text 进行笼统成为一个通用的 view

struct SudokuItemLabel: View {
  var fontSize: CGFloat = 30 //供给默认值
  var title: String
  var size: CGSize
  var backGroundColor: Color
  var foregroundColor: Color
  var body: some View {
    Text(title)
      .font(.system(size: fontSize))
      .foregroundColor(foregroundColor)
      .background(backGroundColor)
      .frame(width: size.width, height: size.height)
  }
}

然后运用相同的方法对横向进行封装,已然横向是一个相同的逻辑,必定牵扯要动态运用 model 来读取数据,咱们先创建一个 item 作为每个数字的数据源

enum SudokuItem {
  case digit(Int)
}
extension SudokuItem: Hashable {
  var title: String {
    switch self {
      case .digit(let value):
        return String(value)
    }
  }
  var size: CGSize {
    let width = floor((UIScreen.main.bounds.size.width - 20 - 3 * 6) / 4)
    if case .digit(let value) = self, value == 0 {
     return CGSize(width: width * 2, height: 88)
    }
    return CGSize(width: width, height: 88)
  }
}

在对横向 UI 进行封装如下:

struct SudokuItemRow: View {
  let items: [SudokuItem]
  var body: some View {
    HStack {
      ForEach(items, id:.self) {item in
        SudokuItemLabel(title: item.title, size: item.size)
      }
    }
  }
}

再来看下ContentView的代码

My Initial Impressions of the SwiftUI World -- UI 篇

是不是非常简练了,其实封装思想、规划准则都是相同的,只不过 UI 是经过 View 来出现。

希望这段代码能够帮助你快速的入门 SwiftUI, 更多知识能够参考官方文档

关于数据驱动 UI 变化的文章,请看我的下篇文章

juejin.cn/creator/con…