SwiftUI Release 引入的辅助焦点管理

news2024/11/23 13:42:08

在这里插入图片描述

文章目录

    • 前言
    • 使用 @FocusState 属性包装器
    • 高级技巧:专用辅助技术
    • 可聚焦字段的高级用法
    • 优化体验
    • 运行截图
    • 总结

前言

SwiftUI Release 引入了强大的新功能,其中之一是辅助焦点管理。

这个新功能使得在SwiftUI中处理辅助技术(如 VoiceOver 和 Switch Control)的焦点状态变得更加轻松。本文将介绍如何使用 @FocusState 属性包装器来在SwiftUI中管理和移动辅助焦点。

在这里插入图片描述

使用 @FocusState 属性包装器

在 SwiftUI Release 中,我们获得了一整套特殊工具来更有效地处理辅助焦点。其中包括 @FocusState 属性包装器和 focused 视图修饰符。通过使用这些工具,我们能够以与无辅助技术相同的方式处理辅助焦点。

核心代码如下:

import SwiftUI

struct SignInView: View {
    @FocusState
    private var isEmailFocused: Bool

    @State private var email = ""

    var body: some View {
        NavigationView {
            Form {
                TextField("Email", text: $email, prompt: Text("Enter your email"))
                    .focused($isEmailFocused)
            }
            .navigationTitle("Sign In")
            .onChange(of: isEmailFocused) { newValue in
                print(newValue)
            }
        }
    }
}

如上例所示,我们使用 @FocusState 属性包装器定义一个变量,表示 email 字段是否聚焦。SwiftUI 默认使用 false 值初始化该变量,因为用户可以聚焦屏幕的任何其他区域。我们还使用 focused 视图修饰符将特定视图的焦点状态绑定到保存其值的变量。

请记住,您可以声明尽需要的变量,以使用 @FocusState 属性包装器涵盖辅助焦点逻辑。

高级技巧:专用辅助技术

核心代码如下:

import SwiftUI

struct SignInView: View {
    @FocusState
    private var isEmailFocused: Bool
    
    @FocusState
    private var isPasswordFocused: Bool

    @State private var email = ""
    @State private var password = ""

    var body: some View {
        NavigationView {
            Form {
                TextField("Email", text: $email, prompt: Text("Enter your email"))
                    .focused($isEmailFocused)
                SecureField("Password", text: $password, prompt: Text("Enter your password"))
                    .focused($isPasswordFocused)
            }
            .navigationTitle("Sign In")
        }
    }
}

@FocusState 属性包装器的好处之一是您可以将其行为限制为专用辅助技术。例如,您可以仅为VoiceOver或Switch Control激活 @FocusState 属性包装器。默认情况下,SwiftUI 会将设备上可用的所有辅助技术的值进行聚合。

可聚焦字段的高级用法

核心代码如下:

import SwiftUI

struct SignInView: View {
    @FocusState(for: .switchControl)
    private var isEmailFocused: Bool

    @State private var email = ""

    var body: some View {
        NavigationView {
            Form {
                TextField("Email", text: $email, prompt: Text("Enter your email"))
                    .focused($isEmailFocused)
            }
            .navigationTitle("Sign In")
            .onChange(of: isEmailFocused) { newValue in
                print(newValue)
            }
        }
    }
}

如上例所示,我们使用 @FocusState 属性包装器为 Switch Control 定义了可选变量 isEmailFocused,以便在用户在视图之间移动焦点时进行切换。

通常,屏幕上有多个元素,您可能希望在它们之间移动焦点。为了支持这种情况,SwiftUI 提供了一种通过枚举定义可聚焦字段并在它们之间切换的方法。这种方法是使用 @FocusState 属性包装器,并为其提供一个用于标识焦点类型的参数(在此例中是 .switchControl)。

优化体验

全部代码如下:

import SwiftUI

enum FocusableField: Hashable {
    case email
    case password
}

struct ContentView: View {
    @State private var email = ""
    @State private var password = ""
    
    @FocusState
    private var focus: FocusableField?

    var body: some View {
        NavigationView {
            Form {
                TextField("email", text: $email, prompt: Text("email"))
                    .focused($focus, equals: .email)
                SecureField("password", text: $password, prompt: Text("password"))
                    .focused($focus, equals: .password)
                Button("login", action: login)
            }
            .toolbar {
                ToolbarItem(placement: .keyboard) {
                    Button("next") {
                        if email.isEmpty {
                            focus = .email
                        } else if password.isEmpty {
                            focus = .password
                        } else {
                            focus = nil
                        }
                    }
                }
            }
            .navigationTitle("Sign in")
            .onAppear {
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                    focus = .email
                }
            }
        }
    }

    private func login() {
        // your logic here
    }
}

