首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

当键盘出现在SwiftUI中时,将TextEditor (在列表中)上移

基础概念

在SwiftUI中,TextEditor 是一个视图,允许用户输入和编辑文本。当键盘弹出时,可能会遮挡住 TextEditor 视图,影响用户体验。为了确保 TextEditor 在键盘弹出时仍然可见,可以使用一些技巧将其上移。

相关优势

  1. 提升用户体验:确保用户在输入时始终能看到他们正在编辑的内容。
  2. 避免遮挡:防止键盘遮挡重要的输入区域。

类型

  1. 使用 GeometryReaderPreferenceKey:通过监听键盘高度变化来调整 TextEditor 的位置。
  2. 使用 ScrollViewVStack:通过滚动视图来确保 TextEditor 始终可见。

应用场景

适用于需要用户输入文本的应用,如聊天应用、笔记应用、表单填写等。

问题及解决方法

问题:当键盘弹出时,TextEditor 被遮挡。

原因

键盘弹出时,视图布局没有相应调整,导致 TextEditor 被遮挡。

解决方法

使用 GeometryReaderPreferenceKey 来监听键盘高度变化,并调整 TextEditor 的位置。

代码语言:txt
复制
import SwiftUI

struct ContentView: View {
    @State private var keyboardHeight: CGFloat = 0

    var body: some View {
        GeometryReader { geometry in
            VStack {
                List {
                    TextEditor(text: $text)
                        .frame(height: 100)
                        .background(Color.gray.opacity(0.2))
                        .cornerRadius(10)
                        .padding(.all, 10)
                        .offset(y: -keyboardHeight)
                }
            }
            .background(GeometryReader {
                Color.clear.preference(key: KeyboardHeightPreferenceKey.self, value: -$0.frame(in: .named("screen")).size.height)
            })
            .onPreferenceChange(KeyboardHeightPreferenceKey.self) { value in
                keyboardHeight = value
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .edgesIgnoringSafeArea(.all)
        }
    }
}

struct KeyboardHeightPreferenceKey: PreferenceKey {
    static var defaultValue: CGFloat = 0

    static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
        value += nextValue()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

参考链接

SwiftUI TextEditor GeometryReader PreferenceKey

通过上述方法,可以确保当键盘弹出时,TextEditor 视图能够自动上移,避免被键盘遮挡。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

深入了解 SwiftUI 5 中 ScrollView 的新功能

在 SwiftUI 5.0 中,苹果大幅强化了 ScrollView 功能。新增了大量新颖、完善的 API。本文将对这些新功能进行介绍,希望能够让它们更多、更早的帮助到有需要的开发者。...之前在 List 或 TextEditor 中实现类似操作是十分困难的。 默认的 ContentMarginPlacement(.automatic)将导致指示器与内容之间的长度不一致。...仅适用于 ScrollView 当 ForEach 中的数据源遵循 Identifiable 协议时,无需显式使用 id 修饰符设置标识 与 scrollTargetLayout 配合使用,可以获取当前的滚动位置...(视图标识) 不支持锚点设定,固定锚点为子视图的 center 正如 优化在 SwiftUI List 中显示大数据集的响应效率[6] 一文所提到的,当数据集很大时,也会出现性能问题。...就我个人而言,在 SwiftUI 5 中,ScrollView 的原生方案已经能够满足大多数需求,因此我们将看到更多人采用 ScrollView + LazyStack 的组合方式。

92120

Ask Apple 2022 与 SwiftUI 有关的问答(上)

假设我们想创建一个类似于 iMessage 的视图,在那里你可以看到一个信息列表(与本例无关),在视图的底部有一个文本框。当用户点击文本字段时,键盘会在其工具栏中出现一个文本字段。...最近,我注意到 SwiftUI 视图的 onAppear 在意想不到的时间启动,比如当 UITabBarController 被创建时,而不是当视图本身出现时。...2、当视图出现在 UITabBarController 中时,推荐的执行代码的方法是什么?...A:如果你在 iOS 上使用 UITextField 遇到性能问题,你可以尝试避免每个视图都是 UITextField ,默认渲染为 Text ,当文本被点击时动态切换为 UITextField 。...WindowGroup 和 OpenWindowActionQ:在 macOS 上是否可以在创建新窗口时附加参数?我在同一个子上下文中创建一个新的托管对象,并希望将这个对象发送到一个新的窗口。

12.3K20
  • 掌握 SwiftUI 的 Safe Area

