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

如何在SwiftUI中确定在多字文本视图中点击的字

在SwiftUI中确定在多字文本视图中点击的字,可以通过使用 TextTextEditor 组件来实现。

首先,使用 Text 组件创建一个多字文本视图,将其包裹在 ZStack 中,以便添加交互功能。然后,使用 GeometryReader 获取父视图的大小,以便确定点击位置。接下来,将文本分割为单个字符,并为每个字符创建一个可点击区域。当用户点击字符时,你可以根据所点击的字符执行相应的操作。

以下是一个示例代码,演示了如何在SwiftUI中实现这个功能:

代码语言:txt
复制
import SwiftUI

struct ContentView: View {
    let text = "Hello, World!" // 多字文本
    
    var body: some View {
        ZStack {
            Text(text)
                .foregroundColor(.black)
                .font(.largeTitle)
                .onTapGesture {
                    let tapLocation = getTappedLocation()
                    let tappedCharacter = getTappedCharacter(location: tapLocation)
                    print("Tapped Character: \(tappedCharacter)")
                    // 在这里可以执行其他操作,例如显示弹出窗口等
                }
        }
    }
    
    // 获取点击位置
    func getTappedLocation() -> CGPoint {
        var tapLocation: CGPoint = .zero
        
        // 使用GeometryReader获取父视图的大小
        GeometryReader { geometry in
            // 获取点击位置
            let tap = TapGesture()
                .onEnded { value in
                    tapLocation = value.location
                }
            // 添加透明的TextEditor,以便捕捉点击事件
            TextEditor(text: .constant(""))
                .frame(width: geometry.size.width, height: geometry.size.height)
                .background(Color.clear)
                .gesture(tap)
        }
        
        return tapLocation
    }
    
    // 获取点击的字符
    func getTappedCharacter(location: CGPoint) -> String {
        let characterIndex = getCharacterIndex(at: location)
        let tappedCharacter = String(text[text.index(text.startIndex, offsetBy: characterIndex)])
        return tappedCharacter
    }
    
    // 根据点击位置获取字符索引
    func getCharacterIndex(at location: CGPoint) -> Int {
        var characterIndex = 0
        let attributedString = NSAttributedString(string: text, attributes: [.font: UIFont.systemFont(ofSize: 36)])
        let textStorage = NSTextStorage(attributedString: attributedString)
        let layoutManager = NSLayoutManager()
        textStorage.addLayoutManager(layoutManager)
        let textContainer = NSTextContainer(size: CGSize(width: CGFloat.greatestFiniteMagnitude, height: .greatestFiniteMagnitude))
        textContainer.lineFragmentPadding = 0
        layoutManager.addTextContainer(textContainer)
        
        let textBoundingBox = layoutManager.usedRect(for: textContainer)
        let textContainerOffset = CGPoint(x: (UIScreen.main.bounds.width - textBoundingBox.size.width) / 2 - textBoundingBox.origin.x,
                                          y: (UIScreen.main.bounds.height - textBoundingBox.size.height) / 2 - textBoundingBox.origin.y)
        let locationInTextContainer = CGPoint(x: location.x - textContainerOffset.x, y: location.y - textContainerOffset.y)
        
        characterIndex = layoutManager.characterIndex(for: locationInTextContainer, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
        
        return characterIndex
    }
}

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

在这个示例中,我们首先创建了一个多字文本视图,然后使用 ZStack 包裹其中。然后,我们在 Text 组件上添加了一个 onTapGesture 闭包,以便在用户点击时触发操作。在这个闭包中,我们使用 getTappedLocation() 方法获取点击位置,并使用 getTappedCharacter(location:) 方法获取点击的字符,并将其打印出来。你可以在这个闭包中执行其他操作,例如显示弹出窗口等。

为了获取点击位置,我们使用了 GeometryReader 获取父视图的大小,并添加了一个透明的 TextEditor 组件,以便捕捉点击事件。然后,我们使用 TapGesture 捕捉点击事件,并将点击位置保存在 tapLocation 变量中。

为了获取点击的字符,我们使用了 getCharacterIndex(at:) 方法来计算点击位置对应的字符索引。首先,我们创建了一个 NSAttributedString 对象,并设置了字体大小。然后,我们创建了一个 NSTextStorage 对象,并将 NSAttributedString 对象添加到其中。接下来,我们创建了一个 NSLayoutManager 对象,并将 NSTextStorage 对象添加到其中。然后,我们创建了一个 NSTextContainer 对象,并将其大小设置为最大。最后,我们使用 NSLayoutManagercharacterIndex(for:in:fractionOfDistanceBetweenInsertionPoints:) 方法计算点击位置对应的字符索引。

请注意,这只是一个示例代码,用于演示在SwiftUI中确定在多字文本视图中点击的字的方法。你可以根据自己的需求进行修改和扩展。另外,由于涉及到UITextView和Cocoa的相关类,该示例代码需要在iOS平台上运行。

希望这能帮助到你!

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

相关·内容

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

假设我们想创建一个类似于 iMessage 视图,在那里你可以看到一个信息列表(与本例无关),在视图底部有一个文本框。当用户点击文本字段时,键盘会在其工具栏中出现一个文本字段。...阅读 SwiftUI 动画机制[8] 一文,了解更多有关动画内容。自适应高度 SheetQ:如何在 iOS16 呈现与动态内容高度相匹配 Sheet?...对于非惰性视图 LazyVStack ),一旦 hosting controller 视图被初始化,onAppear 将被调用。...但是从一个文本字段到下一个文本字段聚焦感觉不够流畅,而且每当我在一个文本字段输入一个字母时,我 CPU 使用率似乎会飙升到 70% — 100%。...A:如果你在 iOS 上使用 UITextField 遇到性能问题,你可以尝试避免每个视图都是 UITextField ,默认渲染为 Text ,当文本点击时动态切换为 UITextField 。

