当前位置: 首页 > news >正文

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))代码,这种是一种自定义字体的写法:
  1. 拷贝.ttf字体文件到工程中;
  2. 配置工程info信息;
  3. 编码;

工程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: 在实例初始化之后&#xff0c…...

面向对象分析与设计

前言: 感觉书本上和线上课程, 讲的太抽象, 不好理解, 但软件开发不就是为了开发应用程序吗?! 干嘛搞这么抽象,对吧, 下面是个人对于软件开发的看法, 结合我的一些看法, 主打简单易懂, 当然,我一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判断…...

XCTF-web-easyupload

试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...

golang循环变量捕获问题​​

在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下: 问题背景 看这个代码片段: fo…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...