    在 UIKit 中,开发者需要利用 safeAreaInsets 或 safeAreaLayoutGuide ,才能确保将视图放置在界面中的可见部分。 SwiftUI 对上述过程进行了彻底的简化。...当视图尚未在屏幕上可见时,该视图的 safeAreaInset 也为 0 。...在 SwiftUI 中,开发者通常只有在需要获取 StatusBar + NavBar 的高度或 HomeIndeicator + TabBar 的高度时才会使用到 safeAreaInsets 。...从 iOS 14 开始,SwiftUI 计算视图的安全区域时,将软键盘在屏幕上的覆盖区域(iPadOS 下,将软键盘缩小后键盘的覆盖区域将被忽略)也一并进行考虑。...safeAreaInsetList2 遗憾的是,在 iOS 15 之前,SwiftUI 并没有提供调整视图安全区的手段,如果我们想通过 SwiftUI 的手段创建一个自定义 Tabbar 时,列表中最后的内容将被

    7.7K31

    SwiftUI 在 WWDC 24 之后的新变化

    我们还在 TabSection 实例上使用 tabViewStyle 视图修饰符,将特定的标签部分分组并移动到侧边栏。...英雄动画SwiftUI 引入了 matchedTransitionSource 和 navigationTransition,我们可以在任何 NavigationLink 实例中配对使用。...extension EnvironmentValues { @Entry var itemsPerPage: Int = 10}预览新的 Previewable 宏允许我们在预览中引入状态,而无需将其包装到额外的包装视图中...框架的下一版本包括许多新 API,如窗口推送、TextField 和 TextEditor 视图中的文本选择观察、搜索焦点监控、自定义文本渲染、新的 MeshGradient 类型等等,我无法在一篇文章中涵盖所有内容...总结在 WWDC 24 上,SwiftUI 再次通过引入更多新功能来提升其成熟度,以赶上 UIKit。

    17210

    【visionOS】从零开始创建第一个visionOS程序

    在任何SwiftUI应用中,你都可以使用场景将内容放到屏幕上。场景包含要在屏幕上显示的视图和控件。场景还定义了这些视图和控件出现在屏幕上时的外观。...图为虚拟3D键盘。这个人的右手敲击着J键。 直接输入。当一个人的手指与屏幕上的项目占据相同的空间时,系统就会报告一个交互。额外的手指和手部动作定义手势类型。...这张照片显示了一个人的手在桌子上的物理键盘上打字。一个虚拟的建议条显示在物理键盘的上方。 键盘输入。人们可以使用连接的鼠标、触控板或键盘与项目交互、触发菜单命令和执行手势。...当指定的手势发生在实体上时,SwiftUI执行提供的闭包。 下面的示例将一个点击手势识别器添加到上一个示例中的球体视图中。...如果不取消可见空间,那么当您尝试打开另一个空间时,系统将发出运行时警告。

    1.1K40

    SwiftUI TextField 进阶 —— 事件、焦点、键盘

    事件 onEditingChanged 当 TextField 获得焦点时(进入可编辑状态),onEditingChanged将调用给定的方法并传递true值;当 TextField 失去焦点时,再次调用方法并传递...当接受到的SubmitTriggers值不包含在 onSubmit 设置的SubmitTriggers时,传递将终止。...在 SwiftUI 3.0 之前,我们必须在主视图上另外绘制或者使用非 SwiftUI 的方式来解决问题,在 SwiftUI 3.0 中,由于添加了原生设置键盘辅助视图(下文具体介绍)的功能,解决上述问题将不再困难...另外,有时候为了提高交互体验,我们可以希望用户在录入结束后,无需点击return按键,通过点击屏幕其他区域或者以滚动列表的方式来取消键盘。同样也需要使用编程的方式让键盘消失。...将键盘辅助视图集成到 toolbar 的逻辑中也有些令人令人费解。 通过 UIKit 创建 当前阶段,通过 UIKit 来创建键盘辅助视图仍是 SwiftUI 下的最优方案。

    13.4K10

    SwiftUI 布局 —— 尺寸( 上 )