运行截图

如上例所示,我们使用了 @FocusState 属性包装器与我们的新 FocusableField 枚举一起使用。该枚举定义了屏幕上所有可聚焦视图,应确保 FocusableField 枚举是可散列的。

使用 @FocusState 属性包装器定义了可选变量 focus,以便在用户将焦点从您定义的视图移动时将其值设置为 nil

我们还使用了 focused 修饰符的一个版本,将一个视图绑定到可散列枚举的特定情况。请记住,您可以通过更改 @FocusState 包装的变量的值来以编程方式移动 VoiceOver 或 Switch Control 的焦点。

总结

在这篇文章中,我们深入探讨了 SwiftUI Release 引入的辅助焦点管理功能,使得处理辅助技术(如 VoiceOver 和 Switch Control)的焦点状态变得更加轻松。通过 @FocusState 属性包装器,我们学习了如何灵活地管理焦点状态,以提高用户体验。通过详细的示例代码,我们演示了如何在 SwiftUI 中使用 @FocusState,以及如何通过 focused 视图修饰符将焦点状态绑定到特定的视图。此外,我们介绍了一种高级用法,通过枚举定义可聚焦字段并在它们之间切换,以更好地支持屏幕上多个元素的焦点移动。最后,我们提供了一些优化 SwiftUI 应用的建议,以更好地整合焦点管理,并通过最佳实践和总结使读者更深入地了解了在 SwiftUI Release 中使用 @FocusState 管理焦点的方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1551202.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

北京空港携手数环通iPaaS,打造航空服务行业数字化利器

01 客户背景 北京空港航空地面服务有限公司(以下简称BGS)是首都机场集团控股的中性地面服务企业,提供全业务链航空地面服务解决方案,助力提升机场综合保障实力,致力于成为卓越服务的创造者,专注于成为地面服…

浏览器扩展程序增加 vue_dev_tools 调试工具

1、引言 在做 Vue 项目的开发时,我们经常需要在页面上调试,接下来介绍如何在浏览器扩展程序增加 vue_dev_tools 调试工具。 Download the Vue Devtools extension for a better development experience 翻译:下载Vue Devtools扩展以获得更好…

A - Environment-Friendly Travel Gym - 102501A

题意:给你一些交通方式和站点,不同的交通方式碳排放不一样,问从起点到终点距离不超过B的路径中最少的碳排放是多少。 思路:二维dijkstra,建图什么的倒不是很难,主要就是对二维dij的理解了; 表示…

编辑图片加文字的软件有哪些?4款编辑软件推荐

编辑图片加文字的软件有哪些?在日常生活中,无论是修饰照片、制作海报,还是为图片添加文字,图片编辑软件都能轻松应对。它们操作简单,功能丰富,让我们能够随时随地展现自己的创意和个性。使用它们&#xff0…

Claude 3被玩出自我意识了?AI社区轰动,我们买会员来了次实测

ChatGPT狂飙160天,世界已经不是之前的样子。 新建了人工智能中文站 每天给大家更新可用的国内可用chatGPT资源​ 更多资源欢迎关注 ​ Anthropic 发布了新一代大模型系列 Claude 3,遥遥领先快一年之久的 GPT-4 终于迎来了强劲的对手。 ​ Claude 3 …

经典机器学习模型(九)EM算法的推导

经典机器学习模型(九)EM算法的推导 1 相关数据基础 1.1 数学期望 1.1.1 数学期望的定义 根据定义,我们可以求得掷骰子对应的期望: E ( X ) X 1 ∗ p ( X 1 ) X 2 ∗ p ( X 2 ) . . . X 6 ∗ p ( X 6 ) 1 ∗ 1 6 2 ∗ 1 6 1 ∗ 1 6 3 ∗ 1 6 …

红酒:不同类型红酒的品鉴技巧与文化传承

红酒,作为一种历史悠久的产品,不仅蕴含着深厚的文化底蕴,还展现了多样的风味特点。云仓酒庄雷盛红酒,其不同类型的产品各具特色,为品鉴者带来了丰富的体验。本文将带您一起探索雷盛红酒的品鉴技巧与文化传承。 品鉴红酒…

DFS:从递归去理解深度优先搜索

一、深入理解递归 二、递归vs迭代 三、深入理解搜索、回溯和剪枝 四、汉诺塔问题 . - 力扣&#xff08;LeetCode&#xff09; class Solution { public: //笔试题&#xff0c;不讲武德&#xff0c;CAvoid move(int n,vector<int>& A, vector<int>& B, ve…

Qwen1.5的多框架部署使用指南

