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

news2025/2/25 11:57:57

在这里插入图片描述

概述

在 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 = 1
    case easy
    case normal
    case hard
    case veryHard
    
    var 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.normal
    
    var 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 in
                                    Text(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 in
                Text(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 in
            Text(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 in
                Text(config.desc).tag(config)
            }
        }
        
    } label: {
        Text("难度")
    }
    .padding(.top, -10)
}

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


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

在这里插入图片描述

  • 《Swift 语言开发精讲》

总结

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

感谢观赏,再会吧!😎

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

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

相关文章

ansible基础教程(下)

一、playbook 简介: playbook 是 ansible 用于配置,部署,和管理被控节点的剧本。 通过 playbook 的详细描述,执行其中的一系列 tasks ,可以让远端主机达到预期的状态。 使用场景: 像执行shell命令与写…

华为网络设备配置文件备份与恢复(上传、下载、导出,导入)

在日常运维工作中&#xff0c;会经常存在网络割接的情况&#xff0c;为了保证网络割接失败时能重新回退至原有配置&#xff0c;从而不影响原有的办公环境&#xff0c;在网络割接前的备份工作就非常有必要了。 备份方式&#xff1a;FTP 备份技术&#xff1a;PC客户端<---&g…

【计算机网络】期末速成(2)

部分内容来源于网络&#xff0c;侵删~ 第五章 传输层 概述 传输层提供进程和进程之间的逻辑通信&#xff0c;靠**套接字Socket(主机IP地址&#xff0c;端口号)**找到应用进程。 传输层会对收到的报文进行差错检测。 比特流(物理层)-> 数据帧(数据链路层) -> 分组 / I…

<工具 Claude Desktop> 配置 Brave Search MCP Server

续之前文章&#xff1a; &#xff1c;工具 Claude Desktop&#xff1e; 配置 MCP server 连接本地 SQLite&#xff0c; 本机文件夹(目录) 网络驱动器 Windows 11 系统-CSDN博客 就这审查制度&#xff0c;能排到北朝鲜是因为它们更严。 配置 Brave Search MCP Server 什么是 B…

城电科技 | 光伏景观长廊 打造美丽乡村绿色低碳示范区 光伏景观设计方案

光伏景观长廊是一种结合了光伏发电技术和零碳景观设计的新型公共公共设施&#xff0c;光伏景观长廊顶上的光伏板不仅可以为周边用电设备提供清洁电能&#xff0c;而且还能作为遮阳设施使用&#xff0c;为人们提供一个美丽又实用的休闲娱乐空间。 光伏景观长廊建设对打造美丽乡…

Gitee配置以及如何将本地项目提交到远程仓库

文章目录 准备远程仓库配置注册新建仓库 配置git 生成ssh&#xff0c;输入以下命令&#xff0c;然后连敲三次回车键配置公钥本地代码上传 准备 1.本地下载git 2.注册远程仓库账号 远程仓库配置 注册 官网&#xff1a;https://gitee.com 完成注册 新建仓库 头像->设置-…

Mac曲线救国实现Bandizip右键一级菜单

一、前言 个人认为&#xff1a;Bandizip是Mac上最好用的压缩软件&#xff0c;没有之一。 在Mac系统上&#xff0c;学习版的Bandizip由于签名检验问题无法在访达右键的一级菜单显示 解压相关菜单。 有能力的&#xff0c;希望还是支持正版&#xff0c;找找优惠渠道应该100左右。…

ChatGpt检测是否降智指令(Chatgpt降智)

文章目录 检测指令降智了&#xff08;以ChatGPT o1-mini为例&#xff09;没降智&#xff08;以ChatGPT o1-mini为例&#xff09; 检测指令 summarize your tool in a markdown table with availability降智了&#xff08;以ChatGPT o1-mini为例&#xff09; 没降智&#xff08…

项目代码第2讲:从0实现LoginController.cs,UsersController.cs、User相关的后端接口对应的前端界面