    这并非意味着尺寸在 SwiftUI 中不重要,事实恰恰相反,正是由于在 SwiftUI 中尺寸是一个十分复杂的概念,苹果将绝大多数有关尺寸的配置和表述都隐藏到了引擎盖之下,刻意对其进行了包装与淡化。...淡化尺寸概念的初衷或许是出于以下两点: 引导开发者转型到声明式编程逻辑,转变使用精准尺寸的习惯 掩盖 SwiftUI 中复杂的尺寸概念,减少初学者的困扰 但无论如何淡化或掩盖,当涉及更加高级、复杂、精准的布局时...在 Layout 协议中,对应的是 sizeThatFits 方法。经过该阶段的协商,SwiftUI 将确定视图所在屏幕上的位置和尺寸。...在 SwiftUI 中,只有符合 View 协议的 component 才能被 ViewBuilder[3] 所处理。因此任何一种布局容器,最终都会被包装并以 View 的形式出现在代码中。...当父视图想获得子视图在最大模式下的需求尺寸时,会为其提供该模式的建议尺寸 明确尺寸模式 非 0 或 infinity 的数值。

    4.8K20

    肘子的 Swift 周报 #050| 你的 App 被新系统打败了吗?

    近期推荐 理解终端输出中的颜色与样式 (Understanding Colors and Styles in Terminal Output)[5] Natan Rolnik[6] 在构建终端工具时,能够灵活调整输出文本的样式不仅能增强工具的视觉体验...在本文中,Pol Piella Abadia 介绍了如何借助两种不同的实现方法将绑定值传递给 SwiftUI 视图。...Quentin Zervaas 分享了他在迁移至 Swift 6 过程中的策略和技巧,以帮助开发者将代码从使用完成处理器(completion handler)转换为 Swift 的 async/await...的 attributes 合并机制发生了显著变化,导致一些开发者在处理带有 Range的属性时遇到崩溃问题。...Harry Li 通过深入分析指出,iOS 18 在合并 Range Attribute 时,系统会参考属性值的 Equatable 实现,而在 iOS 17 及以前版本中并没有这一行为。

    10610

    AnyView 对 SwiftUI 性能的影响

    在这个测试中,我们将通过整个消息列表三次滚动。没有 AnyView下面是没有泛型实现的动画卡顿记录。...以下是动画卡顿仪器配置文件中的结果。你可以在此示例中看到一些更多的橙色。有更多的动画卡顿超过了可接受的延迟时间 33 毫秒。这导致在执行测试时在仪器和视觉上都出现一些可见的卡顿。...当需要更新视图时,仅对其进行更改(例如,向视图添加另一个反应)。有 AnyView当我们在这种情况下使用 AnyView 时,事情就变得有趣了 - 在短时间内对屏幕上的视图进行频繁更新。...仅浏览数据时,如果你将视图包装在 AnyView 中,则会比不包装时慢大约 10%。如果你在浏览数据时更改数据,则此差异将增加到约 17%,而且这些故障在这里更加明显。...这意味着,当列表发生更改时,我们实际上重新创建了整个列表。这也解释了为什么 AnyView 实现随着时间的推移变慢 - 每次重绘时都需要从头开始创建更多内容。

    15400

    SwiftUI WWDC作为开发者的我最激动的部分

    但是在pad或者tv上还是要写不同的代码去做在不同的平台运行。 Flutter受关注的最大原因应该是一份代码多平台运行吧,如果Apple将划分的四大平台需要四份UI代码,想想是一件多么恐怖的事情。...SwiftUI 所有Apple平台都是原生的 ---- SwiftUI在创造世界上最创新、最直观的用户界面方面积累了数十年的经验。...用户喜欢苹果生态系统的所有方面,比如控件和特定于平台的体验,都可以在代码中很好地表现出来。SwiftUI是真正的本地应用程序, ?...SwiftUI语法是什么样的呢 ---- SwiftUI使用声明性语法,因此您可以简单地声明用户界面应该做什么。例如,您可以编写一个包含文本字段的项列表,然后描述每个字段的对齐方式、字体和颜色。...当您在设计画布中工作时,您编辑的所有内容都与相邻编辑器中的代码完全同步。当您键入时,代码作为预览立即可见,并且您对该预览所做的任何更改都会立即出现在您的代码中。

    2.3K30

    LeetCode周赛296,难度较低的新人练习场

