SwiftUI-基础入门
开发OS X 图形应用界面时有三种实现方式:XIB、Storyboard、SwiftUI。Storyboard基于XIB做了优化,但XIB基本被放弃了,而SwiftUI是苹果公司后来开发的一套编程语言,用来平替Objective-C。虽然现在Swift 6 还是有些不完善的地方,但可以看到此为未来的主流。
- 本系列课主要讲下SwiftUI方面的知识,不会过多涉及Swift基础语言,Swift可以查看笔者的另一个专题。本节做为第一节内容,主要课下应用构建的基础知识。
- 笔者的开发环境为: Xcode Version 16.1 (16B40)、Swift 5,需要注意不同版本的Xcode其界面会有稍许差异,不同版本的Swift语言的API也会有一定的差异。
创建工程
所有的示例笔者会统一使用MacOS APP做为工程类型(因为IOS模拟器太占资源了),无论是OS还是IOS这对学习SwiftUI没有任何影响。
创建工程
一路Next,最后工程结构如下:
- Preview Content:用于存放预览内容,开发者可以利用这些预览内容来快速查看和验证他们的界面设计在不同设备和屏幕尺寸上的表现,从而提高开发效率和界面质量;
- .entitlements:相当于原来的info.plist文件,用于配置工程的一些设置;
- Assets.xcassets:资源文件,主要用于存放图标;
- XxApp.swift:工程启动入口函数,相当于main();
- ContentView.swift:SwiftUI 界面设计源码,在正式程序中可能会有多个这样的UI界面源码文件,工程默认创建的这个文件会被XxApp.swift调用。
工程源码
- 启动文件
import SwiftUI@main // 注意此标的使用
struct _1_base1App: App { //实现App协议var body: some Scene { //图控制器或应用入口点WindowGroup {ContentView() //调用UI实现类}}
}
- Swift UI 视图
import SwiftUIstruct ContentView: View {var body: some View {VStack { //布局Image(systemName: "globe").imageScale(.large).foregroundStyle(.tint)Text("Hello, world!")}.padding()}
}//这行可有可无,主要是用于开发时实时预览用的
#Preview {ContentView()
}
工程运行
在运行前最基本的有几个设置需要确认一下:
- targets:同一工程可设置多个运行目标,可在项目设置的
General
面板中设置; - swift版本:可在
building settings
面板中设置;
新建界面
如果要创建新的UI,可选择
File- New- File from template
,选择SwiftUI
。
默认代码如下:
import SwiftUIstruct SwiftUIView: View {var body: some View {Text("Hello, World!")}
}#Preview {SwiftUIView()
}
Doc文档
- 中文文档: https://gitee.com/guangjie2021/SwiftUICn
- 苹果官方:https://developer.apple.com/documentation
基础组件
这里只介绍几个,详细的可以参考上述文档中的内容。
Text 文字
基础代码如下,下面代码中有一些是.gray
的写法,其是为了简便编程,把位于SwiftUICore中对象的一些名称在调用时省略了。
import SwiftUIstruct SwiftUIText: View {var body: some View {VStack{Text("这是一个swiftui实现的文本label,可以设置一些属性").font(.custom("slideyouran-Regular", size: 23)).foregroundColor(.gray).lineLimit(2).multilineTextAlignment(.center).padding()Text("以下是一些详情信息").font(.system(size: 23))}.padding()}}#Preview {SwiftUIText()
}
- 自定义字体,在上述代码中有一行
.font(.custom("slideyouran-Regular", size: 23))
代码,这种是一种自定义字体的写法:
- 拷贝.ttf字体文件到工程中;
- 配置工程info信息;
- 编码;
工程info配置方法如下图所示,其中item 0 后面的值为字体的名称,这个名称可能会和文件名不一样,需要在系统中安装一下再确定:
Image 图片
图片有三种实现方式:
加载资源库图标
就是Assets库中的图片,在这个视图中可以添加文件夹等信息,但在使用时不需要关注其路径问题,但也意味着名称要唯一。
Image("DemoImg").resizable().scaledToFit().frame(width: 64).cornerRadius(12)
加载系统图标
苹果官方开发一个名为SF Symbols
图标库的软件,这个软件主要用于查找系统图标名称,同时还能自动生成一些代码,供开发时何用。
这些图标相当于文字图标,可以使用内置函数设置颜色,线条等样式。
Image(systemName: "square.and.arrow.up.circle").font(.system(size: 52)).symbolEffect(.bounce).padding(12)
加载网络图片
就是从互联网上下载图片,但除了打开client设置外,还需要注意URL只能是https开头的。
// 这是一种闭包写法:// image in:这是闭包的开始,image 是闭包的参数,代表加载的图像AsyncImage(url: URL(string: imageUrl)) { image inimage // 这个闭包在图像加载完成后被调用.resizable().scaledToFit().frame(width: 280).cornerRadius(16)} placeholder: {
// Text("图片加载中")
// .font(.system(size: 24))
// .foregroundColor(.gray)
// .padding()
// .frame(width: 280,height: 160)
// .cornerRadius(16)ProgressView()}
自定义组件
SwiftUI的自定义组件比较简单,可以先了解下如何实现,后面章节再详细讲解。
自定义组件
比如如下代码,定义了一个自定义的TextDemo组件。同时也应该注意到,这里可以封装成比较复杂的套件。
import SwiftUI// MARK: - 文字组件
struct TextDemo: View { //组件参数var text: Stringvar textSize: CGFloatvar textColor: Color//组件样式var body: some View {Text(text).font(.system(size: textSize)).foregroundColor(textColor)}
}
自定义组件调用
自定义组件调用
import SwiftUIstruct SloganTextView: View {var body: some View {VStack(spacing: 10) {TextDemo(text: "你好,世界。", textSize: 23, textColor: .black)TextDemo(text: "愿日子如熹光,愿你能幸福~", textSize: 17, textColor: .gray)}}
}
预览效果如下:
布局组件
SwiftUI中内置了三种纯布局组件:VStack、HStack、ZStack,基本代码写法如下,可做为一个容器使用。
struct ContentView: View {var body: some View {VStack {Image(systemName: "globe").imageScale(.large).foregroundStyle(.tint)Text("我是启动页")}.padding()}
}
主界面设计
实现一个底图+图标这样的简单设计。
import SwiftUIstruct StartUpUI: View {var body: some View {ZStack(alignment: .bottom) {// 背景图片Image("starup").resizable()//.aspectRatio(contentMode: .fill).edgesIgnoringSafeArea(.all)VStack {Spacer() // 占位空间// 应用图标和应用名称HStack(alignment: .center, spacing: 20) {// 应用图标Image("DemoImg").resizable().aspectRatio(contentMode: .fit).frame(width: 60).cornerRadius(16)// 应用名称Text("世纪佳人").font(.system(size: 32)).foregroundColor(.white).bold()}}}}
}#Preview {StartUpUI()
}
常用方法
组件设置
以下是一种设计,很多的操作都需要以resizable()为前提。
- resizable():设置组件是否可以改变尺寸;
- aspectRatio():在resizable()打开的,指定调整尺寸时的横纵比和固定比;
- edgesIgnoringSafeArea():屏幕安全区设置;
- frame(width: 60):设置组件大小;
- cornerRadius(32):设置圆角
位置设置
- Spacer():占位符,它会把他后面的元素计算完大小后,然后占据其它空间
`VStack {Text("这是顶部的文本")Spacer() // 占据剩余空间,将下面的文本推到底部Text("这是底部的文本")
}`
- .frame():设置VStack的框架大小,下面这种
infinity
是一种自适应参数方式,非固定大小,建议用这种方式设置。
VStack {......
}
.frame(maxWidth: .infinity, maxHeight: .infinity) // 设置VStack的框架大小
- padding() 修饰符可以接受不同的参数来指定内边距的大小,默认为5px
Text("Hello, SwiftUI!").padding(10.0) // 在文本视图周围添加10点的内边距Text("Hello, SwiftUI!").padding(.init(top: 10, leading: 20, bottom: 15, trailing: 25)) // 设置上、左(leading)、下、右(trailing)内边距Text("Hello, SwiftUI!").padding(.medium) // 使用中等大小的内边距
按钮与交互
SwiftUI的按钮实现有点特殊,它由两部分组成:事件+样式。其事件只有点击,但样式可以根据面要自定义,格式如下:
Button(action: {print("Tap") //事件
}) {Text("I'm a Button") //样式
}
按钮点击
struct TextButton: View {var body: some View {Button(action: { //事件print("aaa")}) {Text("立即使用") //样式.font(.system(size: 17)).foregroundColor(.white).padding().frame(width: 180).background(LinearGradient(gradient: Gradient(colors: [Color.blue, Color.green]), startPoint: .leading, endPoint: .trailing)).cornerRadius(16)}}
}
上述的样式部分也可以换成图标,如下面代码
struct ImageBtnView: View {var body: some View {Button(action: {// 点击后的操作}) {Image("WoodenFish").resizable().scaledToFit().frame(width: 160)}}
}
onTapGesture()手势
下面代码中用到了@State
,其为状态缓存,用于MVVM交互使用的。
struct SwiftUIButton: View {@State var finNumber: Int = 1var body: some View {// 布局容器VStack(spacing: 32) {// 文字内容Text("功德+" + String(finNumber)).font(.system(size: 20)).foregroundColor(.black)// 图片按钮Image("WoodenFish").resizable().scaledToFit().frame(width: 160)// 点击操作.onTapGesture {finNumber += 1}}}
}
相关文章:

SwiftUI-基础入门
开发OS X 图形应用界面时有三种实现方式:XIB、Storyboard、SwiftUI。Storyboard基于XIB做了优化,但XIB基本被放弃了,而SwiftUI是苹果公司后来开发的一套编程语言,用来平替Objective-C。虽然现在Swift 6 还是有些不完善的地方&…...

C++builder中的人工智能(20):如何在C++中开发一个简单的Hopfield网络
在AI技术的发展历史中,模式识别模型是最伟大的AI技术之一,尤其是从像素图像中读取文本。其中一个是Hopfield网络(或称为Ising模型的神经网络或Ising–Lenz–Little模型),这是一种递归神经网络形式,由John J…...

video2gif容器构建指南
一、介绍 1.项目概述 Video2Gif 项目旨在提供一种便捷的方式,让用户能够将视频中的精彩片段快速转换为 GIF 动画。GIF 动画因其循环播放、文件体积小等特点,在社交媒体、聊天工具中广泛应用,用于表达情感、分享趣事等。 2.核心功能 视频导…...

探秘Spring Boot中的@Conditional注解
文章目录 1. 什么是Conditional注解?2. 为什么需要Conditional注解?3. 如何使用Conditional注解?4. Conditional注解的高级用法5. 注意事项6. 结语推荐阅读文章 在Spring Boot的世界里,配置的灵活性和多样性是至关重要的。有时候&…...

树形dp总结
这类题型在 dp 中很常见,于是做一个总结吧!!! 最经典的题:没有上司的舞会 传送门:没有上司的舞会 - 洛谷 状态表示: dp[i][0] 为 以 i 为根的子树中,选择 i 节点的最大欢乐值 d…...

【算法一周目】双指针(2)
目录 有效三角形的个数 解题思路 C代码实现 和为s的两个数字 解题思路 C代码实现 三数之和 解题思路 C代码实现 四数之和 解题思路 C代码实现 有效三角形的个数 题目链接:611. 有效三角形的个数题目描述:给定一个包含非负整数的数组nums&…...

vue内置方法总结
目录 1. 生命周期钩子方法 2. 响应式系统方法 3. DOM 更新方法 4. 事件处理方法 5. 访问子组件和 DOM 元素 6. 数据观察方法 7. 其他方法 1. 生命周期钩子方法 这些方法在 Vue 实例的不同生命周期阶段自动调用。 beforeCreate: 在实例初始化之后,…...

面向对象分析与设计
前言: 感觉书本上和线上课程, 讲的太抽象, 不好理解, 但软件开发不就是为了开发应用程序吗?! 干嘛搞这么抽象,对吧, 下面是个人对于软件开发的看法, 结合我的一些看法, 主打简单易懂, 当然,我一IT界小菜鸟, 对软件开发的认识也很浅显, 这个思维导图也仅仅是现阶段我的看…...

lineageos-19 仓库群遍历,打印第一条git log
lineageos-19 仓库群遍历,打印第一条git log RepoLsRootD/app4/lineage19_oneplus6 LogF/app4/wiki/repo_head_log_ls-lineageos19.1.log rm -v $LogF && \ cd $RepoLsRootD && \ find . -type l -path "*/*.git" -not -path "./.repo/*"…...

详解基于C#开发Windows API的SendMessage方法的鼠标键盘消息发送
在C#中,SendMessage方法是一个强大的工具,它允许我们与Windows API交互,模拟键盘和鼠标事件。本文将详细介绍如何使用SendMessage方法来发送鼠标和键盘消息。 1. SendMessage方法概述 SendMessage是Windows API中的一个函数,它用…...

VMware安装黑苹果后ICLOUD_UNSUPPORTED_DEVICE(不支持的Icloud设备)
修改文件 关闭虚拟机找到虚拟机文件中以.vmx结尾的文件编辑内容(补充缺失) board-id "Mac-551B86E5744E2388" hw.model.reflectHost "FALSE" hw.model "MacBookPro14,3" serialNumber.reflectHost "FALSE"…...

Python | Leetcode Python题解之第542题01矩阵
题目: 题解: class Solution:def updateMatrix(self, matrix: List[List[int]]) -> List[List[int]]:m, n len(matrix), len(matrix[0])# 初始化动态规划的数组,所有的距离值都设置为一个很大的数dist [[10**9] * n for _ in range(m)]…...

【计算机网络】【传输层】【习题】
计算机网络-传输层-习题 文章目录 10. 图 5-29 给出了 TCP 连接建立的三次握手与连接释放的四次握手过程。根据 TCP 协议的工作原理,请填写图 5-29 中 ①~⑧ 位置的序号值。答案技巧 注:本文基于《计算机网络》(第5版)吴功宜、吴英…...

【LeetCode】【算法】55. 跳跃游戏
LeetCode 99 - 55. 跳跃游戏 题目 给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标,如果可以,返回true;否则,返回 …...

华为:hcia综合实验
一、拓扑图 二、实验要求 1. pc地址请自行规划,vlan已给出 2. 服务器地址自行规划,vlan,网段已给出 3. 交换机互联链路捆绑保证冗余性 4. 内网pc网关集中于核心交换机,交换机vlan 40互联路由器 ,地址网段已给出 5.配置静态路由实…...

MyBatis与MyBatis-Plus(基础)
MyBatis-Plus的优势 在 Spring Data JPA 已经很方便的情况下,有时仍然选择使用 MyBatis-Plus 的核心原因主要有以下三点: 1. 复杂 SQL 控制能力更强 MyBatis-Plus 允许直接编写和优化 SQL,适合复杂查询、精细化 SQL 控制的场景。特别是在性…...

一文总结java语法规则
1. 题记 Java是一门拥有较强语法规则的编程语言,本博文主要总结介绍java语言的java语法规则。 2. java语法规则 2.1 标识符(Identifiers) 定义:标识符是用来给变量、类、方法、接口等命名的字符序列。规则: –标识…...

使用 npm 安装 Yarn
PS E:\WeChat Files\wxid_fipwhzebc1yh22\FileStorage\File\2024-11\spid-admin\spid-admin> yarn install yarn : 无法将“yarn”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后…...

vue3中利用路由信息渲染菜单栏
1. 创建路由时将路由信息对象进行抽离 将路由信息对象单独抽离到router/routes.ts文件 关键:利用路由元信息meta,定义3个属性 hidden:控制当前路由是否显示在菜单栏中title:菜单拦名称icon:对应菜单名称前面的图标 …...

Mysql每日一题(行程与用户,困难※)
今天给大家分享一个截止到目前位置,我遇到最难的一道mysql题目,非常建议大家亲手做一遍 完整代码如下,这道题的主要难点是它有两个外键,以前没遇到过,我也没当回事,分享一下错误经验哈 当时我写的where判断…...

adb 命令 查找启动的包名以及导出安装包
查看安卓内包名 adb 查看所有安装的包 adb shell pm list packages查看安装的第三方app的包名 adb shell pm list packages -3查看启动的app的包名 adb shell dumpsys activity top | find "ACTIVITY"adb shell dumpsys activity activities | findstr "Run…...

Flink_DataStreamAPI_输出算子Sink
Flink_DataStreamAPI_输出算子Sink 1连接到外部系统2输出到文件3输出到Kafka4输出到MySQL(JDBC)5自定义Sink输出 Flink作为数据处理框架,最终还是要把计算处理的结果写入外部存储,为外部应用提供支持。 1连接到外部系统 Flink的D…...

标准C++ 字符串
一、标准库中的字符串类型 在C中,字符串是一个非常重要的数据类型,用于表示和处理文本信息。C提供了多种方式来处理字符串,每种方式都有其特点和适用场景。以下是几种常见的字符串类型及其用法: 1. C 风格字符串 (char* 或 char…...

时序预测:多头注意力+宽度学习
✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢,在这里我会分享我的知识和经验。&am…...

day06(单片机)IIC+STH20
目录 IICSHT20 I2C基础简介 为什么I2C需要使用上拉电阻? I2C特点 时序图分析 起始信号与终止信号 数据传输时序 字节传输和应答信号 I2C寻址 主机给从机发送一个字节 主机给从机发送多个字节 主机从从机接收一个字节 主机从从机接收多个字节 I2C寄存器 I2C_RXDR&…...

Bugku CTF_Web——文件上传
Bugku CTF_Web——文件上传 进入靶场 My name is margin,give me a image file not a php抓个包上传试试 改成png也上传失败 应该校验了文件头 增加了文件头也不行 试了一下 把文件类型改成gif可以上传 但是还是不能连接 将Content-Type改大小写 再把文件后缀名改成php4 成…...

C#版使用融合通信API发送手机短信息
目录 功能实现 范例运行环境 实现范例 类设计 类代码实现 调用范例 总结 功能实现 融合云通信服务平台,为企业提供全方位通信服务,发送手机短信是其一项核心功能,本文将讲述如何使用融合云服务API为终端手机用户发送短信信息…...

人工智能:重塑医疗、企业与生活的未来知识管理——以HelpLook为例
一、医疗行业:AI引领的医疗革新 随着人工智能(AI)技术的持续飞跃,我们正身处一场跨行业的深刻变革之中。在医疗健康的广阔舞台上,人工智能技术正扮演着日益重要的角色。它不仅能够辅助医生进行病例的精准诊断…...

MVVM(Model-View-ViewModel)模型
MVVM(ModelViewViewModel)模型是一种常用于软件开发中的架构模式,尤其在前端框架(如 Vue.js、React、Angular)中被广泛应用。它将程序的用户界面与业务逻辑分离,便于维护和扩展。 MVVM 的三个组成部分 1. …...

权限系统:权限应用服务设计
今天聊聊权限系统的应用服务设计。 从业务需求的角度来看,权限系统需要解决两个核心问题: 1、菜单渲染与动态展示 当用户成功登录并接入系统后,系统需要动态获取并展示该用户有权限访问的菜单项。 这一过程涉及前端系统与权限系统的交互。前端…...