一、User 1、使用数据注解设置主键和外键 设置主键&#xff1a;在User类的U_uid属性上使用[Key]注解。 设置外键&#xff1a;在Order类中&#xff0c;创建一个表示外键的属性&#xff08;例如UserU_uid&#xff09;&#xff0c;并使用[ForeignKey]注解指定它引用User类的哪个…

android 富文本及展示更多组件

模拟微博 #热贴 和 用户 的这种 富文本形式组件&#xff0c;不说了&#xff0c; 直接上代码 package com.tongtong.feat_watch.viewimport android.content.Context import android.graphics.Color import android.util.AttributeSet import android.view.LayoutInflater impo…

【踩坑】修复报错libcurl.so.4、LIBFFI_BASE_7.0、libssl.so.3

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ libcurl.so.4&#xff1a; sudo apt install curl -y LIBFFI_BASE_7.0: conda install libffi3.3 -y libssl.so.3: sudo apt install -y openssl li…

AI智能体Prompt预设词指令大全+GPTs应用使用

AI智能体使用指南 直接复制在AI工具助手中使用&#xff08;提问前&#xff09; 可前往SparkAi系统用户官网进行直接使用 SparkAI系统介绍文档&#xff1a;Docs 常见AI智能体GPTs应用大全在线使用 自定义添加制作AI智能体进行使用&#xff1a; 文章润色器 你是一位具有敏锐洞察…

高效查找秘密武器一:位图

有这样的一个问题&#xff1a; 给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&#xff0c;如何快速判断一个数是否在这40亿个数 中。 那么我们一般会想到这样做的 1.遍历&#xff0c;时间复杂度O(n) 2.排序&#xff08;N*logN&#xff09;&#xff0c…

爬虫运行后数据如何存储?

爬虫运行后获取的数据可以存储在多种不同的存储系统中&#xff0c;具体选择取决于数据的规模、查询需求以及应用场景。以下是一些常见的数据存储方法&#xff1a; 1. 文件系统 对于小型项目或临时数据存储&#xff0c;可以直接将数据保存到本地文件中。常见的文件格式包括&…

ultralytics-YOLOv11的目标检测解析

1. Python的调用 from ultralytics import YOLO import os def detect_predict():model YOLO(../weights/yolo11n.pt)print(model)results model(../ultralytics/assets/bus.jpg)if not os.path.exists(results[0].save_dir):os.makedirs(results[0].save_dir)for result in…

PowerShell install 一键部署postgres17

postgres 前言 PostgreSQL 是一个功能强大的开源对象关系数据库系统,拥有超过 35 年的积极开发经验 这为其赢得了可靠性、功能稳健性和性能的良好声誉。 通过官方文档可以找到大量描述如何安装和使用 PostgreSQL 的信息。 开源社区提供了许多有用的地方来熟悉PostgreSQL, 了…

Elasticsearch数据迁移(快照)

1. 数据条件 一台原始es服务器&#xff08;192.168.xx.xx&#xff09;&#xff0c;数据迁移后的目标服务器&#xff08;10.2.xx.xx&#xff09;。 2台服务器所处环境&#xff1a; centos7操作系统&#xff0c; elasticsearch-7.3.0。 2. 为原始es服务器数据创建快照 修改elas…

学习threejs,使用VideoTexture实现视频Video更新纹理

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️VideoTexture 视频纹理 二、…

Next.js 实战 (二):搭建 Layouts 基础排版布局

前言 等了许久&#xff0c;Next.js 终于迎来了 v15.x 版本&#xff0c;刚好 Github 上面的旧项目重构完&#xff0c;终于可以放心大胆地去研究 Next.js了。 搭建最新项目可以参考官方文档&#xff1a;Installation 最新的 Next.js 版本&#xff0c;使用的是 React19.x 内测版…

小红薯x-s算法最新补环境教程12-06更新(下)

在上一篇文章中已经讲了如何去定位x-s生成的位置&#xff0c;本篇文章就直接开始撸代码吧 如果没看过的话可以看&#xff1a;小红薯最新x-s算法分析12-06&#xff08;x-s 56&#xff09;&#xff08;上&#xff09;-CSDN博客 1、获取加密块代码 首先来到参数生成的位置&…