RVS_Spinner 控制器
这是一个实现“弹出旋转选择器”控制的特殊控制类。
您可以将一个值数组与旋转选择器相关联,并在用户触摸控制中心时将其呈现在用户面前。
该控件将弹出类似“扇形”的值集合,可以像旋钮一样滚动,或者是一个 UIPickerView
。
它完全自包含。您只需要实例化控件,给它一个位置(就像任何其他控件一样),并与之关联一组值。
数值应该伴随着图像。
旋转选择器的设计和外观可以进行高度定制,无论是在运行时还是在 IB Inspectable 属性中。
这解决了什么问题?
移动设备对穿梭和选择器等技术存在困难。Apple 的 UIPickerView
是针对动态选择问题的优秀解决方案,但也有一些问题。
首先,UIPickerView
很大。它们占据了很多宝贵的屏幕空间。这是必要的。
此外,它们使用数据源模式,在运行时以 JIT 的方式提供数据。这是一种优秀的方法,但它相当复杂。您用功能换取了简单性。
RVS_Spinner 是一个小图标,直到被触摸并展开。它也被设计成可以由拇指操作。
它还使用了一个相当简单的Array
数据提供程序。只需将一个结构体Array
与控件关联起来,它就会自动排序。
如何获取
作为 CocoaPod
只需
pod 'RVS_Spinner'
在您的 Podfile 中添加,然后运行 pod install
。
然后您需要通过添加以下内容到将访问旋转器的源文件中,来导入该模块
import RVS_Spinner
Swift Package
作为您可以通过参考其 GitHub 仓库 URI (SSH: [邮箱受保护]:RiftValleySoftware/RVS_Spinner.git 或 HTTPS: https://github.com/RiftValleySoftware/RVS_Spinner.git),使用 Swift 包管理器来包含 Spinner。
然后您需要通过添加以下内容到将访问旋转器的源文件中,来导入该模块
import RVS_Spinner
Carthage
使用您可以使用 Carthage 作为依赖关系管理器来安装它。
只需将以下内容添加到您的 Cartfile
github "RiftValleySoftware/RVS_Spinner"
这将把项目放入一个“Carthage”目录中。
您可能想把单个文件从项目中添加(而不是添加产品)。这个可以在“Checkins”中找到。
如果您这样做,那么不需要导入。
如果您包括产品(在“Build”子目录中),您需要通过将以下内容添加到将访问旋转器的源文件中,来导入该模块
import RVS_Spinner
请注意,Carthage 可能不会对该模块进行签名,您可能遇到提交的问题。
直接从GitHub获取
由于整个控制都在一个文件中,您也可以选择简单地获取那个源文件(RVS_Spinner/RVS_Spinner.swift文件),并将其包含到您的项目中;在这种情况下,您无需导入
模块。
实际上,我建议这样做。我不是特别喜欢“实时”依赖项(我通常将代码依赖项“快照”并包含在项目仓库中),而且这实际上会略微减少开销。
需求
该Spinner是以仅支持Swift的静态库(或动态框架)的形式提供的,支持iOS 11.0及以上版本。
操作
环形加载指示器
它的工作原理是“休眠”控件较小。默认情况下,它是一个椭圆形或圆形;可能包含图像或文本,或者仅包含图像。
在圆圈上轻按“弹出一个围绕它的图像环”,该图像环可以围绕中心旋转,就像一个奖品转盘或旋钮。
此弹出是一个在中心视图的上层打开的UIControl
,因此上层必须能够支持添加更大的视图。
您可以在运行时或Interface Builder/Storyboard编辑器中指定弹出窗体的半径或UIPickerView
。图片大小将自动调整以适应圆形。
您可以通过手势控制打开的Spinner。它被设计为可以由拇指控制;包括可以发送控制进行减速旋转的“抽奖转盘”Spinner。最上面(最显露)的值将被选中。点击旋转的控制将使其停止。您还可以在打开的控制两侧单点,每次向前进(或减一)。
PICKER VIEW VARIANT
您还可以出现标准的UIPickerView
,这可能在处理大量值时更好,或者对于那些更喜欢更标准苹果用户体验的开发者来说更合适。
IMPLEMENTATION
要在您的项目中使用RVS_Spinner
,请将框架导入到Swift 4.0或更高版本的项目中。主要的Spinner类名为“RVS_Spinner”,您可以在storyboards中使用此类。
与UIPickerView
不同,Spinner是自包含的。您提供一个包含RVS_SpinnerDataItem
实例的Array
,这些实例至少包含一个图标(一个UIImage
)和一个标题(一个String
)。当Spinner打开时,将由Spinner显示这些内容(旋转器变体只显示图标,但选择器变体两者都显示)。
Spinner有一个RVS_Spinner.selectedIndex
属性,表示哪个Array
元素是选中的值。
为了在Interface Builder/Storyboard编辑器中使用,您需要拖入一个UIView
,然后将其设置为RVS_Spinner
的实例。模块将是“RVS_Spinner”(如果您使用了CocoaPods或框架的话)。
INTERFACE BUILDER/STORYBOARD EDITOR OPTIONS
一旦将RVS_Spinner
类分配给UIView
,将为Spinner在属性检查器中显示一组选项
-
开启背景颜色 这是显示在开启的环形滚动器或选择器后面的颜色。默认情况下为透明。
-
滚动器模式 这是一个整数,有三个值
- -1 只使用环形滚动器(忽略滚动器阈值值)。
- 0 在环形滚动器与选择器之间切换(基于滚动器阈值值)。
- 1 只使用选择器(忽略滚动器阈值值)。
-
滚动器阈值 这是一个整数,从0到您希望的任何值,它表示
Array
的值从环形滚动器切换到选择器的点。这仅适用于将滚动器模式选项设置为0时(即两者)。 -
声音开启 这指定是否使用可听反馈。当警报(响铃)设置关闭时,将禁用声音。
-
触觉开启 这指定是否使用触觉反馈(在支持触觉反馈的设备上)。
此外,视图的背景颜色用于确定图标周围的颜色,而你着色颜色用于设置图标周围边框和选择器中显示的文本的颜色。
如果UIView
的背景颜色是透明的,并且UIView
的着色是透明的,则图标将以稍微大一点的大小显示,没有周围的环形(顺便说一下,您可以通过程序更改环形的形状。圆形/椭圆形是默认值)。
如果着色是透明的,则UIPickerView
的文本将呈现黑色。
程序化选项
RVS_Spinner的使用重要的一个方面是应用一个Array
的RVS_SpinnerDataItem
实例。
这是一个结构,包含一个用于显示的图标(一个UIImage
)和一个String(图片的标题)。您还可以选择性地将更详细的描述
在滚动器弹出窗口中,仅显示图片,但在PickerView版本中,文字也会显示。将文本设置为""将在选择器中仅显示图片。
您还可以将任意数据项附加到《RVS_SpinnerDataItem》实例中。有一个名为value
的属性,它是一个Any?
属性。您可以将任何数据与RVS_Spinner数据项关联。选择《RVS_Spinner》实例的RVS_Spinner.value
计算属性将返回整个选定的数据项。这些都是值类型,而不是引用类型。
您需要通过程序提供这个数组。将它分配给RVS_Spinner.values
属性,数据将立即可用。
旋转
您可以对控件进行旋转,中心可以补偿。有一个名为 "isCompensatingForContainerRotation
" 的属性,该属性将强制中心图标始终垂直,即使在控制旋转的情况下。默认情况下,这是true。将其设置为false将导致中心图标旋转以匹配控制旋转。
您不应该旋转控件。相反,您应该旋转封装视图(限制和定义打开旋转器和选择器的那个视图)。这确保了所有手势都得到正确旋转。
旋转应通过设置旋转器父视图的《transform
属性》来程序化完成。
代码示例
以下是一个示例代码片段(来自Test Harness应用)
首先,我们将数据数组设置到控件中
func setUpDataItemsArray(_ inNumberOfItems: Int) {
_dataItems = []
let items = subsetOfShapes(inNumberOfItems)
items.forEach {
_dataItems.append(RVS_SpinnerDataItem(title: $0.name, icon: $0.image, value: _associatedText[$0.index]))
}
setUpSpinnerControl()
}
注意value: _associatedText[$0.index]
。这是我们关联任意数据到数据项的方式。在这种情况下,数据是简单的String
实例,但可以是任何您喜欢的类型。请记住,数据数组是一个值类型,而不是引用类型。
func setUpSpinnerControl() {
spinnerView.values = _dataItems
spinnerView.selectedIndex = _dataItems.count / 2
spinnerView.backgroundColor = _colorList[innerColorSegmentedControl.selectedSegmentIndex]
spinnerView.tintColor = _darkColorList[borderColorSegmentedControl.selectedSegmentIndex]
spinnerView.openBackgroundColor = _colorList[radialColorSegmentedControl.selectedSegmentIndex]
spinnerView.delegate = self
}
注意spinnerView.delegate = self
。这是因为测试框架的UIViewController
实现了RVS_SpinnerDelegate
协议。
委托
该旋转器使用了一个 Delegate
模式来与实现进行交互。您可以选择在不分配代理的情况下使用控件,但是拥有代理可以提供更大的交互性和响应性。
要成为代理,您应将 RVS_SpinnerDelegate
作为您类的基 协议。您的类不需要是 @objc
类。代理协议是一个纯粹的 Swift 协议(这也是为什么您无法在 Interface Builder 中分配代理的原因)。
RVS_Spinner
类确实发送传统的 UIControl Target/Action
事件。特别是 UIControl.Event.valueChanged
和 UIControl.Event.touchUpInside
。您可以监听这些事件。旋转器变体会发送连续的 UIControl.Event.valueChanged
,直到旋转完成,而选择器变体直到完成滚动才会发送这些事件
UIControl.Event.touchUpInside
在控制中心的控制被点击时会被调用,以打开、关闭或表现为按钮。
继承和修改
可以通过继承和扩展 RVS_Spinner
。
其中一个原因可能是为了为除了默认圆形以外的项目提供“框架”形状。通过覆盖 RVS_Spinner.centerShape
属性并提供不同的 UIBezierPath
来实现这一操作。
您还可以修改所有其他类型的事情。RVS_Spinner
被设计为一个“基础”控件。
您可以通过设置 RVS_Spinner.displayFont
属性的新值来修改选择器变体中用于显示标题字符串的字体。
使用方法
这里已经涵盖了大量的内容,测试工具应用将帮助展示一些现实世界的实现,但您可以通过修改RVS_Spinner.selectedIndex
中的0基于的索引来更改选定的索引(哪个项被选为当前值)。RVS_Spinner.value
无法设置。它是一个只读属性。
BASIC TEST HARNESS APP
基本测试工具目标导入编译好的框架,因此它确实提供了RVS_Spinner
的现实应用。
该应用提供了对旋转选择器大量“旋钮和按钮”的访问。
它是一个简单的1视图应用,拥有单个窗口。
控件在实时上操作在控制面板上显示的RVS_Spinner
实例。
白色的"关联文本 #XX (XXXXX)"是一个标签,显示了与测试中使用的20个数据项相关联的测试数据。每个项目的value
属性被设置为String
,该字符串在选中该项时显示。
“Spinner/Picker阈值”分段开关将影响上面描述的“Spinner阈值”属性。它仅在“两者都”旋转模式(见下文)下启用。
“触觉”和“声音”开关控制是否启用每个属性。默认为开启。
在其下方是“旋转模式”分段开关。如果选择“仅旋转”,则控件将仅弹出旋转选择器;无论在values
数组属性中提供多少值,都不会启用“Spinner/Picker阈值”分段开关。
如果选择“仅选择器”,则仅显示选择器。同时禁用了“Spinner/Picker阈值”分段开关。
如果选择“两者都”,则“Spinner/Picker阈值”分段开关启用,并描述了几个值,这些值将改变RVS_Spinner实例的行为,从弹出旋转选择器变为弹出选择器。
“边框和文本颜色”分段开关有一些预设,这些预设应用于UIView.tintColor
属性。
“打开控制背景颜色”分段开关影响上面讨论的“打开背景颜色”属性。
“中心背景颜色”分段开关影响UIView.backgroundColor
属性,并影响中心圆的填充以及打开控制中图标的任何“框架”。
“值数量”分段开关将最多20个可用值的一个子集应用于控件。如果选择“1”,则控件不会弹出,而会像常规UIButton
一样表现。
测试工具应用是故意设计的简单,应该为使用RVS_Spinner
提供一个极好的“起点”。
简单示例
这里有三个简单示例,展示了如何在项目中实现 RVS_Spinner
应用
这些链接将下载 .zip 文件,解压后会变成小项目目录。
标签测试引擎应用
另一个测试引擎应用通过标签布局展示控制在不同场景下的使用,采用了一些复杂的自动布局技术。
第一个标签展示了一个简单的居中控制。您可以选择要使用的数据集,并选择是否将其作为滚动条或选择器强制使用。
第二个标签控制占据了屏幕的右下角,并逆时针旋转了 45 度。
第三个标签演示了旋转。滑动条控制旋转,包裹视图显示为略微较暗的方形。
以上图片显示旋转补偿开启。请注意,尽管控制被旋转,中心图标仍然是垂直的。
以下图片显示旋转补偿关闭。请注意,中间的图标现在是倾斜的。
第四个标签有些疯狂。它是四个独立的控制,占据屏幕的四分之一,每个旋转 45 度,但中间结合在一起。
泄露测试引擎应用
该小型简单应用只有一个目的:在“配置文件”模式下运行,并对框架进行审查,例如查找内存泄漏。
依赖关系
在项目中使用此类无需依赖。它可以作为一个单独的源文件包含(无需构建或库链接)。
待办事项
有一个已过时的回调:方向回调(观察者)。它在第1536行。我们需要解决它,但这还不是致命问题(目前还不是)。
许可证
MIT 许可证
以下为本软件和关联文档(“软件”)的副本或部分副本的复制、分发和使用的免费许可,但不得限制,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售软件副本的权利,并允许获得软件的人将其提供给他人以进行此类操作,但受以下条件限制
上述版权声明和本许可声明应包含在软件的全部复制品或主要部分中。
软件按“原样”提供,不提供任何明示或暗示的保证,包括但不限于适销性、特定目的适用性和非侵权的保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任(无论是基于合同、侵权或其他方式)承担责任,这些索赔、损害或其他责任源于、因之或与软件的使用或其他操作有关。