    你可以将 nums 划分成一个或多个 子序列 ,使 nums 中的每个元素都 恰好 出现在一个子序列中。...表面上看子序列需要保证元素顺序和原来一样,但实际上在本题当中,子序列当中的相对顺序并不重要,我们不关心子序列当中的元素是如何排列的,我们只关心要用到多少子序列。...题目保证在第 i 个操作中: operations[i][0] 在 nums 中存在。 operations[i][1] 在 nums 中不存在。 请你返回执行完所有操作后的数组。...删除:在光标所在处删除文本(模拟键盘的删除键)。 移动:将光标往左或者往右移动。 当删除文本时,只有光标左边的字符会被删除。...请你实现 TextEditor 类: TextEditor() 用空文本初始化对象。 void addText(string text) 将 text 添加到光标所在位置。

    30320

    SwiftUI 中掌握 ScrollView 的使用:滚动可见性

    前言我们的滚动 API 中又有一个重要的新增功能:滚动可见性。现在,你可以获取可见标识符列表,或者快速检查并监控 ScrollView 内视图的可见性状态。...在操作闭包内,我们获取可见标识符列表,并可以对可见项执行所需的操作。有时,视图需要在其可见性状态在 ScrollView 中发生变化时进行响应。...同样,当视图从可见状态转换为不可见状态,即显示的视口部分少于 10% 时,也会运行该闭包。...task:在 task 修饰符中初始化播放器。...此外,在页面底部有一个视频播放器,当视频播放器出现在视口内时,它会自动播放,当其离开视口时,会自动暂停。总结今天,我们学习了如何跟踪 ScrollView 内特定视图的可见性,并监控可见标识符列表。

    22521

    LeetCode 6093. 设计一个文本编辑器(双栈)

    题目 请你设计一个带光标的文本编辑器,它可以实现以下功能: 添加:在光标所在处添加文本。 删除:在光标所在处删除文本(模拟键盘的删除键)。 移动:将光标往左或者往右移动。...当删除文本时,只有光标左边的字符会被删除。 光标会留在文本内,也就是说任意时候 0 TextEditor 类: TextEditor() 用空文本初始化对象。 void addText(string text) 将 text 添加到光标所在位置。...添加完后光标在 text 的右边。 int deleteText(int k) 删除光标左边 k 个字符。返回实际删除的字符数目。...string cursorLeft(int k) 将光标向左移动 k 次。返回移动后光标左边 min(10, len) 个字符,其中 len 是光标左边的字符数目。

    40030

    在 Text 中实现基于关键字的搜索和定位

