Inits,Enums in SwiftUI

2,360 阅读5分钟

今天主要说说SwiftUI页面的Init,以及Enum的用法,这个很简单,但是也需要说一下。当你在初始化做一些改动时,你就会用上。枚举就不用说太多了,因为几乎和其他的语言用法很类似。比如你要描述上下左右,如果新手就会使用硬编码使用字符来判断,但是如果引入enum后,我们的代码可读性就会大幅度提升,结构也会变得更和谐。好了我们来一起看看吧


Init

我们的例子是一个简单的页面,总共有三个参数,水果的数量,水果的颜色,水果的名称,具体如下

image.png

当我们去掉属性的默认值,那么就必须要从初始化View时传入参数。但是我们却看不到Init方法。

我们在Preview的方法里面传入了对应的参数,如果不传入就会报错。

image.png

那么其实每个View都有一个隐藏的方法,比如我上面声明的三个属性,那么View会自动生成一个init方法

struct InitAndEnumsSample: View {
    let background: Color
    let count: Int
    let fruit: String
    
    init(background: Color, count: Int, fruit: String) {
        self.background = background
        self.count = count
        self.fruit = fruit
    }
    
    var body: some View {
        VStack(spacing: 10) {
            Text("(count)")
                .font(.largeTitle)
                .foregroundColor(Color.white)
                .underline()
            
            Text("(fruit)")
                .font(.headline)
                .foregroundColor(Color.white)
        }
        .frame(width: 150, height: 150)
        .background(background)
        .cornerRadius(8)
    }
}

你可以用两种方法来证明。

方法一

使用编译过程中的相关命令,下面的方法是把文件生产汇编

swiftc -emit-silgen InitAndEnumsSample.swift -o xxx.sil

生成后打开文件,你可以看到一下内容(并不是全部的汇编文件)

image.png

以上文件的倒数第二行,可以看到其实编译后的文件会默认添加一个init方法,参数和我们上面声明的属性对应

image.png

这是另一处,具体初始化的地方。具体的汇编代码,后面有时间我也会出一篇教程。现在只需要知道init是View文件隐藏的方法即可。

方法二

我们可以从新定义一个新的init方法。

image.png

我们定一个新的init方法,只有两个参数。此时如果我们不改变Preview传入的参数,那么就会报错,原因是之前的默认init方法已经被我们改变了,所以原来的方法找不到了,所以会报错。当我们使用新定义的init方法就不会有问题了

image.png

这样可以证明,它有一个默认的init方法,当我们重新定义init方法时,就需要使用新的init方法来初始化

我们现在有一个新的需求,输入一个水果名称,就可以给出对应的水果颜色和水果名称

如果是刚入门的新手一般会使用字符匹配来完成这个任务,例如下面的代码

init(count: Int, fruit: String) {
        self.count = count
        self.fruit = fruit
        
        if fruit == "Apple" {
            self.background = Color.red
        } else if fruit == "Grape"{
            self.background = Color.green
        } else {
            self.background = Color.blue
        }
    }

会根据水果的名称来给出对应的颜色值填充。这样也可以达到目的,但是对于维护来说很不容意,如果这样的代码用在了多处,如果有一个产品的需求需要改某一个判断条件的值,那么所以这种硬编码的地方都需要改,而且容易出错,所有我们会使用枚举来完成这个工作。


Enum

Swift编程语言中的Enum(枚举)时,它是一种用于定义一组相关值的数据类型。Enum在Swift中被广泛应用,用于创建具有离散值的类型,以提高代码的可读性和可维护性。

Enum允许您定义一组可能的值,每个值都被称为一个”case”(情况)。每个case可以关联一个特定的值或者是没有关联值的情况。

以下是一个简单的例子,展示了如何创建和使用Enum:

enum CompassDirection {
    case north
    case south
    case east
    case west
}

let direction = CompassDirection.north

switch direction {
case .north:
    print("Heading north")
case .south:
    print("Heading south")
case .east:
    print("Heading east")
case .west:
    print("Heading west")
}

在上述示例中,我们定义了一个名为CompassDirection的Enum,表示罗盘的方向。该Enum有四个case:northsoutheastwest。我们可以使用这些case来表示不同的罗盘方向。

在switch语句中,我们根据direction的值来执行不同的操作。这种方式使代码更易读和维护,因为我们可以直观地理解每个case代表的具体含义

有了以上例子,基本你应该知道枚举是干啥的了。那么我们改造一下我们之前的例子,把枚举应用其中。

init(fruit: Fruit, count: Int) {
        self.count = count
        
        if fruit == .Apple {
            self.background = Color.red
            self.fruitName = "Apple"
        } else {
            self.background = Color.green
            self.fruitName = "Grape"
        }
    }
    
    enum Fruit {
        case Apple
        case Grape
    }

首先我们定义枚举值,apple和grape。初始化方法也经过了稍微改造,变成了传入一个枚举值和一个数量参数,判断部分还是没变,只不过判断的类型由之前的String,变成了现在的枚举。在prview这里也由之前的string变成了枚举

struct InitAndEnumsSample_Previews: PreviewProvider {
    static var previews: some View {
        InitAndEnumsSample(
            fruit: .Apple,
            count: 10
        )
    }
}

来看看最终的效果,我们在priview里面创建了两个实例。一个传入apple,一个传入Grape。

image.png

最终的代码

import SwiftUI

struct InitAndEnumsSample: View {
    
    let background: Color
    let count: Int
    let fruitName: String
    
    init(fruit: Fruit, count: Int) {
        self.count = count
        
        if fruit == .Apple {
            self.background = Color.red
            self.fruitName = "Apple"
        } else {
            self.background = Color.purple
            self.fruitName = "Grape"
        }
    }
    
    enum Fruit {
        case Apple
        case Grape
    }
    
    var body: some View {
        VStack(spacing: 10) {
            Text("(count)")
                .font(.largeTitle)
                .foregroundColor(Color.white)
                .underline()
            
            Text("(fruitName)")
                .font(.headline)
                .foregroundColor(Color.white)
        }
        .frame(width: 150, height: 150)
        .background(background)
        .cornerRadius(8)
    }
}

struct InitAndEnumsSample_Previews: PreviewProvider {
    static var previews: some View {
        HStack {
            InitAndEnumsSample(
                fruit: .Apple,
                count: 10
            )
            InitAndEnumsSample(
                fruit: .Grape,
                count: 8
            )
        }
    }
}

这一节并不难,当你有需求在初始化是对某些数据要做处理时,不妨多向这个方向想想。

谢谢观看,喜欢就点击加个小爱心吧