当前位置: 首页 > 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判断…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

逻辑回归暴力训练预测金融欺诈

简述 「使用逻辑回归暴力预测金融欺诈&#xff0c;并不断增加特征维度持续测试」的做法&#xff0c;体现了一种逐步建模与迭代验证的实验思路&#xff0c;在金融欺诈检测中非常有价值&#xff0c;本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...