注意
这是一个标准的 UITextField
,扩展后可在控件下方提供“自动填充”下拉菜单。此控件将提供字符串数组中的匹配项,这些匹配项可用作“自动填充”。如果用户选择了其中一个字符串,则该字符串将完整地输入到文本字段中。
图 1:控件的标准显示,带有“开始于”操作
默认情况下,这是一个简单的“单向”、“贪婪”匹配。它从头开始,然后向前移动,匹配输入到文本字段中的字符。它们必须全部匹配,但匹配可以是大小写/变音符无关的(默认情况下)。
我们可以选择几种匹配模式,因此我们可以在字符串之前和/或之后“通配”文本(或者坚持精确匹配)。
图 2:控件的标准显示,带有“包含”操作
该控件的设计允许大量自定义,以及一种非常简单的方法来提供要搜索的数据。它还具有修改为更高级数据搜索的能力。
用户必须实际选择一个表格行。没有“Tab”自动填充。这适用于电话等设备,在这种设备上,这实际上没有意义,并且应用程序可能对返回函数有其他计划。
在手机上输入文本并不容易。这有助于减少我们实际需要输入的文本量。
此外,这可以帮助我们通过输入部分规范来“探索”数据集。例如,如果我们在某个区域搜索用户,我们可能会进行“分类”搜索,并创建一个本地用户主数据库的子集。在寻找用户时,这些可以用作自动填充建议。
这是一个仅限 Swift 的模块。它基于 标准 UIKit,适用于 iOS/iPadOS。
使用该控件没有依赖项,但如果运行 测试工具,则有几个依赖项
您可以将此软件包作为 Swift Package Manager (SPM) 软件包获取,或者您可以使用 GitHub 的 Carthage Package Manager 包含它。最后,您也可以直接访问 GitHub 仓库,然后简单地将 单个源文件包含到您的应用程序中。
为了使用 SPM,使用其 GitHub 仓库位置将软件包添加到您的项目中
git@github.com:RiftValleySoftware/RVS_AutofillTextField.git (SSH),
或者
https://github.com/RiftValleySoftware/RVS_AutofillTextField.git (HTTPS).
将静态 RVS_AutofillTextField
库添加到您的项目中,并将以下 import
行添加到将使用该控件的文件的顶部
import RVS_AutofillTextField
将以下行添加到您的 Cartfile
github "RiftValleySoftware/RVS_AutofillTextField.git"
然后,在主项目目录中运行 carthage update
。
这将创建一个名为“Carthage”的目录。在该目录中,将是另一个名为 Checkins
的目录。在该目录中,将是 RVS_AutofillTextField/Sources/RVS_AutofillTextField/RVS_AutofillTextField.swift
。
我建议您直接将此文件包含到您的应用程序中,而不是构建库并添加它。如果您这样做,则无需导入模块。此外,IBDesignables 的东西应该可以工作(这些是 storyboard 文件中的预览)。
上述 Carthage 说明也基本上适用于从 GitHub 获取文件。您可以使用以下 GitHub URL 访问仓库
git@github.com:RiftValleySoftware/RVS_AutofillTextField.git (SSH),
或者
https://github.com/RiftValleySoftware/RVS_AutofillTextField.git (HTTPS).
您可以将该仓库添加为 Git Submodule,甚至作为一个单独的仓库,您将其用作物理文件的来源。
获取与 Carthage 指示的文件相同的文件,并将其添加到您的项目中。
您以与实例化 UITextField
实例完全相同的方式实例化控件。这可以通过编程方式完成
var myTextEntryWidget = RVS_AutofillTextField(frame: widgetFrame)
或者使用 Interface Builder 和 storyboard/IB 文件
图 3:拖入一个文本字段对象
首先拖入一个文本字段。
图 4:设置类(以及可能的模块)。
将该类转换为 RVS_AutofillTextField
的实例。您可能还需要设置模块(如果不直接包含该文件)。
图 5:控件,在它的新家。
它现在将显示为标准文本字段。
图 6:自定义控件参数。
这些是 RVS_AutofillTextField
类型的自定义参数。
图 7:标准文本字段参数。
但我们也有传统的文本字段控件。
注意
下拉菜单连接到主根屏幕视图,因此它“浮动”在所有其他内容之上。它不是模态的。您仍然可以访问它后面的所有内容。
此外,只有当控件具有焦点并包含与选择匹配的文本时,才会显示下拉列表。仅仅给它一个字符串列表不足以使下拉列表出现。它还必须在该字段中包含将触发一个或多个字符串中匹配项的文本。
没有数据源,该控件将无法工作。您无法通过 storyboard 添加数据源。它需要以编程方式完成。这是因为我们不想强制此控件的用户必须从基于 NSObject
的类开始(需要通过 IB 提供数据源)。
一旦控件被安装/实例化,它需要被 一个内部属性引用,如下所示
/* ################################################################## */
/**
This is the CuT (Code Under Test). It is the test target instance of `RVS_AutofillTextField`.
*/
@IBOutlet weak var autofillTextField: RVS_AutofillTextField!
在加载设置期间,我们应该添加数据源,如下所示
/* ################################################################## */
/**
Called when the view hierarchy has been loaded. We use this to sync the CuT with the UX.
*/
override func viewDidLoad() {
super.viewDidLoad()
autofillTextField?.dataSource = self
以上示例直接取自 测试工具项目。在该项目中,主视图控制器也是 RVS_AutofillTextFieldDataSource
协议的遵循实例。
RVS_AutofillTextFieldDataSource
协议非常简单。
它要求向控件提供一个 简单结构体的数组,然后该数组将用于提供自动填充“燃料”。
结构体的每个实例都将具有两个属性
这是一个简单的 String
。它具有要搜索的完整字符串,并且可能会提供用于替换文本字段的内容。
这允许您将任意“参考上下文”附加到该元素。这是您可以附加诸如对其他属性或对象的引用的方式。它是一个可选的 Any?
值,默认为 nil
,因此无需定义它。它只是在那里,为您服务。
可以通过以下两种方式之一提供此数组
默认情况下,数据源协议会进行相当简单、幼稚的搜索以查找匹配项。如果我们对此感到满意,那么我们需要做的就是提供一个属性,如下所示
/* ################################################################## */
/**
This is an Array of structs, that are the searchable data collection for the text field.
If this is empty, then no searches will return any results.
*/
var textDictionary: [RVS_AutofillTextFieldDataSourceType] {
testingTextDictionary.compactMap {
let currentStr = $0.trimmingCharacters(in: .whitespacesAndNewlines)
return !currentStr.isEmpty ? RVS_AutofillTextFieldDataSourceType(value: currentStr) : nil
}
}
协议默认设置将负责为我们搜索和匹配。
如果您希望有一种方法来优化或以其他方式过滤/解释提供给控件的数据,则您的数据源可以实现 getTextDictionaryFromThis(string inString: String, isCaseSensitive inIsCaseSensitive: Bool, isWildcardBefore inIsWildcardBefore: Bool, isWildcardAfter inIsWildcardAfter: Bool, maximumAutofillCount inMaximumAutofillCount: Int) -> [RVS_AutofillTextFieldDataSourceType]
方法
控件会重复调用它,传递一个包含当前文本内容的 String,并返回一个经过过滤和搜索的元素数组。
您必须实现上述方法中的至少一种。如果您不这样做,那么您就只有一个普通的 UITextField
实例。
该控件有几个可选字段,可通过 storyboard 获得(图 6)。
isAutoFillOn
这是一个 Bool 值,是功能的“主断路器”。默认为开启。如果关闭,则该控件只是一个普通的 UITextField
。
isCaseSensitive
如果此选项为开启(默认为关闭),则搜索会考虑大小写和变音符。如果关闭,则搜索将忽略变音符和大小写。
isWildcardBefore
如果此选项为开启(默认为关闭),则我们将忽略匹配之前的字符,因此匹配可以更深入到字符串中。它不需要从字符串开始。
isWildcardAfter
如果此选项为开启(默认为开启),则在匹配之后的字符将被忽略。
maximumAutofillCount
这是一个整数值,用于指定表格中显示的最大结果数。如果将其设置为 -1(或任何负数),则将没有限制,并且表格可能会变得非常大(并且可以滚动)。默认为 5。
如果您正在寻找精确匹配,请关闭两个通配符。如果您使其区分大小写,则字符串必须完全匹配。
如果您正在寻找以大小写不敏感的匹配项开始,只需保留默认设置即可。如果您正在寻找“以...结尾”的匹配项,请打开之前的通配符,然后关闭之后的通配符。
您可以指定不同的背景颜色和字体颜色。默认为标准系统背景,不透明度为 75%,标准标签颜色,未匹配文本的不透明度为 50%。
默认情况下,下拉列表附加到应用程序的主 UIWindow
实例,但您可以通过设置 containerView
属性来提供自己的上下文。如果您将其保留为 nil,则使用主窗口。显示的坐标会进行调整以在上下文视图中工作。
存在一个 RVS_AutofillTextFieldDelegate
协议。它有一个简单的方法来检测用户何时选择一个选项。
您只需将代理设置为 UITextField.delegate
属性即可分配代理。它需要是一个 UITextFieldDelegate
(这也意味着代理必须是 NSObject
),即使它不使用任何代理功能。这是因为我们“借用”了内置的代理。代理协议本身并不扩展 UITextFieldDelegate
,因为它具有一种数据类型,该类型不一定适用于 Objective-C。
MIT 许可证
版权所有 (c) 2021 Rift Valley Software, Inc.
特此授予任何人免费获取本软件及相关文档文件(以下简称“软件”)的许可,可以不受限制地处理本软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售本软件的副本,并允许向其提供本软件的人员这样做,但须符合以下条件
上述版权声明和本许可声明应包含在本软件的所有副本或实质性部分中。
本软件按“原样”提供,不提供任何形式的明示或暗示的保证,包括但不限于适销性、特定用途适用性和不侵权的保证。在任何情况下,作者或版权持有者均不对任何索赔、损害或其他责任负责,无论这些责任是因合同、侵权或其他原因引起的,与本软件或本软件的使用或其他处理有关。