SwiftUI 列表(或 Form)子项中的 Picker 引起导航无法跳转的原因及解决

在这里插入图片描述

概述

在 SwiftUI 的界面布局中,列表(List)和 Form 是我们秃头码农们司空见惯的选择。不过大家是否知道:如果将 Picker 之类的视图嵌入到列表或 Form 的子项中会导致导航操作无法被触发。

在这里插入图片描述

从上图可以看到:当在 List 的子项中嵌入 Picker 时,所有互动操作都会聚焦在 Picker 上面,从而使得导航根本无法触发。

这种现象在 SwiftUI 6.0(iOS 18.1)中依然存在。

在本篇博文中,您将学到如下内容:

  • 概述
  • 1. 一个简单的问题
  • 2. “肿么”会这样?
  • 解决之道
  • 总结

想知道如何解决吗?超乎寻常的简单!
那还等什么呢?Let‘s go!!!😉


1. 一个简单的问题

首先是一段平淡无奇的的源代码:

enum JailConfig: Int, Identifiable, CaseIterable {case veryEasy = 1case easycase normalcase hardcase veryHardvar id: Int {rawValue}var desc: String {switch self {case .veryEasy:"非常容易"case .easy:"容易"case .normal:"一般"case .hard:"有点难"case .veryHard:"很难"}}
}@available(iOS 17, *)
struct V3_GameView: View {@State var jailConfig = JailConfig.normalvar body: some View {NavigationStack {List {NavigationLink("每日打卡") {ClockInView()}NavigationLink("抓住机会") {PressBlessingView(config: .normal)}NavigationLink {FingersJail(config: jailConfig)} label: {VStack(alignment: .leading) {Text("指尖监狱")LabeledContent {Picker("", selection: $jailConfig) {ForEach(JailConfig.allCases) { config inText(config.desc).tag(config)}}} label: {Text("难度")}}}}.listStyle(.plain).navigationTitle("游戏").toolbar {Text("大熊猫侯佩 @ \(Text("CSDN").foregroundStyle(.red))").foregroundStyle(.gray).font(.headline.bold())}}}
}

从代码中可以看到:我们在第 3 个列表项中嵌入了一个 Picker 视图,并将其包裹在 NavigationLink 的 label 中。这样做的意图是让用户在导航至子视图之前可以先选择一些配置信息(比如游戏难度)。

但这样简单的组合却带来了意想不到的“不良”结果:我们现在只能选择 Picker 的内容而无法进行导航了。

在这里插入图片描述

2. “肿么”会这样?

为了理解为何会如此,让我们先将布局稍微做一下调整。这次我们将 Picker 放在 NavigationLink 的外部:

VStack {NavigationLink {FingersJail(config: jailConfig)} label: {Text("指尖监狱")}LabeledContent {Picker("", selection: $jailConfig) {ForEach(JailConfig.allCases) { config inText(config.desc).tag(config)}}} label: {Text("难度")}
}

再次运行代码可以看到:结果和之前一毛一样。为了确保这不是 Xcode 预览中的一个 Bug,我特地在模拟器中也运行了一下,毫无二致。


诸多关于 Xcode “蛋疼” 预览(Preview)机制的进一步介绍,请小伙伴们移步如下链接观赏精彩的内容:

  • SwiftUI 界面动画调试一例:做码农最重要的是什么?相信自己!
  • Xcode13模拟器和预览(Preview)导致Mac处理器占用率急剧飙升的解决方法
  • SwiftUI Xcode项目新增单元测试(Unit Test)后预览(Preview)崩溃的解决
  • Xcode预览(Preview)显示List视图内容的一个Bug及解决
  • Xcode如何在预览(Preview)调试中避免与SwiftUI正常运行时环境不一致导致的崩溃
  • Xcode编写SwiftUI代码时一个编译通过但导致预览(Preview)崩溃的小陷阱
  • Xcode 15 预览 SwiftUI 视图中 @FetchRequest 查询结果不能正确刷新的解决

看来目前 SwiftUI 布局中,在列表(或 Form)子项里 VStack(或其它容器)内部如果有类似 Picker 之类的可交互视图,其它视图的交互性将会受到抑制(除非其它视图是 borderless 样式的按钮)。

知道了原因解决起来就十分简单了:只需把它们分开就行啦!

解决之道

如下代码所示,我们可以将 Picker 和原先列表子项中显示的内容完全“分离”:

NavigationLink {FingersJail(config: jailConfig)
} label: {Text("指尖监狱")
}            LabeledContent {Picker("", selection: $jailConfig) {ForEach(JailConfig.allCases) { config inText(config.desc).tag(config)}}} label: {Text("难度")
}
.padding(.top, -10)

