Segnify for iOS
一个优雅的、高性能且丰富的 Swift 组件。
功能
- 文本段:
TextSegment
- 图片段:
ImageSegment
- 段选择指示器:
Segnicator
- 基于
UIButton
、UIPageViewController
、UIScrollView
和UIStackView
的模块化组件 - 支持无限滚动
- 完全自定义,广泛使用不同、独立的协议
- 基于 Auto Layout 的大小和定位
- 100% 代码,0% Storyboard / XIB
要求
- iOS 10.3+
- Xcode 11.4+
- Swift 5.0+
安装
CocoaPods
CocoaPods 是 Cocoa 项目的依赖管理器。您可以使用以下命令进行安装
$ gem install cocoapods
要使用 CocoaPods 将 Segnify 集成到您的 Xcode 项目中,请在您的 Podfile
中指定它
platform :ios, '10.3'
use_frameworks!
target '<Your Target Name>' do
pod 'Segnify'
end
然后,运行以下命令
$ pod install
Carthage
Carthage 是一个去中心化的依赖管理器,它可以构建您的依赖并为您提供二进制框架。
您可以使用以下命令通过 Homebrew 安装 Carthage
$ brew update
$ brew install carthage
要使用 Carthage 将 Segnify 集成到您的 Xcode 项目中,请在您的 Cartfile
中指定它
github "nedap/segnify-ios" ~> 1.1.5
运行 carthage bootstrap
命令构建框架,并将构建好的 Segnify.framework
拖动到您的 Xcode 项目中。
使用方法
通用
-
使用
Segnify
的开始是创建一个PageViewController
实例。PageViewController
是主要类,它代表一个视图控制器,其中包含一个Segnify
实例和一个UIPageViewController
实例。 -
Segnify
实例表示可用于由用户独立选择的不同的Segment
实例。选择一个Segment
实例将触发UIPageViewController
实例,它将相应地显示对应的内容。当用户左右滑动UIPageViewController
实例显示的内容时,Segnify
实例也将相应地作出反应。 -
Segnicator
实例表示位于上方的透明视图,用于直观地指示当前选择的Segment
实例。'Segnicator' 基于指示器,因此得名并执行相应的功能。Segnicator
实例始终位于当前选择的Segment
实例之上。通过向Segnicator
实例添加一个或多个您喜欢的子视图并将其自动布局约束相应地添加,可以完全自定义视觉指示器。
默认值
各种协议默认通过默认代理实现,可在默认文件夹中找到。以下代理正在使用中:
- DefaultImageSegmentDelegate
- DefaultPageViewControllerDelegate
- DefaultSegnicatorDelegate
- DefaultSegnifyDataSourceDelegate
- DefaultSegnifyDelegate
- DefaultTextSegmentDelegate
利用Segnify
的最简单方法是
import Segnify
public class MainViewController: PageViewController {}
仅通过继承它而 不修改任何内容,或通过初始化一个新的PageViewController
实例并将其添加为子视图控制器,将选择默认实现,并添加三个TextSegment
实例,以及三个随机生成的UIViewController
实例。
自定义示例
除了Segnify
框架目标外,项目文件中还有一个名为Segnified
的应用目标。通过运行Segnified
方案,将运行一个示例应用程序,该应用程序展示了Segnify
的所有定制可能性。
示例应用的MainViewController
如下所示
import Segnify
public class MainViewController: PageViewController {
// MARK: - Private delegates
private var content = [SegnifyContentElement]()
private lazy var imageSegmentDelegate = ImageSegmentDelegate()
private lazy var pageViewControllerDelegate = PageViewControllerDelegate()
private lazy var segnicatorDelegate = SegnicatorDelegate()
private lazy var segnifyDelegate = SegnifyDelegate()
private lazy var textSegmentDelegate = TextSegmentDelegate()
// MARK: - Lifecycle
public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
setup()
}
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
// MARK: - Setup
private func setup() {
// Customize.
do {
try setDataSource(self)
delegate = pageViewControllerDelegate
segnify.delegate = segnifyDelegate
segnify.segnicator = Segnicator(configuration: segnicatorDelegate)
}
catch {
// Fail.
print("Failed to set the data source. Make sure it isn't nil.")
}
}
}
// MARK: - SegnifyDataSourceProtocol
extension MainViewController: SegnifyDataSourceProtocol {
public var contentElements: [SegnifyContentElement] {
if content.isEmpty {
content = [
(segment: ImageSegment(image: UIImage(named: "demo_number_1_icon"), configuration: imageSegmentDelegate),
viewController: PageViewContentViewController(text: "Hey you! This is number 1.")),
(segment: TextSegment(text: "Number 2", configuration: textSegmentDelegate),
viewController: PageViewContentViewController(text: "This is number 2 indeed.")),
(segment: ImageSegment(image: UIImage(named: "demo_number_3_icon"), configuration: imageSegmentDelegate),
viewController: PageViewContentViewController(text: "Ola! Si si, 3 it is.")),
(segment: TextSegment(text: "Numéro 4", configuration: textSegmentDelegate),
viewController: PageViewContentViewController(text: "Oh man, number 4 already.")),
(segment: TextSegment(text: "5 💁🏼♂️", configuration: textSegmentDelegate),
viewController: PageViewContentViewController(text: "Number 5 is being shown."))
]
}
return content
}
}
请参阅Segnified文件夹以获取所有详细信息。
协议
为了定制目的,您可能需要实现以下协议之一。
转发事件协议
实现ForwardedEventsProtocol
,以便了解由Segnify
实例或UIPageViewController
实例引起的多个事件。
- 获取当前显示视图控制器之前的视图控制器
- 获取当前显示视图控制器之后的视图控制器
- 由手势触发的过渡触发器
- 段选择触发器
该协议部分依赖于UIPageViewControllerDataSource
和UIPageViewControllerDelegate
协议。所有协议方法都是可选的。
ImageSegmentProtocol
实现ImageSegmentProtocol
以自定义图像段。以下示例显示了DefaultImageSegmentDelegate中的默认实现。
public class DefaultImageSegmentDelegate: ImageSegmentProtocol {
// MARK: - Delegate
public func backgroundColor(for state: UIControl.State) -> UIColor {
switch state {
case .highlighted, .selected, [.selected, .highlighted]:
return .init(red: 39.0/255.0, green: 59.0/255.0, blue: 66.0/255.0, alpha: 1.0)
default:
return .clear
}
}
}
PageViewControllerProtocol
实现PageViewControllerProtocol
以可视方式自定义PageViewController
实例。以下示例显示了DefaultPageViewControllerDelegate中的默认实现。
public class DefaultPageViewControllerDelegate: PageViewControllerProtocol {
// MARK: - Delegate
public var backgroundColor: UIColor {
return .black
}
public var segnifyHeight: CGFloat {
return 75.0
}
}
SegnicatorProtocol
实现SegnicatorProtocol
以可视方式自定义Segnicator
实例。以下示例显示了DefaultSegnicatorDelegate中的默认实现。
创建并添加了一条白色水平线作为子视图。使用SegnifyLayoutConstraint
扩展应用了自动布局约束。
public class DefaultSegnicatorDelegate: SegnicatorProtocol {
// MARK: - Delegate
public var segnicatorView: UIView {
// Create a white, half-transparent background view.
let backgroundView = UIView()
backgroundView.backgroundColor = .clear
// Create a white, horizontal indicator view.
let whiteIndicatorView = UIView()
whiteIndicatorView.backgroundColor = .white
// Add it to the segnicator and give it the correct layout.
backgroundView.addSubview(whiteIndicatorView)
NSLayoutConstraint.activate([
whiteIndicatorView.leadingAnchor.constraint(equalTo: backgroundView.leadingAnchor),
whiteIndicatorView.bottomAnchor.constraint(equalTo: backgroundView.bottomAnchor),
whiteIndicatorView.trailingAnchor.constraint(equalTo: backgroundView.trailingAnchor),
whiteIndicatorView.heightAnchor.constraint(equalToConstant: 2.0)
], for: whiteIndicatorView)
return backgroundView
}
}
SegnifyDataSourceProtocol
实现SegnifyDataSourceProtocol
以定义Segnify
实例和UIPageViewController
实例的数据源。应该使用一个或多个SegnifyContentElement
元素,它是一个元组,表示一个Segment
实例和一个UIViewController
实例。
以下示例显示了DefaultSegnifyDataSourceDelegate中的默认实现。
public class DefaultSegnifyDataSourceDelegate: SegnifyDataSourceProtocol {
// MARK: - Private
/// Define an instance of `DefaultTextSegmentDelegate`.
private lazy var textSegmentDelegate: TextSegmentProtocol = {
return DefaultTextSegmentDelegate()
}()
/// Generate a new UIViewController instance with a random background color.
private func generateViewController() -> UIViewController {
let viewController = UIViewController()
viewController.view.backgroundColor = UIColor(white: .random(in: 0.0 ... 1.0), alpha: 1.0)
return viewController
}
/// The collection of segment-viewcontroller-tuples, used by the `Segnify` instance.
private lazy var content: [SegnifyContentElement] = {
return [(segment: TextSegment(text: "Segment 1", configuration: textSegmentDelegate),
viewController: generateViewController()),
(segment: TextSegment(text: "Segment 2", configuration: textSegmentDelegate),
viewController: generateViewController()),
(segment: TextSegment(text: "Segment 3", configuration: textSegmentDelegate),
viewController: generateViewController())]
}()
// MARK: - Delegate
public var contentElements: [SegnifyContentElement] {
return content
}
}
SegnifyProtocol
实现 SegnifyProtocol
以视觉定制 Segnify
实例。以下示例展示了 DefaultSegnifyDelegate 中的默认实现。
public class DefaultSegnifyDelegate: SegnifyProtocol {
// MARK: - Delegate
public var backgroundColor: UIColor {
return .init(red: 76.0/255.0, green: 114.0/255.0, blue: 128.0/255.0, alpha: 1.0)
}
public var isEquallyFillingHorizontalSpace: Bool {
return true
}
public var segmentWidth: CGFloat {
return 150.0
}
}
TextSegment
实现 TextSegmentProtocol
来自定义文本片段。以下示例展示了 DefaultTextSegmentDelegate 中的默认实现。
public class DefaultTextSegmentDelegate: TextSegmentProtocol {
// MARK: - Delegate
public func backgroundColor(for state: UIControl.State) -> UIColor {
switch state {
case .highlighted, .selected, [.selected, .highlighted]:
return .init(red: 39.0/255.0, green: 59.0/255.0, blue: 66.0/255.0, alpha: 1.0)
default:
return .clear
}
}
public var font: UIFont {
return .systemFont(ofSize: 17.0)
}
public func textColor(for state: UIControl.State) -> UIColor {
switch state {
case .highlighted, .selected:
return .lightGray
default:
return .white
}
}
}
许可协议
版权所有 © 2020 Nederlandsche Apparatenfabriek (Nedap) N.V. 保留所有权利。
有关更多信息,请参阅 LICENSE 文件。
变更日志
请参阅 CHANGELOG 文件。