【SwiftUI】学习笔记1-创建第一个iOS应用
本系列将会开发大量实际的项目。
系列为本人学习笔记,资料:《SwiftUI自学成长笔记》-刘铭
资源源代码下载资源:可以在gitee上下载,搜索刘铭即可。
第一章:创建项目
也可以在菜单栏的File中选择Project...来创建项目
然后选择iOS-App
我们如图填写即可,选项对应的介绍请看下面这篇文章:
【Swift】从零开始的Swift语言学习笔记-1:前言&Hello World
创建完成之后,就可以开始写代码了:
在写代码之前,我们需要为项目添加相关素材。
第二章:为项目添加素材
在Xcode开发流程之中,我们可以同时添加多种规格的素材来适应不同的设备、不同的分辨率。导入了对应的素材以后,你就不需要再过多考虑尺寸适配的问题了。
图标素材:下载
首先先介绍一下Xcode的界面,整个开发界面设计得非常好,从左到右,从整体到局部,从大致到细节。
左边是导航栏,可以从这里管理整个项目;
中间是开发界面;
右边是细节界面。
好了,现在为项目添加素材:
在左边的导航栏中双击Assets,资源。
然后导入应用图标,这里大家可以随便调。
请直接添加上面提供的素材即可。
第三章:创建预定义颜色
这个可以用于暗黑模式,非常方便。设置一个Dark Appearance之后,系统就会自动帮你适应iOS操作系统中的暗黑模式api了,非常方便。
点击下面的“+”号,然后选择Color Set
然后命名为:“ColorShadow”
创建好后,里面有两种模式:
任意模式和暗黑模式。
我们把他们都设置为黑色
透明度为60 。
然后我们再添加其他的颜色,这时导入就好了。(直接拖入!)
然后再点击下面那个+号,创一个单独的文件夹整理好。
第四章:导入图片
iOS程序中,我们可以直接使用矢量图(.svg)来避免图像素材在不同分辨率下的适配(失真)等问题。
随便找一个矢量图片做测试即可,普通图片也可以。
其中,值得注意的是,当勾选了下面这个选项的时候,矢量图就不会失真!
第五章:创建启动动画
在2020年苹果开发者大会上,Apple推出了一套制作启动画面的流程,非常方便。
在最左边点击最上面的图标,就看到如上图信息。
点击info,找到Launch Screen键,
点击Launch Screen的“+”号,
value中填入图片名字即可。
第六章:创建卡片视图
左边导航栏右键MyFirstAppApp,选择New File...
然后选择 用户界面的SwiftUI View
命名为CardView
//
// CardView.swift
// MyFirstApp
//
// Created by Remoo on 2022/6/10.
//
import SwiftUI
struct CardView: View {
var body: some View {
Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
}
}
struct CardView_Previews: PreviewProvider {
static var previews: some View {
CardView()
}
}
然后像我这样在这三个地方做好注释,
点击这个Resume就可以进行预览。
在主体部分添加一个容器:ZStack
ZStack{
Text("卡片")
}.frame(width: 335, height: 545)
.background(Color.green)
.cornerRadius(16)
.shadow(radius: 8)
}
横向是HStack,纵向是VStack。ZStack是中心对齐的意思。
现在是创建好了,但是我们要调用我们刚刚创建好的界面。
我们在ContentView中用代码调用即可。
修改的地方:
struct ContentView: View {
var body: some View {
CardView()
}
}
第七章:为卡片视图添加渐变颜色
再添加之前,我们先创建一个储存渐变颜色信息的变量。
我们在CardView的属性声明区域:颜色集(现在颜色集只有两种颜色)
var gradient: [Color] = [Color("Color01"),Color("Color02")]
然后在CardView主题部分中的Background()修改为如下:
.background(
LinearGradient(
gradient: Gradient(colors: gradient),
startPoint: .top, endPoint: .bottom
)
)
第八章:为卡片添加SVG图片、文字等
效果:
//主体
var body: some View {
ZStack{
Image("woman-6787784")
}.frame(width: 335, height: 545)
.background(
LinearGradient(
gradient: Gradient(colors: gradient),
startPoint: .top, endPoint: .bottom
)
)
.cornerRadius(16)
.shadow(radius: 8)
}
}
再添加一些文字。
我们在与Image组件同样的地方添加一个VStack容器,
然后在容器里添加两组文字(Text)。
ZStack{
Image("woman-6787784")
VStack{
Text("Hi,我是标题")
.font(.largeTitle)
.fontWeight(.heavy)
.foregroundColor(.green)
.multilineTextAlignment(.center)
Text("小蚊子")
.fontWeight(.light)
.foregroundColor(.blue)
.italic()//斜体
}.offset(y:-238)
第九章:为卡片添加按钮
Button(action:{
print("用户点击了按钮")
}){
HStack{
Text("小蚊子")
.fontWeight(.heavy)
.foregroundColor(.white)
.accentColor(.white)
}
.padding(.vertical)
.padding(.horizontal,24)
.background(
LinearGradient(
gradient: Gradient(colors: gradient),
startPoint: .leading, endPoint: .trailing
)
)
.clipShape(Capsule())
.shadow(color: Color("ColorShadow"), radius: 6, x: 0, y: 3)
}.offset(y: 200)
padding()用于修正位置,有时候可能需要使用四次,修订上下左右。
我们这个按钮使用了一个HStack容器封装,从左到右的渐变色。
clipShape是将矩形按钮裁切为Capsule(),胶囊形状。
ColorShadow是按钮的阴影,我们设置为60
第十章:循环生成多张卡片
在ContentView中创建一个横向的视野,然后用横向的容器装载Card。
我们也可以使用foreach生成。
第十一章:创建一个数据模型
刚才我们创建的只是一些重复的卡片,现在我们创建一个模型,再用这个模型来存储卡片信息。
在导航栏中新建一个文件,叫CardModel。
输入如下代码,构建结构体 Card
import SwiftUI
struct Card: Identifiable{
var id = UUID()
var title:String
var headline:String
var imageName:String
var callToAction:String
var message:String
var fradientColors:[Color]
}
这里我们需要注意,要将原来的Foundation框架换成SwiftUI。
结构体要符合Identifiable协议,即通过这个结构体实例化的对象必须是唯一的、可标识的。这里UUID()函数作为id值,就是那个标识的,类似于MySQL的key。
这几个变量意思都非常直接,大家应该都能看懂。
弄完这个模型,我们得弄一个真正存储信息的文件。
第十二章:为静态数据创建数组
我们现在先使用比较简单的方法构建这些数据,以后我们会用更加专业的方法。下面这种是最简单滴方式。
在导航栏中创一个新的文件。名字叫:CardData
let cardData:[Card]=[Card()]
Card里面需要填入所有struct里面的参数哦。
即:
import SwiftUI
let cardData:[Card]=[Card(
title: "我是remoo", headline: "嘻嘻", imageName: "Image001", callToAction: "我是开发者", message: "我喜欢你~", fradientColors: [Color("Color04"),Color("Color06")]
)]
第十三章:显示数据
为了实现不同的卡片显示不同的数据,我们需要把CardView里面的属性设置为变量,可供传入。
CardView代码修改为:
//
// CardView.swift
// MyFirstApp
//
// Created by Remoo on 2022/6/10.
//
import SwiftUI
struct CardView: View {
//属性
var card:Card
var gradient: [Color] = [Color("Color03"),Color("Color04")]
//主体
var body: some View {
ZStack{
Image(card.imageName)
VStack{
Text(card.title)
.font(.largeTitle)
.fontWeight(.heavy)
.foregroundColor(.green)
.multilineTextAlignment(.center)
Text(card.headline)
.fontWeight(.light)
.foregroundColor(.blue)
.italic()//斜体
}.offset(y:-238)
Button(action:{
print("用户点击了按钮")
}){
HStack{
Text(card.callToAction)
.fontWeight(.heavy)
.foregroundColor(.white)
.accentColor(.white)
}
.padding(.vertical)
.padding(.horizontal,24)
.background(
LinearGradient(
gradient: Gradient(colors: card.gradientColors),
startPoint: .leading, endPoint: .trailing
)
)
.clipShape(Capsule())
.shadow(color: Color("ColorShadow"), radius: 6, x: 0, y: 3)
}.offset(y: 200)
}.frame(width: 335, height: 545)
.background(
LinearGradient(
gradient: Gradient(colors: card.gradientColors),
startPoint: .top, endPoint: .bottom
)
)
.cornerRadius(16)
.shadow(radius: 8)
}
}
//预览
struct CardView_Previews: PreviewProvider {
static var previews: some View {
CardView(card: cardData[0])
}
}
修改了几处地方:title、headline、imageName、callToAction、gradientColors。
另外预览的部分也要修改,因为当你调用了CardView的时候,我们需要向其传入数据,就是我们下面的数据
也就是在ContentView中把我们的cardData用上。
以下是当前cardData的内容,现在有两个Card结构的数组,可以自行添加其他的内容。
//
// CardData.swift
// MyFirstApp
//
// Created by Remoo on 2022/6/11.
//
import SwiftUI
let cardData:[Card]=[
Card(title: "我是remoo",
headline: "嘻嘻",
imageName: "Image001",
callToAction: "我是开发者",
message: "这是一条信息",
gradientColors: [Color("Color04"),Color("Color06")]
),
Card(title: "我是小蚊子",
headline: "开心~",
imageName: "Image002",
callToAction: "小蚊子",
message:"嗡嗡嗡",
gradientColors: [Color("Color02"),Color("Color06")]
)
]
//
// ContentView.swift
// MyFirstApp
//
// Created by Remoo on 2022/6/10.
//
import SwiftUI
let cards:[Card] = cardData
struct ContentView: View {
var body: some View {
ScrollView(.horizontal,showsIndicators: false){
HStack(alignment: .center, spacing: 20){
ForEach(cards){ item in
CardView(card: item)
}
}.padding(20)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
这里使用了ForEach的其中一种用法,非常方便,这里将会自动读取所有cardData里面的数据,生成卡片。
所有的卡片数据,都可以在cardData里面录入,程序启动时会自动读取。
以上就是目前的全部代码。
第十四章:播放提示声音
播放一些效果音乐会进一步提升用户体验。
先导入音效文件。下载然后解压即可。
导入到导航栏中。确认勾选了:Copy items if needed
在导航栏中新建一个文件,命名为PlaySound
以下代码:
//
// PlaySound.swift
// MyFirstApp
//
// Created by Remoo on 2022/6/12.
//
import Foundation
import AVFoundation
var audioPlayer: AVAudioPlayer?
func playSound(sound: String,type: String){
if let path = Bundle.main.path(forResource: sound, ofType: type){
do{
audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
audioPlayer?.play()
}catch{
print("播放失败。。")
}
}
}
AVFoundation框架是音频视频等播放的API,我们声明一个audioPlayer变量,注意加个问号表示可选性,以免系统出错时带来恶劣的影响。
接着创建一个playSound()函数,第一个参数是音频文件名字,迪厄个参数是音频拓展名字,都是String类型。
这里使用了do catch语句,用于捕捉错误。
在CardView中调用即可。
playSound(sound: "sound-transitions", type: "mp3")
【SwiftUI】学习笔记1-创建第一个iOS应用的更多相关文章
- ios学习总结(1) -- 创建第一个ios项目
原文地址 下载并打开xcode. 接着新建一个工程,如下图所示: 点击Create a new Xcode project,之后选择ios下的Application,点击Single View App ...
- IOS学习笔记48--一些常见的IOS知识点+面试题
IOS学习笔记48--一些常见的IOS知识点+面试题 1.堆和栈什么区别? 答:管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制:对于堆来说,释放工作由程序员控制,容易产生memor ...
- Java学习笔记-多线程-创建线程的方式
创建线程 创建线程的方式: 继承java.lang.Thread 实现java.lang.Runnable接口 所有的线程对象都是Thead及其子类的实例 每个线程完成一定的任务,其实就是一段顺序执行 ...
- springmvc学习笔记---idea创建springmvc项目
前言: 真的是很久没搞java的web服务开发了, 最近一次搞还是读研的时候, 想来感慨万千. 英雄没落, Eclipse的盟主地位隐隐然有被IntelliJ IDEA超越的趋势. Spring从2. ...
- Docker学习笔记之一,搭建一个JAVA Tomcat运行环境
Docker学习笔记之一,搭建一个JAVA Tomcat运行环境 前言 Docker旨在提供一种应用程序的自动化部署解决方案,在 Linux 系统上迅速创建一个容器(轻量级虚拟机)并部署和运行应用程序 ...
- Django:学习笔记(2)——创建第一个应用
Django:学习笔记(2)——创建第一个应用 创建应用 在 Django 中,每一个应用都是一个 Python 包,并且遵循着相同的约定.Django 自带一个工具,可以帮你生成应用的基础目录结构, ...
- Android:日常学习笔记(2)——分析第一个Android应用程序
Android:日常学习笔记(2)——分析第一个Android应用程序 Android项目结构 整体目录结构分析 说明: 除了APP目录外,其他目录都是自动生成的.APP目录的下的内容才是我们的工作重 ...
- Android(java)学习笔记219:开发一个多界面的应用程序之两种意图
1.两种意图: (1)显式意图: 在代码里面用intent设置要开启Activity的字节码.class文件: (2)隐式意图: Android(java)学习笔记218:开发一个多界面的应用程序之人 ...
- Android(java)学习笔记162:开发一个多界面的应用程序之两种意图
1.两种意图: (1)显式意图: 在代码里面用intent设置要开启Activity的字节码.class文件: (2)隐式意图: Android(java)学习笔记218:开发一个多界面的应用程序之人 ...
随机推荐
- HMS Core新闻行业解决方案:让技术加上人文的温度
开发者们,你希望用户如何获取新闻? 有的人靠手机弹窗知天下事,有的人则在新闻应用中尽览每一篇文章:有的人一目十行,有的人则喜欢细细咀嚼:有的人主动探索,有的人则想要应用投其所好. 科技在不断刷新着用户 ...
- iNeuOS工业互联网操作系统,视图建模(WEB组态)增加2154个行业矢量图元、大屏背景及相关图元
1. 概述 现在三维数字孪生(3D)比较流行,各行业各领域的项目也都在上数字孪生项目或是项目中包括数字孪生模块,能做的厂家也很多.从全厂区的应用视觉的冲击力还是比较震撼,但是数字孪生不太可能包括 ...
- RPA SAP财务内部对账机器人
[简介] 本机器人用于使用SAP软件的集团公司间往来对账前台登录SAP账户和密码,需退出PC微信,输入法切换为英文半角状态. [详细流程] 1.清空Excel-VBA管理工具原始数据 2.输入对账时间 ...
- ansible在linux和windows批量部署zabbix-agent2
--- - hosts: linux tasks: - name: copy centos 7 zabbix-agent2 copy: src=zabbix-agent2-5.0.11-1.el7.x ...
- Vue动态组件的实践与原理探究
我司有一个工作台搭建产品,允许通过拖拽小部件的方式来搭建一个工作台页面,平台内置了一些常用小部件,另外也允许自行开发小部件上传使用,本文会从实践的角度来介绍其实现原理. ps.本文项目使用Vue CL ...
- this关键字、static关键字、方法的调用
1.带有static关键字的方法,不可使用this关键字.因为其调用方法为类名.方法名(建议这种方式,调用不需要对象的参与),不存在对象. 2.实例方法调用必须有对象的存在,先创建对象,通过引用.的方 ...
- 聊聊 Netty 那些事儿之 Reactor 在 Netty 中的实现(创建篇)
本系列Netty源码解析文章基于 4.1.56.Final版本 在上篇文章<聊聊Netty那些事儿之从内核角度看IO模型>中我们花了大量的篇幅来从内核角度详细讲述了五种IO模型的演进过程以 ...
- C++ 练气期之二维数组与矩阵运算
1. 前言 C++中的一维数组可以存储线性结构的数据,二维数组可以存储平面结构的数据.如班上所有学生的各科目成绩就有二个维度,学生姓名维度和科目成绩维度. 这样的表格数据可以使用二维数组进行存储. 当 ...
- String长度限制?
String我们在开发和学习中会经常用到,但对String类型的取值范围我们并不明确. String底层是char数组,并未标明长度限制.java中可以对数组指定长度,如果不指定就以实际元素来指定 p ...
- Cascade-LSTM: A Tree-Structured Neural Classifier for Detecting Misinformation Cascades(KDD20)
Cascade-LSTM是一个用于虚假信息级联检测的树结构神经分类器,它本质上是一个谣言(假新闻)检测模型,它将谣言检测任务视为一个树分类问题. Cascade-LSTM在递归神经网络(本文具体基于T ...