SwiftUI - 学习

1. SwiftUI-第一天

1. 1SwiftUI的基本架构

在这里插入图片描述
这里介绍下SwiftUI中特有的两个文件,至于其他的文件大家都很熟悉了,这里就不多做介绍了。

  • ContentView.swift 包含程序的初始用户界面(UI),是我们在此项目中执行所有工作的地方
  • Preview Content 是一个黄色文件夹,其中包含Preview Assets.xcarets —— 这是另一个资源目录,特别是您在设计用户界面时要使用的图像,以便让您了解它们在程序运行时的外观
import SwiftUI

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

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

在我们开始编写自己的代码之前,有必要过一下我们没有见过的新功能

  • import SwiftUI告诉Swift我们希望使用SwiftUI框架提供的所有功能。苹果为我们提供了很多框架,比如机器学习、音频播放、图像处理等等,所以我们不想假设我们的程序想要使用所有的东西,而是说我们想使用哪些部分,以便加载它们。

  • struct ContentView: View创建一个名为ContentView的新结构体,表示它遵循View的协议.View来自SwiftUI,它是您想在屏幕上绘制的任何内容都必须采用的基本协议——所有文本、按钮、图像等都是视图,包括您自己的布局,可以组合其他视图。

  • var body: some View定义了一个计算属性body,它有一个有趣的类型:some View。这意味着它返回符合视图协议的内容。但额外的some关键字添加了一个重要限制:它必须始终是被返回的同一类型的视图——您不能有时返回一种类型的内容,有时又返回另一种不同类型的内容。
    View协议只有一个要求,即您有一个名为body的计算属性,该属性返回some View。您可以(也将会)向视图结构中添加更多的属性和方法,但body是唯一一个必须要有的。

  • Text(“Hello World”)使用字符串“Hello World”创建一个文本视图。文本视图是绘制到屏幕上的简单静态文本,并将根据需要自动换行。

ContentView结构体下面,您将看到一个ContentView_Previews结构体,它遵循PreviewProvider协议。这段代码实际上不会构成最终应用程序的一部分,而是专门供Xcode使用,以便它可以在代码旁边显示UI设计的预览。

1.2 创建表单

许多应用程序都要求用户输入某种内容——可能是要求他们设置一些偏好,可能是要求他们确认他们想要车去哪里接他们,可能是从菜单上订购食物,或是其他类似的东西。

SwiftUI为此提供了一个专用的视图类型,称为Form.表单是正在滚动静态控件列表像文本和图像,但是也可以包括文本字段、切换按钮、按钮等用户交互控件

//创建一个结构体,遵守View的协议,view是所有屏幕显示的内容的基本协议
struct ContentView: View {
    var body: some View {
        //这个必须返回同一类型的视图
        Form {
            //创建一个文本视图,内容为Hello, World!
            
//            Text("Hello, World!")
            
            
            //SwiftUI中 一个父视图中,最多只能有10个子视图(是直接子视图,不包括子视图中的子视图)
            //如果想要解决这个问题 我们可以使用Group来将解决
            //相当于表哥头视图 和尾视图  通过这种方式可以将表单拆分成多个部分
            Section {
                Text("Hello,dasdsadsa")
            }
            //如果需要再表单中包含超过10以上的内容,可以使用Group来分组,Group不会改变用户界面的外观,它们只是让我们绕过了SwiftUI在父视图中只包含10个子视图的限制
            Group {
                Text("Hello, Worlssssd!")
            }
            Group {
                Text("Hello, World!")
            }
            
            //如果希望表单在将其项拆分为块时看起来不同,则应改用Section视图。这会将表单拆分为不同的可视组,就像设置应用程序所做的那样
            Section {
                Text("footer")
                Text("Hello, World!")
            }
            
        }
        //这样直接发安徽两个文本内容k容器是错误的,需要被包裹在一个容器中 入Form表单
//        Text("Hello, World!")
//        Text("Hello, world!")
    }
}
  • 注意:在SwiftUI中,一个父级中有10个子级的限制实际上适用于所有地方。