不过,这样从界面上看会略显“割裂感”:

在这里插入图片描述

于是乎,我们可以用视图的 listRowSeparator 修改器隐藏中间的分隔线:

NavigationLink {FingersJail(config: jailConfig)
} label: {Text("指尖监狱")
}
.listRowSeparator(.hidden)

现在效果好极了:

在这里插入图片描述

或者我们可以将 Picker 和 NavigationLink 的内容统统放到一个 Section 中去,这样代码组织性会更好一些:

Section {NavigationLink {V3_FingersJail(config: jailConfig)} label: {Text("指尖监狱")}.listRowSeparator(.hidden)LabeledContent {Picker("", selection: $jailConfig) {ForEach(V3_JailConfig.allCases) { config inText(config.desc).tag(config)}}} label: {Text("难度")}.padding(.top, -10)
}

至此,我们成功的解决了博文开头那个问题!希望可以一解小伙伴们的燃眉之急,棒棒哒!💯


想要系统学习 Swift 的小伙伴们,欢迎来我的《Swift 语言开发精讲》专栏逛一逛哦:

在这里插入图片描述

  • 《Swift 语言开发精讲》

总结

在本篇博文中,我们讨论了 SwiftUI 列表(或 Form)子项中的 Picker 导致无法导航跳转的原因,并随后给出完美的解决方案。

感谢观赏,再会吧!😎

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

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

相关文章

Ubuntu Linux 文件、目录权限问题

本文为Ubuntu Linux操作系统- 第五弹 此文是在上期文件目录的内容操作基础上接着讲权限问题 上期回顾:Ubuntu Linux 目录和文件的内容操作 文件访问者身份与文件访问权限 Linux文件结构 所有者(属主)所属组(属组)其他…

SIP系列五:HTTP(SIP)鉴权

我的音视频/流媒体开源项目(github) SIP系列目录 目录 一、基本认证(basic) 二、摘要认证(digest) 1、摘要认证(digest) RFC 2069​ 2、摘要认证(digest) RFC 2617​ 2.1、未定义qop字段或值为"(空) 2.2、qop值为"auth" 2.3、qop值为"auth-int&quo…

解决kali xterm终端中英文字符过宽、中文乱码问题

编辑并保存以下内容 root用户 nano ~/.Xresources XTerm*faceName: DejaVu Sans Mono XTerm*faceName2: Noto Sans CJK SC XTerm*background: #000000没有终端背景变白的问题可以不加 XTerm*background: #000000 重新加载配置生效 xrdb ~/.Xresources 自动加载 .Xresource…

2020年国赛高教杯数学建模E题校园供水系统智能管理解题全过程文档及程序

2020年国赛高教杯数学建模 E题 校园供水系统智能管理 原题再现 校园供水系统是校园公用设施的重要组成部分,学校为了保障校园供水系统的正常运行需要投入大量的人力、物力和财力。随着科学技术的发展,校园内已经普遍使用了智能水表,从而可以…

最新版Chrome谷歌加载ActiveX控件之金格iWebOffice2015控件

allWebPlugin简介 allWebPlugin中间件是一款为用户提供安全、可靠、便捷的浏览器插件服务的中间件产品,致力于将浏览器插件重新应用到所有浏览器。它将现有ActiveX控件直接嵌入浏览器,实现插件加载、界面显示、接口调用、事件回调等。支持Chrome、Firefo…

【Flink-scala】DataStream编程模型之水位线

DataStream API编程模型 1.【Flink-Scala】DataStream编程模型之 数据源、数据转换、数据输出 2.【Flink-scala】DataStream编程模型之 窗口的划分-时间概念-窗口计算程序 3.【Flink-scala】DataStream编程模型之 窗口计算-触发器-驱逐器 文章目录 DataStream API编程模型前言…

VoCo-LLaMA: Towards Vision Compression with Large Language Models

视觉语言模型在各种多模态任务上取得了显著的成功,但经常受到有限上下文窗口和处理高分辨率图像输入和视频的高计算成本的瓶颈。视觉压缩可以通过减少视觉令牌数量避免该问题。先前方法使用额外模块压缩视觉令牌并强制LLM理解压缩的令牌。然而,LLM对视觉…

iOS平台接入Facebook登录

1、FB开发者后台注册账户 2、完善App信息 3、git clone库文件代码接入 4、印尼手机卡开热点调试 备注: 可能遇到的问题: 1、Cocos2dx新建的项目要更改xcode的git设置,不然卡在clone,无法在线获取FBSDK 2、动态库链接 需要在…

unity打包web,发送post请求,获取地址栏参数,解决TypeError:s.replaceAll is not a function

