注意
RVS_CalendarInput 是一个自定义的 UIView 实现,它将显示一个基本的月份/网格日历,并在选定的日期上显示活动的按钮。
对于使用过基于 Web 的“预订”系统的人来说,该工作流程可能很熟悉。 以日历形式呈现日期网格,某些日期突出显示为切换按钮。 用户可以选择这些日期。
与我们生产的其他一些开源小部件不同,此小部件是为单个应用程序和工作流程设计的,因此它不如 Great Rift Valley Software Company 的其他小部件那么“通用”。
在我们的应用程序中,我们添加了一个工作流程,允许应用程序的用户声明他们将参加某些日期的活动。 这个小部件是他们执行此操作的方式。
向用户呈现一个可能的日期网格,并且某些日期已启用。 这在视觉上通过颜色/对比度和透明度的组合来指示。 用户可以选择或取消选择已启用的日期,并且该视图将包含一个滚动条,允许实现者呈现一系列可能的日期。 当用户选择启用的日期时,其状态将切换。 存储的数据集将修改该日期,并且会通知委托。
有用于星期几、年份和月份的标题。 它们都可以单独隐藏。 星期几标题是“固定的”。 滚动条将在其下方滚动。
该小部件已完全本地化,尊重用户的日历和一周的开始。 所有星期几和月份都以本地化形式显示。 它也能很好地适应各种布局,并且可以自定义其标题和其他项目。
这是一个仅使用 Swift 的模块。 它基于 标准的 UIKit,用于 iOS/iPadOS。
该小部件或测试工具应用程序没有依赖项。
该小部件仅包含 一个单独的源文件。 这就是您的项目所需要的全部。 其他一切都是测试和文档。 您可以通过多种方式访问此文件。
您可以将此软件包作为 Swift Package Manager (SPM) 软件包获取,也可以使用 GitHub 的 Carthage Package Manager 将其包含在内。 最后,您还可以 直接访问 GitHub 存储库,并将 单个源文件 简单地包含在您的应用程序中。
为了使用 SPM,请使用其 GitHub 仓库位置将该软件包添加到您的项目中
git@github.com:RiftValleySoftware/RVS_CalendarInput.git (SSH),
或
https://github.com/RiftValleySoftware/RVS_CalendarInput.git (HTTPS).
将静态 RVS_CalendarInput
库添加到您的项目中,并将以下 import
行添加到将使用该小部件的文件顶部
import RVS_CalendarInput
将以下行添加到您的 Cartfile
github "RiftValleySoftware/RVS_CalendarInput.git"
然后,在主项目目录中运行 carthage update
。
这将创建一个名为“Carthage”的目录。 在该目录中,将是另一个名为 Checkins
的目录。 在该目录中,将是 RVS_CalendarInput/Sources/RVS_CalendarInput/RVS_CalendarInput.swift
。
我建议您将此文件直接包含在您的应用程序中,而不是构建库并添加该库。 如果这样做,则无需导入模块。 此外,IBDesignables 内容应该有效(这些是情节提要文件中的预览)。
上述 Carthage 说明基本上也适用于从 GitHub 获取文件。 您可以使用以下 GitHub URL 访问存储库
git@github.com:RiftValleySoftware/RVS_CalendarInput.git (SSH),
或
https://github.com/RiftValleySoftware/RVS_CalendarInput.git (HTTPS).
您可以将存储库添加为 Git 子模块,甚至可以将其添加为单独的存储库,用作物理文件的来源。
获取与 Carthage 指示的相同文件,并将其添加到您的项目中。
实现者将实例化此类的实例(通过情节提要或以编程方式)。 然后,他们将日期对象数组(符合 RVS_CalendarInputDateItemProtocol
)呈现给小部件,并且该小部件将围绕该数组进行配置。
最小单位是一个月。 月份将始终完整显示,从该月的第一天到最后一天。 数据集中最早的日期将确定开始月份,而数据集中最新的日期将确定数据集的最终月份。 数据集在呈现时不需要排序,但内部数据集将始终排序(按日期)。 有一个有用的 Array Extension,用于过滤数据集。
在呈现的数组中必须至少有一个日期。 任何其他日期将在小部件内合成(例如,如果一个日期是一个月的二十日,则将创建整个月,包括所有未提供的其他日期)。
只有初始集中明确存在的日期才能启用和/或选择(不是必需的。这些日期也可以禁用和/或取消选择)。 所有其他(人为的)日期都将被取消选择和禁用。
实现者可以注册为 delegate,以便在用户[取消]选择某一天时 接收通知,或者他们可以检查代表控件状态的数据对象数组。
所有这些属性都有默认值,但可以在运行时更改。
注意: 禁用的项目将始终以单色和透明显示。 您可以调整透明度和字体,但不能调整颜色。
calendar: Calendar
这包含用于控件的日历。 它默认为当前日历,但可以更改。
weekdayHeaderHeightInDisplayUnits: CGFloat
星期几标题的高度(以显示单位为单位)。 它默认为 30 个单位,但可以更改。
yearHeaderHeightInDisplayUnits: CGFloat
年份标题的高度(以显示单位为单位)。 它默认为 25 个单位,但可以更改。
monthHeaderHeightInDisplayUnits: CGFloat
月份标题的高度(以显示单位为单位)。 它默认为 20 个单位,但可以更改。
weekdayHeaderFont: UIFont
用于顶部星期几标题的字体。
yearHeaderFont: UIFont
用于年份标题的字体。
monthHeaderFont: UIFont
用于月份标题的字体。
weekdayFont: UIFont
用于每一天(包括启用和禁用)的字体。
enabledItemBackgroundColor: UIColor
这是未选择和启用的日期的背景颜色。 UIView.tintColor
属性用于设置启用日期的字体颜色(并在选择日期时变为背景)。 如果选择了日期,则此属性将变为字体颜色。
weekdayHeaderFontColor: UIColor
用于顶部星期几标题的字体。
yearHeaderFontColor: UIColor
用于年份标题的字体颜色。
monthHeaderFontColor: UIColor
用于月份标题的字体颜色。
yearHeaderBackgroundColor: UIColor
用于年份标题的背景颜色。
monthHeaderBackgroundColor: UIColor
用于月份标题的背景颜色。
disabledAlpha: CGFloat
禁用日期按钮的不透明度。
showMonthHeaders: Bool
如果此属性为 false(默认为 true),则月份标题将不会显示。
showYearHeaders: Bool
如果此属性为 false(默认为 true),则年份标题将不会显示。
showWeekdayHeader: Bool
如果此属性为 false(默认为 true),则星期标题将不会显示。
readOnlyMode: Bool
如果此属性为 true(默认为 false),则控件将在“只读”模式下运行。 在此模式下,日期不会切换。 协议回调仍然会进行,但日期项的状态是临时的,并在回调后恢复到其原始值。 如果此属性为 false(默认值),则每个日期的状态会在回调后切换并保持。
delegate: RVS_CalendarInputDelegate?
这是用于接收日期项更改通知的委托。 委托需要是一个类,这是一个弱引用。 这不能通过 IB 访问,因为我们不希望委托必须符合 NSObjectProtocol
协议。
日历根据符合 RVS_CalendarInputDateItemProtocol
协议 的元素数组来确定其月份范围。 此协议定义了一些基本特征,这些特征定义了日期本身、是否已选择和/或启用日期,并且还可以附加一个“引用上下文”,这是一个任意实体。“引用上下文”是一种旧模式,它允许我们以类型无关的方式将任何类型的信息附加到信息元素。 当您在 data
数组中查看日期项时,或者在 委托回调中显示时,您将能够访问和转换此项。
每个符合 RVS_CalendarInputDateItemProtocol
协议 的元素都必须实现以下属性或计算属性:
您可以通过创建一个包含一系列符合此协议的元素的数组来将数据呈现给控件,并且该控件将自动配置自身以显示数组指定的范围内的日期。
控件以整个月份为单位显示日期。 如果数组中的日期落在该月的任何位置,则会显示该月的整个日期。 月份范围将从包含数组中最早日期的月份(数组不需要排序)到包含数组中最新日期的月份。
数组中未明确提及的任何日期都将显示为禁用且未选择。
有一个 便捷的初始化器,可用于设置初始数据,或者您可以在任何时候通过将数组设置为 setupData
属性来设置控件。 设置此属性将重新计算日期范围并重新绘制小部件。
当数据呈现给小部件时,它用于创建一个内部数组,该数组会从呈现的数组中复制相关数据。 它不引用数组元素。 在内部,该数组被视为类(引用上下文),因此查看 data
数组会查看引用,但这些引用并未引用呈现的原始数据。
即使该协议不可哈希,我们也应将其视为可哈希的,每个日期的唯一值(年份 + 月份 + 日期)。
该控件不派生自 UIControl
。 这是因为 UIControl
事件目标系统对于可能与此控件发生的交互类型没有用。 而是,实现者应注册为 委托 (RVS_CalendarInputDelegate
),并在使用控件时 接收消息。 实现者始终可以检查 data
数组并确定控件状态。 该数组会实时更新。 数据保存在 RVS_CalendarInputDateItemProtocol
实例的数组中。 小部件维护一个无法从控件外部影响但可以读取的内部数组。
该控件完全以程序化的自动布局执行。 实现者需要做的就是实例化此类的一个实例,将其放置在布局中,并为其提供一个初始数据集。 小部件本身使用自动布局来维护其内部布局。 用户需要担心的只是在他们自己的布局中将小部件定位为一个矩形。
可以自定义控件的大多数颜色,但禁用的颜色将始终基于系统背景颜色(并且日期将略微透明)。 您无法更改禁用日期的颜色。
小部件类也被声明为 open
,因此可以对其进行子类化和完全修改。
测试工具应用程序是一个简单的单屏 iOS 应用程序,它在“仪表板”下呈现小部件。 默认日期范围是从今天之前的 1 个月(或偶尔 2 个月)到最多随后的 4 个月。 与今天相同的星期几在所有显示的日期中突出显示(在日期范围内)。
“今天”已启用并已选择(请注意图 2 中的 11 月 18 日)。 与“今天”相同的星期几的后续实例已启用但未突出显示(请注意图 2 中的 11 月 25 日)。 启用的日期在日期选择器中指定的结束日期结束。 即使在结束日期之后小部件中显示更多日期,它们也不会被启用或选择。
过去的日期始终禁用。 开始日期之后的同一星期几的过去日期也被选择(请注意图 1 中的 10 月 7 日 - 图 2 中的 11 月 11 日)。
![]() |
![]() |
---|---|
图 1:测试工具默认屏幕 | 图 2:测试工具默认屏幕(已滚动) |
仪表板中的三个开关将隐藏小部件标题。 图 3-6 将显示此过程是如何发生的
![]() |
![]() |
---|---|
图 3:隐藏年份标题 | 图 4:隐藏月份标题 |
![]() |
![]() |
---|---|
图 5:隐藏星期几标题 | 图 6:隐藏所有标题 |
使用日期选择器选择一个范围。 请注意,今天之前的任何日期(此文件于 2021 年 11 月 18 日编写)将被禁用。 将突出显示与今天相同的星期几。
![]() |
![]() |
---|---|
图 7:选择 2021 年 11 月 | 图 8:忽略今天(11 月 18 日) |
在图 8 中,我们限制了范围,以便不包括今天,因此即使显示了 11 月 18 日,我们也不会启用它。 它被选中,因为测试工具应用程序将其标记为已选中。
如果您点击小“小丑”按钮,小部件的颜色将被自定义为一些真正可怕的颜色(不用担心。再次点击该按钮,您将恢复默认值)
![]() |
![]() |
---|---|
图 9:小丑模式开启 | 图 10:小丑模式关闭 |
测试工具的源代码应该给出一个关于如何使用该应用程序的很好的例子。
MIT 许可证
版权所有 (c) 2021 Rift Valley Software, Inc.
特此授予任何人免费获得本软件和相关文档文件(“软件”)的副本的许可,以不受限制地处理本软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售本软件的副本,并允许向其提供本软件的人员这样做,但须遵守以下条件:
上述版权声明和本许可声明应包含在本软件的所有副本或实质部分中。
本软件“按原样”提供,不提供任何形式的明示或暗示的保证,包括但不限于适销性、特定用途的适用性和不侵权的保证。 在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任承担责任,无论是在合同诉讼、侵权诉讼或其他诉讼中,无论是由本软件或本软件的使用或其他交易引起的,还是与之相关的。