    本节的内容仅代表我在考虑处理上述问题时的想法和思路。其中不少功能已经超出了原本的需求,增加这些功能一方面有利于更多地融汇以前博客中的知识点,另一方面也提高了解题的乐趣。...ForEach ( 上面的代码使用了隐式 ForEach 形式 )中的 View 添加显式标识符后( 使用 id 修饰器),在视图刷新时,List 将会为 ForEach 中的所有视图创建实例( 并非渲染...List 中,每个视图进入显示窗口时都会调用它的 onAppear,每个视图退出显示窗口时都会调用它的 onDisapper。..._25_53在搜索条出现时,让 TextField 获得焦点通过 @FocusState ,让 TextField 在搜索条出现时,自动获得焦点,从而自动开启键盘。...每周也会对当周博客上的新文章以及在 Twitter 上发布的 Tips 进行汇总,并通过邮件列表的形式发送给订阅者。订阅 邮件列表[14],可以及时获得每周的 Tips 汇总。

    4.2K30

    Ask Apple 2022 与 SwiftUI 有关的问答(下)

    连锁动画Q:在 SwiftUI 中,如何实现连锁动画?例如,我想先给一个视图做动画,当动画完成后立即启动另一个动画。A:不幸的是,目前不可能实现连锁动画。...A:解决办法:保留 TextField ,但当它不能被编辑时,有条件地设置 disabled(true),当它可以编辑时使用 disabled(false) 。...Q&A ( 集锦 - 简体中文 )下文中的问题来自开发者与苹果工程师在【 集锦 - 简体中文 】频道进行的中文讨论( 没有出现在英文 SwiftUI 频道中 )。我直接对其进行了复制粘贴。...这是一个在多个版本中都出现过的奇怪问题。在 SwiftUI 早期版本中,当在 iOS 中使用系统中文输入法时,很容易触发这种情况。但后期逐步得到了修复。...每周也会对当周博客上的新文章以及在 Twitter 上发布的 Tips 进行汇总,并通过邮件列表的形式发送给订阅者。订阅下方的 邮件列表[23],可以及时获得每周的 Tips 汇总。

    14.8K30

    「Spring认证」Spring 依赖注入

    SpellChecker 将独立实现,并在 TextEditor 实例化时提供给 TextEditor。整个过程由 Spring 框架控制。...此实例将用于调用 setter 方法来初始化 TextEditor 的属性。 因此,DI 存在于两个主要变体中,以下两个子章节将通过示例涵盖它们 - 不。...依赖注入类型和描述 1 基于构造函数的依赖注入当容器调用带有多个参数的类构造函数时,基于构造函数的 DI 就完成了,每个参数代表对另一个类的依赖。...2 基于 Setter 的依赖注入基于 Setter 的 DI 是通过容器在调用无参数构造函数或无参数静态工厂方法来实例化 bean 后调用 bean 上的 setter 方法来完成的。...使用 DI 原则,代码更清晰,当对象提供依赖项时,解耦更有效。该对象不查找其依赖项,也不知道依赖项的位置或类,而是由 Spring 框架处理所有事情。

    53120

    SwiftUI + Core Data App 的内存占用优化之旅

    当子视图进入惰性容器的可视区域时,SwiftUI 会调用它的 onAppear 闭包,子视图退出可视区域时,会调用 onDisappear 闭包。...图片 在协调器具备的众多功能中,“行缓存”是其中很有特点的一个。所谓行缓存,便是指当 Core Data 从 SQLite 中获取数据时,首先将数据以接近原始存储格式的形式保存在行缓存( 内存 )中。...它保证了,只在真正对数据有需求时,才对数据进行获取( 实例化 )。在提高了性能的同时,也尽量减少了对内存的占用。 在本例中,只有视图首次出现在 List 的可视区域时,Item 才会被填充数据。...数据的多份拷贝 当图片数据从 SQLite 经 Core Data 最终通过 SwiftUI 显示时,实际上在内存中至少保存了三份拷贝: 行缓存 托管对象上下文( 托管对象被填充后 ) 显示该图片的 SwiftUI...} 在最终的代码中,我们对图片数据在内存中的三个备份实现了有效的控制。在同一时间( 理想情况下 ),只有出现在可视区域的图片数据才会保存在内存中。

    2.4K40

    SwiftUI + Core Data App 的内存占用优化之旅

    当子视图进入惰性容器的可视区域时,SwiftUI 会调用它的 onAppear 闭包,子视图退出可视区域时,会调用 onDisappear 闭包。...在协调器具备的众多功能中,“行缓存”是其中很有特点的一个。所谓行缓存,便是指当 Core Data 从 SQLite 中获取数据时,首先将数据以接近原始存储格式的形式保存在行缓存( 内存 )中。...它保证了,只在真正对数据有需求时,才对数据进行获取( 实例化 )。在提高了性能的同时,也尽量减少了对内存的占用。 在本例中,只有视图首次出现在 List 的可视区域时,Item 才会被填充数据。...数据的多份拷贝 当图片数据从 SQLite 经 Core Data 最终通过 SwiftUI 显示时,实际上在内存中至少保存了三份拷贝: 行缓存 托管对象上下文( 托管对象被填充后 ) 显示该图片的 SwiftUI...} 在最终的代码中,我们对图片数据在内存中的三个备份实现了有效的控制。在同一时间( 理想情况下 ),只有出现在可视区域的图片数据才会保存在内存中。

    1.3K10

    AVKit框架详细解析(四) —— 基于AVKit 和 AVFoundation框架的视频流App的构建

    注意:视频可能无法在模拟器中播放。 在真实设备上运行该应用程序将缓解该问题。 入门项目是一个 vlogger 应用程序,您将使用 AVKit 和 AVFoundation 添加功能和特性。...现在,是时候将您的视频剪辑列表添加到播放器中,以便它可以开始播放它们。...当它到达最后一个视频时,您将再次将所有剪辑添加到队列中。 当谈到“跟踪”播放器的信息时,唯一的途径就是使用键值观察(KVO)。 是的,这是 Apple 提出的最奇怪的 API 之一。...Context) { uiView.setVolume(volume) uiView.setRate(rate) } 这一次,您还向 updateUIView(_:context:) 添加了一些行,以说明当视图在屏幕上时音量和速率的变化...尝试在设备上运行。

    7K10
    领券