12.2K20

SwiftUI TextField进阶——格式与校验

SwiftUI TextField进阶——格式与校验 想获得更好阅读体验,请访问我博客 www.fatbobman.com[1] SwiftUITextField可能是开发者在应用程序中最常使用文本录入组件了...本文为【SwiftUI 进阶】系列文章一篇,在本文中,我将介绍如何在TextField实现如下功能: •屏蔽无效字符•判断录入内容是否满足特定条件•对录入文本实时格式化显示 textfieldDemo1...SwiftUI修饰方法) 以上原则,在SheetKit——SwiftUI模态视图扩展库[3]和用NavigationViewKit增强SwiftUI导航视图[4]均有体现。...如何在TextField屏蔽无效字符 现有屏蔽字符方法 在SwiftUI,可以通过设置仅使用特定键盘类型来实现一定程度上录入限制。...不利于判断用户是否录入新信息(更多信息可参阅如何在SwiftUI创建一个实时响应Form[10])。方案二允许不提供初始值,支持可选值。

8.1K20
  • 何在 SwiftUI 视图中显示应用图标和版本

    前言在应用显示应用图标和版本是为用户提供快速识别应用版本和变体好方法,无论是内部用户(测试人员或利益相关者)还是外部用户。...在本文中,我将展示如何创建一个可访问 SwiftUI 视图,既能显示应用图标和版本,又能在各种文本大小和外观下看起来都很好:获取应用图标构建视图第一步是从主包获取应用图标。...可以通过检索应用 Info.plist 文件一组键值来完成, Stack Overflow 上这个答案所示:AppIconProvider.swiftimport Foundationenum...最终结果是一个在各种文本大小下都看起来很好视图:在应用显示版本信息视图Copy codeContentView.swiftimport SwiftUIstruct ContentView: View...我们学习了如何在 SwiftUI 应用显示应用图标和版本信息。

    15022

    何在 SwiftUI 创建条形图

    系列文章 如何在 SwiftUI 创建条形图 SwiftUI 水平条形图 在 iOS 16 中用 SwiftUI Charts 创建一个折线图 在 iOS16 中用 SwiftUI 图表定制一个线图...在 Swift 图表中使用 Foudation 库测量类型 开始图表布局 SwiftUI 对探索不同布局和预览实时视图结果是很友好。...条形图上值使用叠加视图修改移到了条形图顶部。这个值是偏移,所以文本不会离条形图顶部太近。数据名称字体大小和重也可以被设置。...文本视图宽度被限制在条形图宽度范围内,而且条形图标签文本会被截断,条形图文本视图也被限制在条形宽度范围内,并且文本可以被隐藏起来。...SwiftUI 是一个很好平台,用于创建视图和快速重构独立视图。在 SwiftUI 构建条形图需要做一些工作,随着使用数据来试用条形图,可以确定更多定制化。

    5.2K10

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

    Swiftcord[12] 代码展示了如何在 SwiftUI 下实现倒置列表。阅读 优化在 SwiftUI List 显示大数据集响应效率[13] 一文,了解苹果工程师推荐方法。...但是,此转换仅在文本字段完成编辑时才会发生,并且不会阻止输入非数字字符。目前 SwiftUI 没有 API 可以限制用户在字段输入字符。...将背景扩展到安全区域Q:如果我有一个自定义容器类型,可以接受一个顶部和底部视图,是否有办法让 API 调用者将所提供视图背景扩展到安全区域内,同时将内容( 文本或按钮 )保留在安全区域内?...macOS APIQ:对于运行 Monterey Mac,能否如何在 SwiftUI 实现下面需求建议:打开一个窗口在该窗口中初始化数据找到所有打开窗口确定一个窗口是否打开从不在该窗口视图中关闭一个窗口...然而,两个内容相同视图之间交换并不能使视图顺利地产生动画,因为两者文本也被动画化了。我正在使用仅禁用 TextField 替代方法,但有没有办法引导动画以使用文档方法?

    14.8K30

    SwiftU:将状态绑定到UI控件

    SwiftUI@State属性包装器允许我们自由修改视图结构体,这意味着当程序更改时,我们可以更新视图属性以匹配。 但是,使用UI控件时,事情会更复杂一些。...但是,该代码不会编译,因为SwiftUI想知道文本字段文本存储位置。 请记住,视图是其状态函数——文本输入框只能在反映存储在程序值时显示某些内容。...SwiftUI需要是结构一个字符串属性,它可以显示在文本输入框,还将存储用户在文本输入框中键入任何内容。...Enter your name", text: $name) Text("Hello World") } } } 现在试着运行这个代码——你应该发现你可以点击文本字段并输入你名字...,预期那样。

    2.9K10

    WWDC - SwiftUI - 初恋般感觉

    我们将使用SwiftUI框架来构建Landmark详情界面。 Landmarks利用stacks将图片和文本组合起来来进行视图布局。你需要引用MapKit框架头文件来创建一个地图视图。...修改文本框字体是利用系统字体。 ? 第四步 手动修改代码,即添加.color(.green)把文本修改成绿色。 要自定义SwiftUI视图,你可以调用modifiers方法。...第六步 注意一点就是,Xcode会根据inspector修改自动更新你代码。 利用Stacks组合视图 我们创建了一个文本框用来显示landmark详情信息,并且把这个文本控件放到头部。...当我们创建SwiftUI视图控件时候,我们会把控件内容、布局还有一些行为放在body属性;然而body属性只返回了一个view。...你可以MapKitMKMapView类来展示渲染地图界面。 在SwiftUI要使用UIView或者其子类,你需要让你view遵循UIViewRepresentable协议。

    3.8K10

    从用SwiftUI搭建项目说起

    在UIKit我们导航、标签都是通过控制器来管理,但是在SwiftUI他们分别是通过NavigationView+TabView管理,我们得在认识上有一个基本转变,从Controller到View...public typealias Body = some View } 关于这个TabView在定义上面苹果是给出了一个使用基本示例,要和我们项目中经常使用模式要绑定在一起的话就是结合他初始化方法绑定一个...@State变量使用,具体我们会在后面的代码,关于这个@State我在项目Demo中有具体解释,包括像@bind类型或者是@EnvironmentObject这些关键我们肯定是得需要学习...,需要注意是我们点击item时候视图切换绑定状态,基本上在代码注释我说比较清楚了,应该能理解。...当 @State 装饰过属性发生了变化,SwiftUI 会根据新属性值重新创建视图 */ @State private var selectedTab = 0 var

    4.5K20

    何在 SwiftUI 熟练使用 visualEffect 修饰符

    前言在 WWDC 23 SwiftUI 引入了一个名为 visualEffect 视图修饰符。此修饰符允许我们通过访问特定视图布局信息来附加一组可动画化视觉效果。...下面我们将学习如何在 SwiftUI 中使用新 visualEffect 视图修饰符。介绍 visualEffect让我们从使用 visualEffect 视图修饰符最简单示例开始。...我们定义了一个文本视图并附加了 visualEffect 视图修饰符。...视觉效果是可以改变视图视觉外观但不影响其布局任何东西。在 SwiftUI 框架先前版本,我们有视图修饰符,缩放、偏移、模糊、对比度、饱和度、不透明度、旋转等。...总结本文章介绍了在 SwiftUI 引入视图修饰符 visualEffect。该修饰符允许我们通过访问特定视图布局信息来附加一组可动画视觉效果。

    11911

    我庆幸果断放弃了SwiftUI:它还不够成熟

    但在开始实现更复杂检查器视图时,特别是涉及带有 / 不带步进器或颜色选择器多个文本字段时,整个运行速度开始剧烈下降。...但每当 SwiftUI 更新检查器视图时(这种更新可能出现在移动过程,甚至是在输入文本字段时候),渲染速率都会下降到每秒 10 到 15 帧,而且相当不稳定。这显然让人无法容忍。...但这会导致检查器值出现延迟,因此在地图编辑器交互过程(比如使用移动工具时)结果不准确,所以效果还是称不上完美。 但我觉得这可能只是个独立问题,并不能因此把 SwiftUI 一棒子打死。...大家所见,这是个复杂窗口,包含多种不同上下文(上方「Sprite 资产数据库」列表,左侧特定「Sprite 资产数据库」内容,以及其他与选定 Sprite 资产对应编辑器元素)。...但上图展示效果其实是在 AppKit 完成,因为我在 SwiftUI 一直实现不了预期功能。大家应该注意到了,中间 SpriteKit 视图上有三个按钮(分别是 +、200% 和 -)。

    4.9K20

    SwiftUI中使用UIKit视图

    SwiftUI中使用UIKit视图 想获得更好阅读体验可以访问我博客www.fatbobman.com,或点击下方阅读原文 已迈入第三个年头SwiftUI相较诞生初始已经提供了更多原生功能...在相当长时间中开发者仍需在SwiftUI依赖UIKit(AppKit)代码。好在,SwiftUI为开发者提供了便捷方式将UIKit(AppKit)视图(或控制器)包装成SwiftUI视图。...本文将通过对UITextField包装来讲解以下几点: •如何在SwiftUI中使用UIKit视图•如何让你UIKit包装视图具有SwiftUI风格•在SwiftUI使用UIKit视图需要注意地方...如果按照TextField正常行为,当我们在其中输入任何文本时,下方Text应该显示出对应内容,不过在我们当前代码版本,并没有表现出预期行为。...当点击Random Name引起name变化时,SwiftUI将会调用updateUIView,而我们并没有在其中做任何处理。

    8.2K22

    SwiftUI 在 WWDC 24 之后新变化

    视图集合SwiftUI 为 Group 和 ForEach 视图引入了新重载,允许我们创建自定义容器, List 或 TabView。...SwiftUI 引入了新 Subview 和 SubviewsCollection 类型,提供了对真实视图代理访问。...extension EnvironmentValues { @Entry var itemsPerPage: Int = 10}预览新 Previewable 宏允许我们在预览引入状态,而无需将其包装到额外包装视图中...框架下一版本包括许多新 API,窗口推送、TextField 和 TextEditor 视图文本选择观察、搜索焦点监控、自定义文本渲染、新 MeshGradient 类型等等,我无法在一篇文章涵盖所有内容...这些改进使开发者能够创建更灵活和高效用户界面。SwiftUI还引入了许多新API,窗口推送、文本选择观察、搜索焦点监控等,使开发更加便捷和强大。

    6700

    SwiftUI 状态管理系统指南

    前言 SwiftUI与苹果之前UI框架区别不仅仅在于如何定义视图和其他UI组件,还在于如何在整个使用它应用程序管理视图层级状态。...属性状态 由于SwiftUI主要是一个UI框架(尽管它也开始获得用于定义更高层次结构(应用程序和场景)API),其声明式设计不一定需要影响应用程序整个模型和数据层——而只是直接绑定到我们各种视图状态...观察对象 State和Bingding共同点是,它们处理是在SwiftUI视图层次结构本身管理值。...尽管在一个父视图和它一个子视图之间创建绑定通常很容易,但在整个视图层次结构传递某个对象或值可能相当麻烦——而这正是环境变量旨在解决问题类型。 有两种主要方法来使用SwiftUI环境。...——我们可以将其应用于我们层次结构何在其之上视图

    5.1K20

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

    -08-22_09.16.25.2022-08-22 09_17_38通过按钮实现搜索结果切换image-20220822084740855切换搜索结果时可自动定位到结果所在位置点击非当前高亮关键...image-20220822161247454点击切换按钮定位到对应搜索结果为 TranscriptionRow 视图添加显式标识符,并通过 ScrollViewProxy 滚动到指定位置。...请阅读 优化在 SwiftUI List 显示大数据集响应效率[6] 以及 避免 SwiftUI 视图重复计算[7] 两篇文章,了解更多有关性能优化方面的内容通过 currentPostion 获取需要滚动到...了解更多内容,请阅读 SwiftUI 视图生命周期研究[9] 一文优先定位于最靠近屏幕中央搜索结果:/// 从 List 当前显示 transcription 中就近选择 match positionprivate...} else { return position.last }}locate_onScreen_2022-08-22_17.49.52.2022-08-22 17_50_35点击搜索结果切换当前选择点击非选择搜索结果

    4.2K30

    SwiftUI 布局工作原理

    SwiftUI 布局工作原理 ---- 所有的 SwiftUI 布局都有三个简单步骤,理解这些步骤是每次获得优秀布局关键。步骤如下: 父视图提供一个大小并询问其子视图大小。...您所见,ContentView主体(它呈现内容)是一些带有背景色文本。所以ContentView大小总是和它主体大小一样,不多不少。...,我向您解释过,当您对视图应用修饰符时,我们实际上会得到一个名为ModifiedContent视图类型,它存储了原始视图及其修饰符。...这意味着当我们应用修饰符时,进入层次结构实际视图是修改后视图,而不是原始视图。 在我们简单background()示例,这意味着ContentView顶层视图是背景,而内部是文本。...background(Color.red)),文本视图成为其背景视图。当涉及到视图及其修改器时,SwiftUI有效地从下到上工作。

    3.8K20

    何在 SwiftUI 中使用 AccessibilityCustomContentKey 修饰符

    前言SwiftUI 3 发布了许多新辅助功能 API,我们可以利用这些 API 以轻松方式显著提高用户体验。...本篇文章来聊聊另一个新 API,我们可以使用 SwiftUI 新 accessibilityCustomContent 视图修饰符提供自定义辅助功能内容。...不需要执行任何操作即可使你 UserView 可访问。UserView 内每个文本片段都对辅助技术(VoiceOver和Switch Control)可访问。...通常,我们使用不同字体和颜色在视觉上为文本设置优先级,但是如何在辅助技术实现相同影响呢?...使用新修饰符SwiftUI 通过全新 accessibilityCustomContent视图修饰符提供了一种使用不同重要性生成自定义辅助功能内容方法。让我们看看如何使用它。

    7400

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

    onCommit 当用户在输入过程按下(或点击)return键时触发 onCommit(无法通过代码模拟触发)。...在 SwiftUI 3.0 ,苹果为开发者提供了一个远好于预期解决方案,同 onSubmit 类似,可以从更高视图层次来统一对视图 TextField 进行焦点判断和管理。...在 SwiftUI 3.0 之前,我们必须在主视图上另外绘制或者使用非 SwiftUI 方式来解决问题,在 SwiftUI 3.0 ,由于添加了原生设置键盘辅助视图(下文具体介绍)功能,解决上述问题将不再困难...同其他类型 Toolbar 类似,SwiftUI 会干预内容排版。•无法对同一视图中多个 TextField 分别设定辅助视图在 ToolbarItem 无法使用稍微复杂一点判断语法。...将键盘辅助视图集成到 toolbar 逻辑也有些令人令人费解。 通过 UIKit 创建 当前阶段,通过 UIKit 来创建键盘辅助视图仍是 SwiftUI最优方案。

    13.2K10

    AttributedString——不仅仅让文字更漂亮

    想字符串同时支持多框架显示(代码复用),请分别为不同Scope同名属性赋值 attributedString.swiftUI.foregroundColor = .redattributedString.uiKit.foregroundColor...属性也将一并被转换 视图 在属性字符串,属性和文本可以被独立访问,AttributedString提供了三种视图方便开发者从另一个维度访问所需内容。...Character和unicodeScalar视图 这两个视图提供了类似NSAttributedStringstring属性功能,让开发者可以在纯文本维度操作数据。...= run.attributes totalKeysContainer.merge(container)} 使用Runs视图可以方便从众多属性获取到需要信息 不使用Runs视图,达到类似的效果...还有在Formatter中使用自定义属性案例 总结 在AttributedString之前,多数开发者将属性字符串主要用于文本显示样式描述,随着可以在Markdown文本添加自定义属性,相信很快就会有开发者扩展

    3.9K40
    领券