WhatsNewKit 使您能轻松展示您出色的全新应用程序功能。
它从头开始设计,完全可以根据您的需求进行定制。
特性
- 根据您的需求进行定制和配置
💪 - 预定义主题和动画
🎬 - 轻松检查您的功能是否已经展示过
🎁 - 出色的 UI
😍
示例
示例应用程序是查看 WhatsNewKit
在实际中如何使用的极好方式。您将简要了解可用的配置选项以及它们如何影响 WhatsNewViewController
的外观和感觉。只需打开 WhatsNewKit.xcodeproj
并运行 WhatsNewKit-Example
方案即可。
安装
CocoaPods
WhatsNewKit 通过 CocoaPods 提供。要安装它,只需将以下行添加到您的 Podfile 中
pod 'WhatsNewKit'
Carthage
Carthage 是一个去中心化的依赖管理工具,它构建你的依赖,并为你提供二进制框架。
要在你的 Xcode 项目中使用 Carthage 集成 WhatsNewKit,请在高 specification 文件中指定。
github "SvenTiigi/WhatsNewKit"
运行 carthage update --platform iOS
以构建框架,并将构建好的 WhatsNewKit.framework
拖入到你的 Xcode 项目中。
在你的应用程序目标“构建阶段”设置标签页上,点击“+”图标,选择“新建运行脚本阶段”,并添加框架路径,如 Carthage 入门步骤 4、5 和 6 中所述
Swift 包管理器
要使用 Apple 的 Swift 包管理器 进行集成,请将以下内容添加到你的 Package.swift
dependencies: [
.package(url: "https://github.com/SvenTiigi/WhatsNewKit.git", from: "1.3.0")
]
手动方式
如果你不希望使用上述任何依赖管理器,你可以手动将 WhatsNewKit 集成到你的项目中。只需将 源代码
文件夹拖入到你的 Xcode 项目中即可。
使用方法
以下第一部分使用说明展示了使用 WhatsNewKit
展示你的新应用功能的简单方法。
👨💻 请参阅 高级部分 了解更多配置选项和功能。
import WhatsNewKit
// Initialize WhatsNew
let whatsNew = WhatsNew(
// The Title
title: "WhatsNewKit",
// The features you want to showcase
items: [
WhatsNew.Item(
title: "Installation",
subtitle: "You can install WhatsNewKit via CocoaPods or Carthage",
image: UIImage(named: "installation")
),
WhatsNew.Item(
title: "Open Source",
subtitle: "Contributions are very welcome 👨💻",
image: UIImage(named: "openSource")
)
]
)
// Initialize WhatsNewViewController with WhatsNew
let whatsNewViewController = WhatsNewViewController(
whatsNew: whatsNew
)
// Present it 🤩
self.present(whatsNewViewController, animated: true)
此外,你可以使用 WhatsNewVersionStore
来确保 WhatsNewViewController
在每个版本的的应用中只显示一次。
// Initialize WhatsNewVersionStore
let versionStore: WhatsNewVersionStore = KeyValueWhatsNewVersionStore()
// Passing a WhatsNewVersionStore to the initializer
// will give you an optional WhatsNewViewController
let whatsNewViewController: WhatsNewViewController? = WhatsNewViewController(
whatsNew: whatsNew,
versionStore: versionStore
)
// Verify WhatsNewViewController is available
guard let viewController = whatsNewViewController else {
// The user has already seen the WhatsNew-Screen for the current Version of your app
return
}
// Present WhatsNewViewController
self.present(viewController, animated: true)
👨💻 前往 WhatsNewVersionStore 了解更多信息。
高级
如前所述,WhatsNewKit
可以完全根据您的需求进行定制。本高级部分将详细介绍WhatsNewKit
的所有配置可能性和特性。首先,理解WhatsNewViewController
的组成部分对于定制行为和UI设计至关重要。
WhatsNewViewController配置
WhatsNewViewController.Configuration结构体允许您根据需求定制WhatsNewViewController
组件。该配置本身可以通过将要创建的初始化器传递。
// Initialize default Configuration
var configuration = WhatsNewViewController.Configuration()
// Customize Configuration to your needs
configuration.backgroundColor = .white
configuration.titleView.titleColor = .orange
configuration.itemsView.titleFont = .systemFont(ofSize: 17)
configuration.detailButton?.titleColor = .orange
configuration.completionButton.backgroundColor = .orange
// And many more configuration properties...
// Initialize WhatsNewViewController with custom configuration
let whatsNewViewController = WhatsNewViewController(
whatsNew: whatsNew,
configuration: configuration
)
🌄
主题主题允许您分组自定义WhatsNewViewController.Configuration
。WhatsNewKit
实现了预定义的主题,这些主题在亮色模式和深色模式中都有可用的静态属性。或者您可以创建自己的主题,以满足您的定制需求。
.darkRed |
.whiteRed |
---|---|
// Configuration with predefined Dark Red Theme
let darkRed = WhatsNewViewController.Configuration(
theme: .darkRed
)
// Apply predefined White Red Theme to Configuration
var configuration = WhatsNewViewController.Configuration()
configuration.apply(theme: .whiteRed)
// Or create your own Theme and initialize a Configuration with your Theme
let myTheme = WhatsNewViewController.Theme { configuration in
configuration.backgroundColor = .white
configuration.titleView.titleColor = .orange
configuration.itemsView.titleFont = .systemFont(ofSize: 17)
configuration.detailButton?.titleColor = .orange
configuration.completionButton.backgroundColor = .orange
// ...
}
// Initialize a Configuration with your Theme
let configuration = WhatsNewViewController.Configuration(
theme: myTheme
)
要全面了解可用的预定义主题,请查看示例应用程序。
iOS 13 深色模式
如果您希望预定义的主题如.darkRed
和.whiteRed
自动适应当前的用户界面样式,请使用.red
主题。
// Configuration with predefine `red` Theme which auto adapts to the UserInterfaceStyle
// in order to support iOS 13 Dark-Mode
let configuration = WhatsNewViewController.Configuration(
theme: .red
)
兼容深色模式的主题:.blue
、.lightBlue
、.orange
、.purple
、.red
、.green
📐
布局WhatsNewKit
包含三种预定义的 ItemsView.Layouts
。
左 | 居中 | 右 |
---|---|---|
![]() |
![]() |
![]() |
// Left Layout
configuration.itemsView.layout = .left
// Centered Layout
configuration.itemsView.layout = .centered
// Right Layout
configuration.itemsView.layout = .right
☝️ 默认情况下,ItemsView 布局设置为.left
。
📏
内容模式在 ItemsView
配置中设置 ContentMode
将调整沿轴排列您的高级功能的方式。
顶部 | 居中 | 填充 |
---|---|---|
![]() |
![]() |
![]() |
// ContentMode Top
configuration.itemsView.contentMode = .top
// ContentMode Center
configuration.itemsView.contentMode = .center
// ContentMode Fill
configuration.itemsView.contentMode = .fill
☝️ 默认情况下,ItemsView 内容模式设置为top
。
内边距
此外,如果您想修改 WhatsNewViewController
组件的布局内边距,可以这样做。
// Set TitleView Insets (Default values)
configuration.titleView.insets = UIEdgeInsets(top: 50, left: 20, bottom: 15, right: 20)
// Increase the CompletionButton Bottom Inset
configuration.completionButton.insets.bottom += 10
图像大小
为了为您的高级功能中的每个功能定义图像大小,您可以在 ItemsView
配置中设置 ImageSize。
// Use the original image size as it is
configuration.itemsView.imageSize = .original
// Use the preferred image size which fits perfectly :)
configuration.itemsView.imageSize = .preferred
// Use a custom height for each image
configuration.itemsView.imageSize = .fixed(height: 25)
☝️ 默认情况下,ItemsView 图像大小设置为preferred
。
图像着色-颜色
默认情况下,WhatsNewKit 会自动将给定配置的颜色着色到每个 WhatsNew.Item
的图像中。如果您想禁用此功能,只需将 autoTintImage
设置为 false
// Disable auto tinting images
configuration.itemsView.autoTintImage = false
☝️ 默认情况下,ItemsView 自动着色图像设置为true
。
🎬
动画
您可以通过预定义的动画类型,将动画应用于WhatsNewViewController
的 所有组件。默认情况下,所有动画属性都设置为 nil
,表示不应执行动画。
// Set SlideUp Animation to TitleView
configuration.titleView.animation = .slideUp
// Set SlideRight Animation to ItemsView
configuration.itemsView.animation = .slideRight
// Set SlideLeft Animation to DetailButton
configuration.detailButton?.animation = .slideLeft
// Set SlideDown Animation to CompletionButton
configuration.completionButton.animation = .slideDown
如果您想要将动画应用于具有相同类型的所有视图,只需将其应用于配置即可。
// Global Animation-Type for all WhatsNewViewController components
configuration.apply(animation: .fade)
如果您想自定义动画,请设置 custom
枚举并传递一个动画器闭包。
// Custom Animation for DetailButton
configuration.detailButton?.animation = .custom(animator: { (view: UIView, settings: AnimatorSettings) in
// view: The View to perform animation on
// settings: Preferred duration and delay
})
标题模式
默认情况下,TitleView 贴在顶部。如果希望 TitleView 和 ItemsView 一起滚动,可以在 TitleView 配置中更改 titleMode
。
// TitleView scrolls alongside with the ItemsView
configuration.titleView.titleMode = .scrolls
// TitleView is fixed to top
configuration.titleView.titleMode = .fixed
☝️ 默认情况下,titleMode 设置为.fixed
。
辅助标题颜色
通过在 TitleView 上设置 SecondaryColor ,可以更改某些字符的颜色。
// Set secondary color on TitleView Configuration
configuration.titleView.secondaryColor = .init(
// The start index
startIndex: 0,
// The length of characters
length: 5,
// The secondary color to apply
color: .whatsNewKitLightBlue
)
☝️ 默认情况下,secondaryColor 设置为nil
。
详细按钮
通过在 WhatsNewViewController.Configuration
结构中设置 DetailButton 结构,可以自定义 WhatsNewViewController
中显示的详细按钮的 title
和对应的 action
。由于 DetailButton
结构声明为可选的,只有当存在 DetailButton
配置时,WhatsNewViewController
才会显示按钮
动作 | 描述 |
---|---|
网站 |
当用户按下详细按钮时,将显示一个带有给定 URL 的 SFSafariViewController |
自定义 |
用户按下详细按钮后,将调用您的自定义操作 |
// Initialize DetailButton with title and open website at url
let detailButton = WhatsNewViewController.DetailButton(
title: "Read more",
action: .website(url: "https://github.com/SvenTiigi/WhatsNewKit")
)
// Initialize DetailButton with title and custom action
let detailButton = WhatsNewViewController.DetailButton(
title: "Read more",
action: .custom(action: { [weak self] whatsNewViewController in
// Perform custom action on detail button pressed
})
)
完成按钮
完成按钮结构体配置了显示的标题和用户在按下WhatsNewViewController
上的完成按钮时的操作。
动作 | 描述 |
---|---|
关闭 |
当用户按下完成按钮时,WhatsNewViewController 将会关闭。这是默认值。 |
自定义 |
用户按下完成按钮后,将调用您的自定义操作。 |
// Initialize CompletionButton with title and dismiss action
let completionButton = WhatsNewViewController.CompletionButton(
title: "Continue",
action: .dismiss
)
// Initialize CompletionButton with title and custom action
let completionButton = WhatsNewViewController.CompletionButton(
title: "Continue",
action: .custom(action: { [weak self] whatsNewViewController in
// Perform custom action on completion button pressed
})
)
📳
触觉反馈您可以在用户按下DetailButton
或CompletionButton
时,在这两个按钮上启用触觉反馈。通过设置属性或将其传递给初始化器来实现。
// Impact Feedback
button.hapticFeedback = .impact(.medium)
// Selection Feedback
button.hapticFeedback = .selection
// Notification Feedback with type
let completionButton = WhatsNewViewController.CompletionButton(
title: "Continue",
action: .dismiss,
hapticFeedback: .notification(.success)
)
☝️ 默认情况下,触觉反馈为nil
,表示不应执行触觉反馈。
iPad Adjustments
如果您希望在iPad上呈现WhatsNewViewController.Configuration
时修改它,可以设置padAdjustment
闭包。
// Set PadAdjustment closure
configuration.padAdjustment = { configuration in
// Adjust TitleView FontSize
configuration.titleView.titleFont = .systemFont(ofSize: 45, weight: .bold)
// Invoke default PadAdjustments (Adjusts Insets for iPad)
WhatsNewViewController.Configuration.defaultPadAdjustment(&configuration)
}
☝️ 默认情况下,将调用WhatsNewViewController.Configuration.defaultPadAdjustment
。
💾
WhatsNewVersionStore
当我们谈论展示令人惊叹的新应用程序功能时,我们必须注意,如果用户安装了应用程序或更新后打开它,此类UI
操作只发生一次。《WhatNewsKit》通过WhatNewsVersionStore协议提供面向协议的解决方案。
/// WhatsNewVersionStore typealias protocol composition
public typealias WhatsNewVersionStore = WriteableWhatsNewVersionStore & ReadableWhatsNewVersionStore
/// The WriteableWhatsNewVersionStore
public protocol WriteableWhatsNewVersionStore {
func set(version: WhatsNew.Version)
}
/// The ReadableWhatsNewVersionStore
public protocol ReadableWhatsNewVersionStore {
func has(version: WhatsNew.Version) -> Bool
}
WhatsNewViewController
将以以下方式使用WhatNewsVersionStore
的API。
API | 描述 |
---|---|
has(version:) |
检查WhatNews.Version 是否可用,并在初始化期间返回nil 。 |
set(version:) |
按下完成按钮后,将设置WhatNews.Version 。 |
WhatNewsVersionStore
可以作为参数传递给初始化器。如果这样做,初始化器将变为可选的。
// Initialize WhatsNewViewController with WhatsNewVersionStore
let whatsNewViewController: WhatsNewViewController? = WhatsNewViewController(
whatsNew: whatsNew,
versionStore: myVersionStore
)
// Check if WhatsNewViewController is available to present it.
if let controller = whatsNewViewController {
// Present it as WhatsNewViewController is available
// after init with WhatsNewVersionStore
self.present(controller, animated: true)
} else {
// WhatsNewViewController is `nil` this Version has already been presented
}
// Or invoke present on the WhatsNewViewController
// to avoid the need of unwrapping the optional
whatsNewViewController?.present(on: self)
☝️ 请注意,当您传递一个WhatsNewVersionStore
对象时,WhatsNewViewController
构造函数将变为可选并且会检查版本是否已经被展示。
实现
如果您已经在您的应用程序中将用户设置保存到了像 Realm
、CoreData
或 UserDefaults
这样的地方,您可以将其 conson 到 WhatsNewVersionStore
。
// Extend your existing App-Logic
extension MyUserSettingsDatabase: WhatsNewVersionStore {
// Implement me 👨💻
}
预定义实现
WhatsNewKit
提供 WhatsNewVersionStore
的两种预定义实现。
KeyValueWhatsNewVersionStore
KeyValueWhatsNewVersionStore 通过采用符合 KeyValueable
协议的对象来保存和检索 WhatsNew.Version
。已经符合该协议的例如 UserDefaults
和 NSUbiquitousKeyValueStore
。
// Local KeyValueStore
let keyValueVersionStore = KeyValueWhatsNewVersionStore(
keyValueable: UserDefaults.standard
)
// iCloud KeyValueStore
let keyValueVersionStore = KeyValueWhatsNewVersionStore(
keyValueable: NSUbiquitousKeyValueStore.default
)
// Initialize WhatsNewViewController with KeyValueWhatsNewVersionStore
let whatsNewViewController: WhatsNewViewController? = WhatsNewViewController(
whatsNew: whatsNew,
versionStore: keyValueVersionStore
)
InMemoryWhatsNewVersionStore
InMemoryWhatsNewVersionStore 在内存中保存和检索 WhatsNew.Version
。非常适合开发或测试阶段。
// Initialize WhatsNewViewController with InMemoryWhatsNewVersionStore
let whatsNewViewController: WhatsNewViewController? = WhatsNewViewController(
whatsNew: whatsNew,
versionStore: InMemoryWhatsNewVersionStore()
)
WhatsNew.Version
在初始化 WhatsNew
结构体时,WhatsNewKit
会自动通过 CFBundleShortVersionString 获取当前 App 版本,并为您构建一个 WhatsNew.Version,供 WhatsNewVersionStore
协议使用,以便持久化呈现的应用版本。如果您想手动设置版本,可以像以下示例那样操作。
// Initialize Version 1.0.0
let version = WhatsNew.Version(
major: 1,
minor: 0,
patch: 0
)
// Use a String literal
let version: WhatsNew.Version = "1.0.0"
// Current Version in Bundle (Default)
let version = WhatsNew.Version.current()
初始化一个 WhatsNew.Version
后,您可以将其传递给 WhatsNew
结构体的初始化器。
// Initialize WhatsNew with Title and Items
let whatsNew = WhatsNew(
version: version,
title: "WhatsNewKit",
items: []
)
如果您在一个数组中持有多个 WhatsNew
结构体,您可以利用以下两个函数根据 WhatsNewVersion
获取一个 WhatsNew
结构体。
let whatsNews: [WhatsNew] = [...]
// Retrieve WhatsNew from array based on Version 1.0.0
let whatsNewVersion1 = whatsNews.get(byVersion:
.init(major: 1, minor: 0, patch: 0)
)
// Or retrieve it via String as WhatsNew.Version is
// conform to the ExpressibleByStringLiteral protocol
let whatsNewVersion2 = whatsNews.get(byVersion: "2.0.0")
// If you want the WhatsNew for your current App-Version
// based on the CFBundleShortVersionString from Bundle.main
let currentWhatsNew = whatsNews.get()
Codable WhatsNew
WhatsNew
结构体符合 Codable
协议,这允许您通过 JSON
初始化 WhatsNew
结构体。
{
"version": {
"major": 1,
"minor": 0,
"patch": 0
},
"title": "WhatsNewKit",
"items": [
{
"title": "Open Source",
"subtitle": "Contributions are very welcome 👨💻",
"image": "iVBORw0KGgoA..."
}
]
}
WhatsNew.Item
的可选 image
属性将以 Base64 进行解码和编码。
// Encode to JSON
let encoded = try? JSONEncoder().encode(whatsNew)
// Decode from JSON data
let decoded = try? JSONDecoder().decode(WhatsNew.self, from: data)
Featured on
- Awesome iOS Weekly
- Swift Weekly
- AppCoda Weekly
- iOS Goodies
- MyBridge - Open Source Swift Projects (June 2018)
- The iOS Times
- DZone
- Brian Advent
- 过去一年内用 Swift 编写的 23 个惊人的 iOS UI 库(v.2019)
- Indie iOS Focus Weekly
- 5 个能激发你创造力的 iOS 库
Contributing
欢迎贡献力量
Credits
《What's New.Item》中的图片(icons8-github,icons8-puzzle,icons8-approval,icons8-picture)在截图和示例应用程序中可以看到,这些图片来自icons8.com,并受Creative Commons Attribution-NoDerivs 3.0 Unported协议许可。
授权协议
WhatsNewKit
Copyright (c) 2020 Sven Tiigi <[email protected]>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.