发送post请求 public string url "http://XXXXXXXXX";// 请求数据public string postData "{\"user_id\": 1}";// Start is called before the first frame updatevoid Start(){// Post();StartCoroutine(PostRequestCoroutine(url, postData…

VTK编程指南<三>:基于VTK入门程序解析来理解VTK基础知识

1、VTK入门程序 下面是一个完整的Vtk入门程序&#xff0c;我们基于这个程序来对VTK的基本知识进行一个初步了解。 #include <iostream>#include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL2);// VTK was built with vtkRenderingOpenGL2 VTK_MODULE_INI…

IMP-00038: 无法转换为环境字符集句柄

问题 在导入oracle数据库文件的时候报这个报错&#xff0c;原因是你使用的是imp命令导入的使用expdp命令导出的dmp文件导致的。 原因 关于imp命令和expdp命令 exp和imp是客户端的工具程序命令&#xff0c;既可以在客户端使用&#xff0c;也可以在服务端使用。 expdp和impd…

大语言模型应用Text2SQL本地部署实践初探

自从两年前OpenAI公司发布ChatGPT后&#xff0c;大模型(Large Language Model&#xff0c;简称LLM)相关技术在国内外可谓百家争鸣&#xff0c;遍地开花&#xff0c;在传统数据挖掘、机器学习和深度学习的基础上&#xff0c;正式宣告进入快速发展的人工智能(Artificial Intellig…

shell脚本实战案例

文章目录 实战第一坑功能说明脚本实现 实战第一坑 实战第一坑&#xff1a;在Windows系统写了一个脚本&#xff0c;比如上面&#xff0c;随后上传到服务&#xff0c;执行会报错 原因&#xff1a; 解决方案&#xff1a;在linux系统touch文件&#xff0c;并通过vim添加内容&…

Power BI - 批量导入数据

1.简单介绍 假定已经使用Power Automate Desktop(微软的RPA产品&#xff0c;是Power Platform平台的其中一个产品)从福布斯中文网获取了各地区的2024年的财富数据如下&#xff0c; 现在想批量导入数据到Power BI中&#xff0c;分析一下各地区的产业以及财富情况 2.具体说明 …

医疗系统国产数据库高质量发展路径探析

信息工程人员操作数据库 一、国外数据库在医疗系统中的困境 &#xff08;一&#xff09;数据分散与难以整合 在美国&#xff0c;分散式医疗服务成为癌症研究数据库优化的巨大障碍。患者先在社区接受肿瘤科医生常规检查&#xff0c;再到学术医疗中心进行尖端治疗&#xff0c;然…

Maven 打包出现问题解决方案

我执行 mvn install 报如下错误 可是我在 web 模块中能正确引用到 common 的类&#xff0c;于是我把 web 引用到的 common 中的类先移动到 web 模块中&#xff0c;然后把 common 模块的类都删掉&#xff0c;然后再次执行 mvn install,结果报错如下&#xff1a; [ERROR] Faile…

微信小程序里的小游戏研发需要什么技术栈

研发小程序里的小游戏通常需要以下技术栈&#xff1a; 前端技术 HTML5 / CSS3&#xff1a;用于构建游戏的界面布局和样式。JavaScript&#xff1a;作为核心编程语言&#xff0c;实现游戏的逻辑和交互。小程序开发框架&#xff1a;如微信小程序的开发框架&#xff0c;了解其 API…

NIO(New IO)和BIO(Blocking IO)的区别

Java中的NIO&#xff08;New IO&#xff09;和BIO&#xff08;Blocking IO&#xff09;的区别及NIO的核心组件 Java中的NIO&#xff08;New IO&#xff09;和BIO&#xff08;Blocking IO&#xff09;是两种不同的网络通信模型&#xff0c;各自具有独特的特性和适用场景。下面将…

RabbitMQ延迟消息的实现

RabbitMQ延迟队列的实现 延迟消息是什么延迟消息的实现死信交换机代码实现 延迟消息插件 延迟消息是什么 延迟消息是将消息发送到MQ中&#xff0c;消费者不会立即收到消息&#xff0c;而是过一段时间之后才会收到消息&#xff0c;进行处理。在一些业务中&#xff0c;可以用到延…

HTML5 拖拽 API 深度解析

一、HTML5 拖拽 API 深度解析 1.1 背景与发展 HTML5 的拖拽 API 是为了解决传统拖拽操作复杂而设计的。传统方法依赖鼠标事件和复杂的逻辑计算&#xff0c;而 HTML5 提供了标准化的拖拽事件和数据传递机制&#xff0c;使得开发者能够快速实现从一个元素拖拽到另一个元素的交互…