1.3 添加导航栏

  • 我们可以仿造添加一个表单一样添加一个导航栏视图(NavigationView:导航栏视图
struct ContentView: View {
    var body: some View {
        //以同样的方式 防止一个导航栏视图 swiftUI中 NavigationView
        NavigationView {
            Form {
                Section {
                    Text("hello World!")
                }
            }.navigationBarTitle("SwiftUI导航栏").navigationBarItems(leading: Text("左侧lable"))  //链式语法来赋值
            //参考页面 iphone手机设置页面
            // navigationBarTitle("SwiftUI导航栏", displayMode: .inline) //使用一个小的标题
            
            //navigationBarTitle("SwiftUI导航栏")
            //当我们将.navigationBarTitle()修饰符附加到表单时,Swift实际上会创建一个新表单,该表单具有导航栏标题和您提供的所有现有内容。
            
            //因此使用大标题是很常见的
        }
    }
}

1.3 修改程序状态

  • 创建一个按钮点击事件来改变属性状态
struct ContentView: View {
    
    /// 定义一个储存属性
    var tapCount = 0
    
    @State private var tapCountTwo = 0
    var body: some View {
        //如果和在SwiftUI上 修改状态 - 例子 : 创建点击事件按钮,修改变量的值
        //使用闭包的方式 创建一个带点击事件的按钮
        Button("Tap Count:\(tapCountTwo)") {
            //self.tapCount += 1
            //这样看起来很合理 由于contenView是个stuct,如果修改结构体中的储存属性,需要加上mutating,例如 mutating var body: some View,但是swift中不允许我们创建一个可变的计算属性
            // 根据这种情况 SwiftUI中为我们提供一个@State 属性包装器 @State允许我们绕过结构体的限制:我们知道不能更改它们的属性,因为结构是固定的,但是@State允许SwiftUI将该值单独存储在可以修改的地方。
            self.tapCountTwo += 1
        }
    }
}
  • 注意@State允许我们绕过结构体的限制:我们知道不能更改它们的属性,因为结构是固定的,但是@State允许SwiftUI将该值单独存储在可以修改的地方。
  • 提示:@State是专门为存储在一个视图中的简单属性而设计的。因此,苹果建议我们向这些属性添加私有访问控制,比如:@State private var tapCountTwo = 0

1.4 状态绑定到UI控件

  • 如果把一个属性和控件实现双向绑定,控件可以读取也可以修改属性值, SwiftUI中使用$来实现双向绑定
struct ContentView: View {
    //如果实现属性和 UI控件的绑定 使用的是$符号,如果属性前不使用$符号,就表示读取属性,并不形成双向绑定,也不能修改属性
    @State private var name = ""
    
    var body: some View {
        Form {
            TextField("Enter your name", text: $name)
            //这里我们没有使用$符号,意味着这里我们不需要使用双向绑定, 我们想读取值,但是我们不想已某种方式将其写会,因为文本视图不会改变
            Text("Your name is: \(name)")
        }
    }
}

1.5 在循环中创建视图

  • SwiftUI为此提供了一个专用的视图类型,称为ForEach。这可以在数组和范围上循环,根据需要创建尽可能多的视图。更妙的是,ForEach不会像我们手动输入视图一样被10个视图限制所影响。
struct ContentView: View {
    var body: some View {
       // 使用循环创建多个窗体  可以绕过手动创建视图不能超过10个的限制影响
        Form {
//            ForEach(0..<100) { index in
//                Text("\(index)")
//            }
            //ForEach 使用闭包,我们可以对参数名使用速记语法
            ForEach(0..<100) {
                Text("\($0)")
            }
        }
    }
}
  • ForEach在使用SwiftUIPicker视图时特别有用,它允许我们显示各种选项供用户选择。
  • 我们定义一个视图:
    1. 有一系列可能的学生名称
    2. 具有一个@State属性存储当前选定学生。
    3. 创建一个Picker视图,要求用户选择他们最喜欢的,并将选择的值和@State属性双向绑定。
    4. 使用ForEach循环遍历所有可能的学生姓名,将其转换为文本视图。
struct ContentView: View {
    //常量不需要@State修饰 ,因为常量不会改变
    let student = ["Hanry","hermione","Ron"]
    
    @State private var currentStudent = 0
    
    var body: some View {
        VStack {
            //原来的PiackerView
            //Picker与currentStudent有双向绑定,这意味着它将开始显示0的选择,但是在用户滑动选择器时更新属性。
            Picker("Selected your Student", selection: $currentStudent) {
                ForEach(0..<student.count) { index in
                    Text(self.student[index])
                    //Text(self.student[$0])
                }
            }
            Text("Your choose :Student #\(student[currentStudent])")
        }
    }
}

SwiftUI-第二天

  • 今天又4个主题需要解决,您将在其中运用有关form@StatePicker等知识
  1. 使用TextField读取用户的输入
  2. 在表单中创建选择器
  3. 使用分段控件选择百分比
  4. 计算每个人的金额
  • 示例代码:
struct ContentView: View {
    //1.我们构建一个账单分割应用程序,这意味着用户需要输入他们的账单话费、多少人分担,以及他们想留下的消费, 所以我需要声明3个可以修改的属性
    @State private var currentMonery = "" //SwiftUI必须使用字符串来存储TextField输入值。
    @State private var numberOfPeople = 2
    @State private var tipPercentage = 2 //百分比数组的下标
    
    let tipPercentages = [10,15,20,25,0] //百分比  例子10 代表想留下10%的消费
    
    //定义一个计算属性,计算每个人最终应付的钱数
    var totolPerPerson: Double {
        let perpleCount = Double(numberOfPeople+2)//用餐人数
        let tipSelection = Double(tipPercentages[tipPercentage])//给小费的%比
        let orderAmout = Double(currentMonery) ?? 0 //订单签署
        
        let tipValue = orderAmout / 100  * tipSelection //小费
        let grandTotal = orderAmout + tipValue //总钱数
        let amoutPerPerson = grandTotal / perpleCount //每个人应该付的钱
        
        return amoutPerPerson
    }
    
    var body: some View {
        NavigationView {
            Form {
                /**
                1.我们的文本输入框与currentMonery属性有双向绑定。
                2.checkAmount属性用@State标记,它自动监视值的更改。
                3.当@State属性更改时,SwiftUI将重新调用body属性(即,重新加载我们的UI)
                4.因此,文本视图将获得currentMonery的更新值。
                */
                Section {
                    //把文本框的值和currentMonery属性双向绑定 ,双向绑定之后会自动监听值的改变
                    TextField("Amount", text: $currentMonery)
                        .keyboardType(UIKeyboardType.decimalPad)
//                    $numberOfPeople  下标表示的值
                    Picker("Number of people", selection: $numberOfPeople) {
                        ForEach(2..<100) {
                            Text("\($0) people")
                        }
                    }
                }
                
                //设置分区头的内容
                Section(header: Text("How much tip do you want to leave?")) {
                    Picker("Tip percentage", selection: $tipPercentage) {
                        ForEach(0 ..< tipPercentages.count) {
                            Text("\(self.tipPercentages[$0])%")
                        }
                    }.pickerStyle(SegmentedPickerStyle())//表示分段空控件
                }
                
                Section {
                    Text("$\(totolPerPerson)")
                }
            }.navigationBarTitle("WeSplit") //直接设置表单的标题
            //很多人认为应该将修饰符附加到NavigationView的末尾,但是需要将其附加到表单的末尾。
            //原因是导航视图能够在程序运行时显示许多视图,因此通过将标题附加到导航视图中的内容,我们允许iOS自由更改标题。
        }
    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【课程特点】1、231节大容量课程:包含了SwiftUI的大部分知识点,详细讲解SwiftUI的方方面面;2、15个超级精彩的实例:包含美食、理财、健身、教育、电子商务等各行业的App实例;3、创新的教学模式:手把手教您SwiftUI用户界面开发技术,一看就懂,一学就会;4、贴心的操作提示:让您的眼睛始终处于操作的焦点位置,不用再满屏找光标;5、语言简洁精练:瞄准问题的核心所在,减少对思维的干扰,并节省您宝贵的时间;6、视频短小精悍:即方便于您的学习和记忆,也方便日后对功能的检索;7、齐全的学习资料:提供所有课程的源码,在Xcode 11 + iOS 13环境下测试通过; 更好的应用,更少的代码!SwiftUI是苹果主推的下一代用户界面搭建技术,具有声明式语法、实时生成界面预览等特性,可以为苹果手机、苹果平板、苹果电脑、苹果电视、苹果手表五个平台搭建统一的用户界面。SwiftUI是一种创新、简单的iOS开发中的界面布局方案,可以通过Swift语言的强大功能,在所有的Apple平台上快速构建用户界面。 仅使用一组工具和API为任何Apple设备构建用户界面。SwiftUI具有易于阅读和自然编写的声明式Swift语法,可与新的Xcode设计工具无缝协作,使您的代码和设计**同步。自动支持动态类型、暗黑模式、本地化和可访问性,意味着您的**行SwiftUI代码已经是您编写过的非常强大的UI代码了。 

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值