在当今的技术领域&#xff0c;大型语言模型的应用日益广泛&#xff0c;而Qwen1.5作为其中的佼佼者&#xff0c;已经得到了多个推理框架的支持。 原生混合精度推理 from transformers import AutoModelForCausalLM, AutoTokenizer import torch# 设置设备为CUDA&#xff0c;如果…

【Vue3】实现二维码、链接 分享功能

界面效果: 描述 要实现的功能分别是 1.复制链接可以将次链接分享给他人&#xff0c;他人依靠链接便可以打开你想要让他看到的数据 2.通过微信扫一扫&#xff0c;便可看到和链接一样的内容在手机端 需要的依赖 二维码:qrcode 复制功能:vue-clipboard3 下载二维码:html2canv…

网络编程之流式套接字

流式套接字&#xff08;SOCK_STREAM&#xff09;是一种网络编程接口&#xff0c;它提供了一种面向连接的、可靠的、无差错和无重复的数据传输服务。这种服务保证了数据按照发送的顺序被接收&#xff0c;使得数据传输具有高度的稳定性和正确性。通常用于那些对数据的顺序和完整性…

ES5和ES6的深拷贝问题

深拷贝我们知道是引用值的一个问题&#xff0c;因为在拷贝的时候&#xff0c;拷贝的是在内存中同一个引用。所以当其中的一个应用值发生改变的时候&#xff0c;其他的同一个引用值也会发生变化。那么针对于这种情况&#xff0c;我们需要进行深度拷贝&#xff0c;这样就可以做到…

Linux下javaweb项目部署

javaweb项目部署测试 测试环境&#xff1a;centos7 下载安装jdk rpm -ivh jdk-8u131-linux-x64.rpm 下载安装MySQL wget https://downloads.mysql.com/archives/get/p/23/file/mysql-community-server-5.7.33-1.el7.x86_64.rpm https://downloads.mysql.com/archives/get/p…

Docker部署一个SpringBoot项目(超级详细)

注意&#xff1a;下面的教程主要是针对 Centos7 的&#xff0c;如果使用的其他发行版会有细微的差别&#xff0c;请查看官方文档。 Docker部署一个SpringBoot项目&#xff08;超级详细&#xff09; 一、安装Docker1.卸载旧版2.配置Docker的yum库3.安装Docker4.设置开机自启动5.…

前端实现浏览器自定义滚动条

前言&#xff1a; 最近有个项目&#xff0c;产品觉得浏览器默认滚动条太丑了。想美化一下&#xff0c;比如自定义颜色&#xff0c;加上圆角&#xff0c;宽高都要更改一下。我查了资料和文档总结了一下 写法&#xff0c;特此记录以便之后使用。 浏览器滚动条api 总结&#xff…

2024年了,为何 Selenium 依然这么火?

今天给大家带来的主题是自动化测试框架Selenium&#xff0c;话不多说&#xff0c;直接开始&#xff01; 1.什么是 Selenium 自动化测试 Jason Huggins 于 2004 年创建了一个 JavaScript 框架&#xff0c;旨在将其从重复的手动测试中解放出来。 最初命名为 JavaScriptTestRunn…

基于SpringCloud+Hadoop+Vue实现的企业级网盘系统实现

编程语言&#xff1a;Java、Mybatis、Spring、SpringBoot、SpringCloud、Node、Vue 开发环境&#xff1a;Windows 10 Mysql 开发工具&#xff1a;WebStorm、IDEA编译器、Git、Maven 应用部署服务器&#xff1a;SpringBoot内置Tomcat插件 Node服务器&#xff1a;Node v10.1…

【吊打面试官系列】Redis篇 -Redis 集群如何选择数据库?

大家好&#xff0c;我是锋哥。今天分享关于 【Redis 集群如何选择数据库&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; Redis 集群如何选择数据库&#xff1f; Redis 集群目前无法做数据库选择&#xff0c;默认在 0 数据库。 Redis 集群不支持使用 SELECT 命令…

RF-TI1352P2—双频多协议高发射功率无线模块

RF-TI1352P2是一款基于TI CC1352P7为核心的双频&#xff08;Sub-1 GHz 和 2.4 GHz&#xff09;多协议高发射功率&#xff08;20 dBm&#xff09;无线模块&#xff1b;支持IPEX接口和邮票孔两种天线形式&#xff1b;模块除了集成负责应用逻辑的高性能 48 MHz ARM Cortex-M4F 主处…

实验02-1 C#和ASP.NET控件:在Web窗体中输出九九乘法表

【实验内容及要求】 1. 在Web窗体中输出九九乘法表 浏览效果如图2-1所示。 图2-1 在Default.aspx.cs中编写C#代码 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls;public par…