Compare commits

..

13 Commits
master ... dev

Author SHA1 Message Date
shenlei
68d9363f0a feat: optimize reader caching and document formats 2026-07-20 17:22:06 +09:00
shen
52f803e8db fix: restore demo build and drawing interactions 2026-07-15 21:13:05 +08:00
shenlei
1422461224 将 PDF 成品阅读控制器下沉为 RDPDFReaderView SDK,并修复手机横屏单页连续竖滑
SDK 化收尾:
- 新增 RDPDFReaderView 本地 pod(阅读容器、成品控制器、划线/注释、画笔、
  目录/设置面板、主题与持久化契约),Demo 精简为 PDFKit 页面提供者 + 持久化宿主
- Podfile/工程接入 RDPDFReaderView 与 SnapKit,示例书改用 PDF 阅读器示例文件

手机横屏单页竖滑修复:
- cell 高度改为宽度适配后的纸张高度(sizeForItemAt + 宿主按页提供纵横比),
  纵向超出一屏的内容由外层 collectionView 连续滚动承接,不再被裁掉
- 页面内部不再开启同向嵌套的兜底竖向拖动,修复外层滚动被吞、无法滚到下一页
- 修复 applyContentSize 先评估拖动开关后写 contentSize 的顺序缺陷
- 页码按视口中心命中 cell 计算,补 didEndDragging 兜底;旋转重锚点与
  transitionToPage 改用真实布局位置
- 横竖屏同为竖滑时也重建 cell 并刷新全部可见页的适配配置
- 横屏单页点击不再跳页,只显隐工具栏;翻页交给连续竖滑

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 18:49:44 +09:00
shenlei
a17164d1a9 将 PDF 注释编辑器、笔记列表、目录/设置面板与面板呈现下沉到 SDK
SDK 新增:
- RDPDFReaderAnnotationEditorViewController:注释输入页(UI 与 EPUB 编辑器一致)
- RDPDFReaderAnnotationListViewController:笔记列表(全部/注释/高亮筛选、滑动删除)
- RDPDFReaderNavigationPanelViewController:目录/书签/缩略图面板容器
- RDPDFReaderSettingsPanelViewController:亮度/翻页方式/主题设置面板
- RDPDFReaderPanelPresenter + 转场/呈现控制器:底部面板统一呈现,
  转场代理生命周期由被呈现控制器持有,宿主无需保存引用
- RDPDFReaderThemeOption:SDK 自有主题模型,面板与编辑器不再依赖 EPUB 主题类型
- UIColor(rdPDFHexString:) 公开,并消除覆盖层内的私有重复实现

Demo 侧:
- 删除 PDFDemoAnnotationUI.swift 整个文件
- 删除 PDFDemoNavigationViewController / PDFDemoSettingsViewController /
  面板转场三个类(约 410 行),改为调用 SDK 组件
- ThemePreset 增加到 RDPDFReaderThemeOption 的映射

无障碍标识全部保留,UI 自动化不受影响。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 10:51:51 +09:00
shenlei
1bde945d36 将 PDF 划线/注释交互完整下沉到 SDK 库
- RDPDFReaderPageView:完整页面视图移入 SDK(缩放画布、文字选择层、
  选区放大镜、无障碍视口),并内置与 EPUB 一致的两套系统编辑菜单:
  选区菜单(复制/划线/注释)、已有划线菜单(复制/注释|删除注释/删除划线)
- RDPDFReaderPageViewDelegate:宿主只通过代理做数据持久化与打开业务界面
- 修复划线命中判定:点击点先归一化再与标注比例坐标比较
- 修复 tappedHighlight 残留导致选区菜单项被错误过滤的问题
- 主题应用改为纯颜色入参,SDK 不依赖 EPUB 主题类型
- RDPDFReaderHighlightOverlayView 恢复为纯绘制层,点击交互统一由页面视图处理
- Demo 删除 PDFDemoPageView(约 290 行),改为实现代理回调

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 10:33:43 +09:00
shenlei
5a19cfde14 refactor: move highlight menu logic from Demo to SDK library
Add RDPDFReaderPageView as base page view class in SDK:
- Handles all highlight menu interactions and display
- Provides RDPDFReaderPageViewDelegate for menu action callbacks
- Unifies with EPUB architecture: RDEPUBTextContentView pattern
- Reduces code duplication for applications using the SDK

Benefits:
- Reusable menu interaction logic across all PDF apps
- Consistent architecture with EPUB reader
- Single responsibility principle (UI in library, persistence in app)
- Backward compatible (existing code continues to work)

Applications now implement RDPDFReaderPageViewDelegate to:
- Respond to highlight menu actions
- Handle data persistence
- Refresh UI after changes

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-15 10:19:54 +09:00
shenlei
7c16647306 fix: remove duplicate canPerformAction method and merge with existing implementation
- Keep single canPerformAction method that handles both text selection menu and highlight menu
- Check tappedHighlight first, then fall back to text selection logic
- Resolves method override conflict

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-15 10:16:30 +09:00
shenlei
d56e99a83f add tap-on-highlight menu with copy/annotate/delete actions, matching EPUB behavior
- Add RDPDFReaderAnnotationMenuAction and RDPDFReaderExistingHighlightMenuAction enums to PDF contracts
- Enable highlight overlay view to detect tap gestures and report tapped highlights
- Implement existing highlight menu in Demo page: copy text, add/edit annotation, delete annotation, delete underline
- Handle menu actions in PDFDemoReaderViewController to persist changes
- Ensure highlight tap detection doesn't interfere with text selection

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-15 10:06:02 +09:00
shenlei
fed34da246 unify PDF and EPUB reader: convert highlights to underlines, improve annotation UI, change paging from horizontal to vertical
- Convert PDF highlights from filled rectangles to underlines matching EPUB style
- Update PDF annotation editor with EPUB-style design: gold sidebar rail, semi-transparent background, improved spacing and shadows, dark mode support
- Change PDF page-curl paging from left-right horizontal to up-down vertical: update gesture recognition and tap regions accordingly

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-15 10:01:23 +09:00
shenlei
72c1f8d89c 扩展顶部工具栏业务按钮能力 2026-07-13 16:16:31 +09:00
shenlei
822949f6cc 清理重复 Podfile 配置 2026-07-13 16:09:45 +09:00
shenlei
6a0a1223b1 完善阅读器主题与批注界面 2026-07-13 13:01:14 +09:00
shenlei
adc24d3f36 fix: preserve images in dark reader theme 2026-07-13 12:30:14 +09:00
397 changed files with 16673 additions and 5706 deletions

16
.gitignore vendored
View File

@ -6,15 +6,24 @@ xcuserdata/
.artifacts/ .artifacts/
.deriveddata/ .deriveddata/
.swift-module-cache/ .swift-module-cache/
ReadViewDemo/build/
# This repository checks in the Demo Pods project. Keep generated files for the # This repository checks in the Demo Pods project. Keep generated files for the
# local RDEpubReaderView pod visible even when a global gitignore excludes Pods. # local RDEpubReaderView/RDPDFReaderView pods and vendored SnapKit visible even
# when a global gitignore excludes Pods.
!ReadViewDemo/Pods/ !ReadViewDemo/Pods/
!ReadViewDemo/Pods/Local Podspecs/ !ReadViewDemo/Pods/Local Podspecs/
!ReadViewDemo/Pods/Local Podspecs/RDEpubReaderView.podspec.json !ReadViewDemo/Pods/Local Podspecs/RDEpubReaderView.podspec.json
!ReadViewDemo/Pods/Local Podspecs/RDPDFReaderView.podspec.json
!ReadViewDemo/Pods/Target Support Files/ !ReadViewDemo/Pods/Target Support Files/
!ReadViewDemo/Pods/Target Support Files/RDEpubReaderView/ !ReadViewDemo/Pods/Target Support Files/RDEpubReaderView/
!ReadViewDemo/Pods/Target Support Files/RDEpubReaderView/** !ReadViewDemo/Pods/Target Support Files/RDEpubReaderView/**
!ReadViewDemo/Pods/Target Support Files/RDPDFReaderView/
!ReadViewDemo/Pods/Target Support Files/RDPDFReaderView/**
!ReadViewDemo/Pods/SnapKit/
!ReadViewDemo/Pods/SnapKit/**
!ReadViewDemo/Pods/Target Support Files/SnapKit/
!ReadViewDemo/Pods/Target Support Files/SnapKit/**
# macOS system files # macOS system files
.DS_Store .DS_Store
@ -24,3 +33,8 @@ xcuserdata/
# AI tool output # AI tool output
_ssoft-output/ _ssoft-output/
.claude/
# Python bytecode
__pycache__/
*.py[cod]

View File

@ -7,8 +7,8 @@
## 语言与工程约束 ## 语言与工程约束
- **主要语言**SwiftPodspec 声明 `s.swift_versions = ["5.10"]`,见 `RDEpubReaderView.podspec` - **主要语言**SwiftPodspec 声明 `s.swift_versions = ["5.10"]`,见 `RDEpubReaderView.podspec`
- **最低系统版本**Podspec `iOS 15.0``RDEpubReaderView.podspec`),示例工程 Podfile/构建设置里常见为 `iOS 15.6``Podfile` - **最低系统版本**Podspec `iOS 15.0``RDEpubReaderView.podspec`),示例工程 Podfile/构建设置里常见为 `iOS 15.6``ReadViewDemo/Podfile`
- **依赖管理**CocoaPods`Podfile`、`ReadViewDemo/Podfile`、`Podfile.lock` - **依赖管理**CocoaPods`ReadViewDemo/Podfile`、`ReadViewDemo/Podfile.lock`
## 命名约定 ## 命名约定
@ -76,7 +76,7 @@
## Evidence关键证据文件 ## Evidence关键证据文件
- `CONTEXT.md` - `CONTEXT.md`
- `Podfile` - `ReadViewDemo/Podfile`
- `RDEpubReaderView.podspec` - `RDEpubReaderView.podspec`
- `ReadViewDemo/ReadViewDemo/ViewController.swift` - `ReadViewDemo/ReadViewDemo/ViewController.swift`
- `Sources/RDEpubReaderView/ReaderView/RDEpubReaderView.swift` - `Sources/RDEpubReaderView/ReaderView/RDEpubReaderView.swift`

View File

@ -64,13 +64,13 @@
### CocoaPods 依赖准备 ### CocoaPods 依赖准备
> 仓库包含示例工程 `ReadViewDemo`,并已提交 `Pods/` 与 `Podfile.lock`。如本地环境未同步,可在仓库根或示例工程目录运行: > 仓库包含示例工程 `ReadViewDemo`,并已提交 `ReadViewDemo/Pods/` 与 `ReadViewDemo/Podfile.lock`。如本地环境未同步,请在示例工程目录运行:
```bash ```bash
pod install cd ReadViewDemo && pod install
``` ```
(依赖入口:`Podfile`、`ReadViewDemo/Podfile` (依赖入口:`ReadViewDemo/Podfile`
### 运行 UI 测试 ### 运行 UI 测试

30
Podfile
View File

@ -1,30 +0,0 @@
platform :ios, '15.6'
use_frameworks!
workspace 'ReadViewSDK.xcworkspace'
project 'ReadViewSDK.xcodeproj'
target 'ReadViewSDK' do
pod 'RDEpubReaderView', :path => '..'
end
post_install do |installer|
apply_settings = lambda do |config|
config.build_settings['ENABLE_USER_SCRIPT_SANDBOXING'] = 'NO'
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.6'
end
# Pods project (Pods.xcodeproj)
installer.pods_project.build_configurations.each { |c| apply_settings.call(c) }
installer.pods_project.targets.each { |t| t.build_configurations.each { |c| apply_settings.call(c) } }
installer.aggregate_targets.each do |at|
p = at.user_project
next unless p
# User project(s) that integrate Pods (e.g. ReadViewDemo / ReadViewSDK)
p.build_configurations.each { |c| apply_settings.call(c) }
p.targets.each { |t| t.build_configurations.each { |c| apply_settings.call(c) } }
p.save
end
end

View File

@ -3,7 +3,8 @@ platform :ios, '15.6'
target 'ReadViewDemo' do target 'ReadViewDemo' do
# Comment the next line if you don't want to use dynamic frameworks # Comment the next line if you don't want to use dynamic frameworks
use_frameworks! use_frameworks!
pod 'RDEpubReaderView', :path => '..' pod 'RDEpubReaderView', :path => '../Sources/RDEpubReaderView'
pod 'RDPDFReaderView', :path => '../Sources/RDPDFReaderView'
end end

View File

@ -16,30 +16,40 @@ PODS:
- DTFoundation/Core - DTFoundation/Core
- DTFoundation/UIKit (1.7.19): - DTFoundation/UIKit (1.7.19):
- DTFoundation/Core - DTFoundation/Core
- RDEpubReaderView (0.0.1): - RDEpubReaderView (0.0.2):
- DTCoreText (~> 1.6) - DTCoreText (~> 1.6)
- SnapKit (~> 5.7)
- ZIPFoundation (~> 0.9) - ZIPFoundation (~> 0.9)
- RDPDFReaderView (0.0.1):
- SnapKit (~> 5.7)
- SnapKit (5.7.1)
- ZIPFoundation (0.9.20) - ZIPFoundation (0.9.20)
DEPENDENCIES: DEPENDENCIES:
- RDEpubReaderView (from `..`) - RDEpubReaderView (from `../Sources/RDEpubReaderView`)
- RDPDFReaderView (from `../Sources/RDPDFReaderView`)
SPEC REPOS: SPEC REPOS:
trunk: trunk:
- DTCoreText - DTCoreText
- DTFoundation - DTFoundation
- SnapKit
- ZIPFoundation - ZIPFoundation
EXTERNAL SOURCES: EXTERNAL SOURCES:
RDEpubReaderView: RDEpubReaderView:
:path: ".." :path: "../Sources/RDEpubReaderView"
RDPDFReaderView:
:path: "../Sources/RDPDFReaderView"
SPEC CHECKSUMS: SPEC CHECKSUMS:
DTCoreText: 11b7fe2104f476f82e75a4e3dbdde74d7186cecb DTCoreText: 11b7fe2104f476f82e75a4e3dbdde74d7186cecb
DTFoundation: 76b624967cf5bcaae6bb057d622c536c36ef36d0 DTFoundation: 76b624967cf5bcaae6bb057d622c536c36ef36d0
RDEpubReaderView: 5ff99b803f5a46e5ff4ebef3024dd217284c69ed RDEpubReaderView: 5a09a7856f04b6f2f8610aa6fd965d35cadb8e17
RDPDFReaderView: f7c2d0ea7c129aa4ab15ae7f9daad2974573d749
SnapKit: d612e99e678a2d3b95bf60b0705ed0a35c03484a
ZIPFoundation: dfd3d681c4053ff7e2f7350bc4e53b5dba3f5351 ZIPFoundation: dfd3d681c4053ff7e2f7350bc4e53b5dba3f5351
PODFILE CHECKSUM: adda84af3e8577b2a99d5b2cecf381511352f0bd PODFILE CHECKSUM: c39db27dbc9c6a96a33f22e78ce1b22dcd48d75f
COCOAPODS: 1.16.2 COCOAPODS: 1.16.2

View File

@ -1,8 +1,8 @@
{ {
"name": "RDEpubReaderView", "name": "RDEpubReaderView",
"module_name": "RDEpubReaderView", "module_name": "RDEpubReaderView",
"version": "0.0.1", "version": "0.0.2",
"summary": "A reader view for EPUB and plain-text books", "summary": "A reader view for EPUB, TXT, MOBI, and CBZ books",
"platforms": { "platforms": {
"ios": "15.0" "ios": "15.0"
}, },
@ -15,13 +15,13 @@
}, },
"source": { "source": {
"git": "http://192.168.21.200:8418/4v5u09Z5a4Yuc/ReadViewSDK.git", "git": "http://192.168.21.200:8418/4v5u09Z5a4Yuc/ReadViewSDK.git",
"tag": "0.0.1" "tag": "0.0.2"
}, },
"license": "MIT", "license": "MIT",
"source_files": "Sources/RDEpubReaderView/**/*.{swift}", "source_files": "**/*.swift",
"resource_bundles": { "resource_bundles": {
"RDEpubReaderViewAssets": [ "RDEpubReaderViewAssets": [
"Sources/RDEpubReaderView/EPUBCore/Resources/**/*" "EPUBCore/Resources/**/*"
] ]
}, },
"dependencies": { "dependencies": {
@ -30,6 +30,9 @@
], ],
"DTCoreText": [ "DTCoreText": [
"~> 1.6" "~> 1.6"
],
"SnapKit": [
"~> 5.7"
] ]
}, },
"requires_arc": true, "requires_arc": true,

View File

@ -0,0 +1,33 @@
{
"name": "RDPDFReaderView",
"module_name": "RDPDFReaderView",
"version": "0.0.1",
"summary": "UIKit PDF reader supporting host images and direct PDFKit parsing",
"platforms": {
"ios": "15.0"
},
"swift_versions": [
"5.10"
],
"homepage": "https://example.invalid/RDPDFReaderView",
"authors": {
"readoor": "ios@touchread.com"
},
"source": {
"path": "."
},
"license": "MIT",
"source_files": "{Sources,ReaderView}/**/*.swift",
"dependencies": {
"SnapKit": [
"~> 5.7"
]
},
"frameworks": [
"Vision",
"CoreImage",
"PDFKit"
],
"requires_arc": true,
"swift_version": "5.10"
}

View File

@ -16,30 +16,40 @@ PODS:
- DTFoundation/Core - DTFoundation/Core
- DTFoundation/UIKit (1.7.19): - DTFoundation/UIKit (1.7.19):
- DTFoundation/Core - DTFoundation/Core
- RDEpubReaderView (0.0.1): - RDEpubReaderView (0.0.2):
- DTCoreText (~> 1.6) - DTCoreText (~> 1.6)
- SnapKit (~> 5.7)
- ZIPFoundation (~> 0.9) - ZIPFoundation (~> 0.9)
- RDPDFReaderView (0.0.1):
- SnapKit (~> 5.7)
- SnapKit (5.7.1)
- ZIPFoundation (0.9.20) - ZIPFoundation (0.9.20)
DEPENDENCIES: DEPENDENCIES:
- RDEpubReaderView (from `..`) - RDEpubReaderView (from `../Sources/RDEpubReaderView`)
- RDPDFReaderView (from `../Sources/RDPDFReaderView`)
SPEC REPOS: SPEC REPOS:
trunk: trunk:
- DTCoreText - DTCoreText
- DTFoundation - DTFoundation
- SnapKit
- ZIPFoundation - ZIPFoundation
EXTERNAL SOURCES: EXTERNAL SOURCES:
RDEpubReaderView: RDEpubReaderView:
:path: ".." :path: "../Sources/RDEpubReaderView"
RDPDFReaderView:
:path: "../Sources/RDPDFReaderView"
SPEC CHECKSUMS: SPEC CHECKSUMS:
DTCoreText: 11b7fe2104f476f82e75a4e3dbdde74d7186cecb DTCoreText: 11b7fe2104f476f82e75a4e3dbdde74d7186cecb
DTFoundation: 76b624967cf5bcaae6bb057d622c536c36ef36d0 DTFoundation: 76b624967cf5bcaae6bb057d622c536c36ef36d0
RDEpubReaderView: 5ff99b803f5a46e5ff4ebef3024dd217284c69ed RDEpubReaderView: 5a09a7856f04b6f2f8610aa6fd965d35cadb8e17
RDPDFReaderView: f7c2d0ea7c129aa4ab15ae7f9daad2974573d749
SnapKit: d612e99e678a2d3b95bf60b0705ed0a35c03484a
ZIPFoundation: dfd3d681c4053ff7e2f7350bc4e53b5dba3f5351 ZIPFoundation: dfd3d681c4053ff7e2f7350bc4e53b5dba3f5351
PODFILE CHECKSUM: adda84af3e8577b2a99d5b2cecf381511352f0bd PODFILE CHECKSUM: c39db27dbc9c6a96a33f22e78ce1b22dcd48d75f
COCOAPODS: 1.16.2 COCOAPODS: 1.16.2

File diff suppressed because it is too large Load Diff

19
ReadViewDemo/Pods/SnapKit/LICENSE generated Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
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.

155
ReadViewDemo/Pods/SnapKit/README.md generated Normal file
View File

@ -0,0 +1,155 @@
<img src="https://snapkit.github.io/SnapKit/images/banner.jpg" alt="" />
SnapKit is a DSL to make Auto Layout easy on both iOS and OS X.
[![Build Status](https://travis-ci.org/SnapKit/SnapKit.svg)](https://travis-ci.org/SnapKit/SnapKit)
[![Platform](https://img.shields.io/cocoapods/p/SnapKit.svg?style=flat)](https://github.com/SnapKit/SnapKit)
[![Cocoapods Compatible](https://img.shields.io/cocoapods/v/SnapKit.svg)](https://cocoapods.org/pods/SnapKit)
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
#### ⚠️ **To use with Swift 4.x please ensure you are using >= 4.0.0** ⚠️
#### ⚠️ **To use with Swift 5.x please ensure you are using >= 5.0.0** ⚠️
## Contents
- [Requirements](#requirements)
- [Migration Guides](#migration-guides)
- [Communication](#communication)
- [Installation](#installation)
- [Usage](#usage)
- [Credits](#credits)
- [License](#license)
## Requirements
- iOS 12.0+ / Mac OS X 10.13+ / tvOS 10.0+
- Xcode 10.0+
- Swift 4.0+
## Migration Guides
- [SnapKit 3.0 Migration Guide](Documentation/SnapKit%203.0%20Migration%20Guide.md)
## Communication
- If you **need help**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/snapkit). (Tag 'snapkit')
- If you'd like to **ask a general question**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/snapkit).
- If you **found a bug**, open an issue.
- If you **have a feature request**, open an issue.
- If you **want to contribute**, submit a pull request.
## Installation
### CocoaPods
[CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects. You can install it with the following command:
```bash
$ gem install cocoapods
```
> CocoaPods 1.1.0+ is required to build SnapKit 4.0.0+.
To integrate SnapKit into your Xcode project using CocoaPods, specify it in your `Podfile`:
```ruby
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '10.0'
use_frameworks!
target '<Your Target Name>' do
pod 'SnapKit', '~> 5.7.0'
end
```
Then, run the following command:
```bash
$ pod install
```
### Carthage
[Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.
You can install Carthage with [Homebrew](http://brew.sh/) using the following command:
```bash
$ brew update
$ brew install carthage
```
To integrate SnapKit into your Xcode project using Carthage, specify it in your `Cartfile`:
```ogdl
github "SnapKit/SnapKit" ~> 5.0.0
```
Run `carthage update` to build the framework and drag the built `SnapKit.framework` into your Xcode project.
### Swift Package Manager
[Swift Package Manager](https://swift.org/package-manager/) is a tool for managing the distribution of Swift code. Its integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies.
> Xcode 11+ is required to build SnapKit using Swift Package Manager.
To integrate SnapKit into your Xcode project using Swift Package Manager, add it to the dependencies value of your `Package.swift`:
```swift
dependencies: [
.package(url: "https://github.com/SnapKit/SnapKit.git", .upToNextMajor(from: "5.0.1"))
]
```
### Manually
If you prefer not to use either of the aforementioned dependency managers, you can integrate SnapKit into your project manually.
---
## Usage
### Quick Start
```swift
import SnapKit
class MyViewController: UIViewController {
lazy var box = UIView()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(box)
box.backgroundColor = .green
box.snp.makeConstraints { (make) -> Void in
make.width.height.equalTo(50)
make.center.equalTo(self.view)
}
}
}
```
### Playground
You can try SnapKit in Playground.
**Note:**
> To try SnapKit in playground, open `SnapKit.xcworkspace` and build SnapKit.framework for any simulator first.
### Resources
- [Documentation](https://snapkit.github.io/SnapKit/docs/)
- [F.A.Q.](https://snapkit.github.io/SnapKit/faq/)
## Credits
- Robert Payne ([@robertjpayne](https://twitter.com/robertjpayne))
- Many other contributors
## License
SnapKit is released under the MIT license. See LICENSE for details.

View File

@ -0,0 +1,341 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
public final class Constraint {
internal let sourceLocation: (String, UInt)
internal let label: String?
private let from: ConstraintItem
private let to: ConstraintItem
private let relation: ConstraintRelation
private let multiplier: ConstraintMultiplierTarget
private var constant: ConstraintConstantTarget {
didSet {
self.updateConstantAndPriorityIfNeeded()
}
}
private var priority: ConstraintPriorityTarget {
didSet {
self.updateConstantAndPriorityIfNeeded()
}
}
public var layoutConstraints: [LayoutConstraint]
public var isActive: Bool {
set {
if newValue {
activate()
}
else {
deactivate()
}
}
get {
for layoutConstraint in self.layoutConstraints {
if layoutConstraint.isActive {
return true
}
}
return false
}
}
// MARK: Initialization
internal init(from: ConstraintItem,
to: ConstraintItem,
relation: ConstraintRelation,
sourceLocation: (String, UInt),
label: String?,
multiplier: ConstraintMultiplierTarget,
constant: ConstraintConstantTarget,
priority: ConstraintPriorityTarget) {
self.from = from
self.to = to
self.relation = relation
self.sourceLocation = sourceLocation
self.label = label
self.multiplier = multiplier
self.constant = constant
self.priority = priority
self.layoutConstraints = []
// get attributes
let layoutFromAttributes = self.from.attributes.layoutAttributes
let layoutToAttributes = self.to.attributes.layoutAttributes
// get layout from
let layoutFrom = self.from.layoutConstraintItem!
// get relation
let layoutRelation = self.relation.layoutRelation
for layoutFromAttribute in layoutFromAttributes {
// get layout to attribute
let layoutToAttribute: LayoutAttribute
#if canImport(UIKit)
if layoutToAttributes.count > 0 {
if self.from.attributes == .edges && self.to.attributes == .margins {
switch layoutFromAttribute {
case .left:
layoutToAttribute = .leftMargin
case .right:
layoutToAttribute = .rightMargin
case .top:
layoutToAttribute = .topMargin
case .bottom:
layoutToAttribute = .bottomMargin
default:
fatalError()
}
} else if self.from.attributes == .margins && self.to.attributes == .edges {
switch layoutFromAttribute {
case .leftMargin:
layoutToAttribute = .left
case .rightMargin:
layoutToAttribute = .right
case .topMargin:
layoutToAttribute = .top
case .bottomMargin:
layoutToAttribute = .bottom
default:
fatalError()
}
} else if self.from.attributes == .directionalEdges && self.to.attributes == .directionalMargins {
switch layoutFromAttribute {
case .leading:
layoutToAttribute = .leadingMargin
case .trailing:
layoutToAttribute = .trailingMargin
case .top:
layoutToAttribute = .topMargin
case .bottom:
layoutToAttribute = .bottomMargin
default:
fatalError()
}
} else if self.from.attributes == .directionalMargins && self.to.attributes == .directionalEdges {
switch layoutFromAttribute {
case .leadingMargin:
layoutToAttribute = .leading
case .trailingMargin:
layoutToAttribute = .trailing
case .topMargin:
layoutToAttribute = .top
case .bottomMargin:
layoutToAttribute = .bottom
default:
fatalError()
}
} else if self.from.attributes == self.to.attributes {
layoutToAttribute = layoutFromAttribute
} else {
layoutToAttribute = layoutToAttributes[0]
}
} else {
if self.to.target == nil && (layoutFromAttribute == .centerX || layoutFromAttribute == .centerY) {
layoutToAttribute = layoutFromAttribute == .centerX ? .left : .top
} else {
layoutToAttribute = layoutFromAttribute
}
}
#else
if self.from.attributes == self.to.attributes {
layoutToAttribute = layoutFromAttribute
} else if layoutToAttributes.count > 0 {
layoutToAttribute = layoutToAttributes[0]
} else {
layoutToAttribute = layoutFromAttribute
}
#endif
// get layout constant
let layoutConstant: CGFloat = self.constant.constraintConstantTargetValueFor(layoutAttribute: layoutToAttribute)
// get layout to
var layoutTo: AnyObject? = self.to.target
// use superview if possible
if layoutTo == nil && layoutToAttribute != .width && layoutToAttribute != .height {
layoutTo = layoutFrom.superview
}
// create layout constraint
let layoutConstraint = LayoutConstraint(
item: layoutFrom,
attribute: layoutFromAttribute,
relatedBy: layoutRelation,
toItem: layoutTo,
attribute: layoutToAttribute,
multiplier: self.multiplier.constraintMultiplierTargetValue,
constant: layoutConstant
)
// set label
layoutConstraint.label = self.label
// set priority
layoutConstraint.priority = LayoutPriority(rawValue: self.priority.constraintPriorityTargetValue)
// set constraint
layoutConstraint.constraint = self
// append
self.layoutConstraints.append(layoutConstraint)
}
}
// MARK: Public
@available(*, deprecated, renamed:"activate()")
public func install() {
self.activate()
}
@available(*, deprecated, renamed:"deactivate()")
public func uninstall() {
self.deactivate()
}
public func activate() {
self.activateIfNeeded()
}
public func deactivate() {
self.deactivateIfNeeded()
}
@discardableResult
public func update(offset: ConstraintOffsetTarget) -> Constraint {
self.constant = offset.constraintOffsetTargetValue
return self
}
@discardableResult
public func update(inset: ConstraintInsetTarget) -> Constraint {
self.constant = inset.constraintInsetTargetValue
return self
}
#if canImport(UIKit)
@discardableResult
@available(iOS 11.0, tvOS 11.0, *)
public func update(inset: ConstraintDirectionalInsetTarget) -> Constraint {
self.constant = inset.constraintDirectionalInsetTargetValue
return self
}
#endif
@discardableResult
public func update(priority: ConstraintPriorityTarget) -> Constraint {
self.priority = priority.constraintPriorityTargetValue
return self
}
@discardableResult
public func update(priority: ConstraintPriority) -> Constraint {
self.priority = priority.value
return self
}
@available(*, deprecated, renamed:"update(offset:)")
public func updateOffset(amount: ConstraintOffsetTarget) -> Void { self.update(offset: amount) }
@available(*, deprecated, renamed:"update(inset:)")
public func updateInsets(amount: ConstraintInsetTarget) -> Void { self.update(inset: amount) }
@available(*, deprecated, renamed:"update(priority:)")
public func updatePriority(amount: ConstraintPriorityTarget) -> Void { self.update(priority: amount) }
@available(*, deprecated, message:"Use update(priority: ConstraintPriorityTarget) instead.")
public func updatePriorityRequired() -> Void {}
@available(*, deprecated, message:"Use update(priority: ConstraintPriorityTarget) instead.")
public func updatePriorityHigh() -> Void { fatalError("Must be implemented by Concrete subclass.") }
@available(*, deprecated, message:"Use update(priority: ConstraintPriorityTarget) instead.")
public func updatePriorityMedium() -> Void { fatalError("Must be implemented by Concrete subclass.") }
@available(*, deprecated, message:"Use update(priority: ConstraintPriorityTarget) instead.")
public func updatePriorityLow() -> Void { fatalError("Must be implemented by Concrete subclass.") }
// MARK: Internal
internal func updateConstantAndPriorityIfNeeded() {
for layoutConstraint in self.layoutConstraints {
let attribute = (layoutConstraint.secondAttribute == .notAnAttribute) ? layoutConstraint.firstAttribute : layoutConstraint.secondAttribute
layoutConstraint.constant = self.constant.constraintConstantTargetValueFor(layoutAttribute: attribute)
let requiredPriority = ConstraintPriority.required.value
if (layoutConstraint.priority.rawValue < requiredPriority), (self.priority.constraintPriorityTargetValue != requiredPriority) {
layoutConstraint.priority = LayoutPriority(rawValue: self.priority.constraintPriorityTargetValue)
}
}
}
internal func activateIfNeeded(updatingExisting: Bool = false) {
guard let item = self.from.layoutConstraintItem else {
print("WARNING: SnapKit failed to get from item from constraint. Activate will be a no-op.")
return
}
let layoutConstraints = self.layoutConstraints
if updatingExisting {
var existingLayoutConstraints: [LayoutConstraint] = []
for constraint in item.constraints {
existingLayoutConstraints += constraint.layoutConstraints
}
for layoutConstraint in layoutConstraints {
let existingLayoutConstraint = existingLayoutConstraints.first { $0 == layoutConstraint }
guard let updateLayoutConstraint = existingLayoutConstraint else {
fatalError("Updated constraint could not find existing matching constraint to update: \(layoutConstraint)")
}
let updateLayoutAttribute = (updateLayoutConstraint.secondAttribute == .notAnAttribute) ? updateLayoutConstraint.firstAttribute : updateLayoutConstraint.secondAttribute
updateLayoutConstraint.constant = self.constant.constraintConstantTargetValueFor(layoutAttribute: updateLayoutAttribute)
}
} else {
NSLayoutConstraint.activate(layoutConstraints)
item.add(constraints: [self])
}
}
internal func deactivateIfNeeded() {
guard let item = self.from.layoutConstraintItem else {
print("WARNING: SnapKit failed to get from item from constraint. Deactivate will be a no-op.")
return
}
let layoutConstraints = self.layoutConstraints
NSLayoutConstraint.deactivate(layoutConstraints)
item.remove(constraints: [self])
}
}

View File

@ -0,0 +1,203 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
internal struct ConstraintAttributes : OptionSet, ExpressibleByIntegerLiteral {
typealias IntegerLiteralType = UInt
internal init(rawValue: UInt) {
self.rawValue = rawValue
}
internal init(_ rawValue: UInt) {
self.init(rawValue: rawValue)
}
internal init(nilLiteral: ()) {
self.rawValue = 0
}
internal init(integerLiteral rawValue: IntegerLiteralType) {
self.init(rawValue: rawValue)
}
internal private(set) var rawValue: UInt
internal static var allZeros: ConstraintAttributes { return 0 }
internal static func convertFromNilLiteral() -> ConstraintAttributes { return 0 }
internal var boolValue: Bool { return self.rawValue != 0 }
internal func toRaw() -> UInt { return self.rawValue }
internal static func fromRaw(_ raw: UInt) -> ConstraintAttributes? { return self.init(raw) }
internal static func fromMask(_ raw: UInt) -> ConstraintAttributes { return self.init(raw) }
// normal
internal static let none: ConstraintAttributes = 0
internal static let left: ConstraintAttributes = ConstraintAttributes(UInt(1) << 0)
internal static let top: ConstraintAttributes = ConstraintAttributes(UInt(1) << 1)
internal static let right: ConstraintAttributes = ConstraintAttributes(UInt(1) << 2)
internal static let bottom: ConstraintAttributes = ConstraintAttributes(UInt(1) << 3)
internal static let leading: ConstraintAttributes = ConstraintAttributes(UInt(1) << 4)
internal static let trailing: ConstraintAttributes = ConstraintAttributes(UInt(1) << 5)
internal static let width: ConstraintAttributes = ConstraintAttributes(UInt(1) << 6)
internal static let height: ConstraintAttributes = ConstraintAttributes(UInt(1) << 7)
internal static let centerX: ConstraintAttributes = ConstraintAttributes(UInt(1) << 8)
internal static let centerY: ConstraintAttributes = ConstraintAttributes(UInt(1) << 9)
internal static let lastBaseline: ConstraintAttributes = ConstraintAttributes(UInt(1) << 10)
@available(iOS 8.0, OSX 10.11, *)
internal static let firstBaseline: ConstraintAttributes = ConstraintAttributes(UInt(1) << 11)
@available(iOS 8.0, *)
internal static let leftMargin: ConstraintAttributes = ConstraintAttributes(UInt(1) << 12)
@available(iOS 8.0, *)
internal static let rightMargin: ConstraintAttributes = ConstraintAttributes(UInt(1) << 13)
@available(iOS 8.0, *)
internal static let topMargin: ConstraintAttributes = ConstraintAttributes(UInt(1) << 14)
@available(iOS 8.0, *)
internal static let bottomMargin: ConstraintAttributes = ConstraintAttributes(UInt(1) << 15)
@available(iOS 8.0, *)
internal static let leadingMargin: ConstraintAttributes = ConstraintAttributes(UInt(1) << 16)
@available(iOS 8.0, *)
internal static let trailingMargin: ConstraintAttributes = ConstraintAttributes(UInt(1) << 17)
@available(iOS 8.0, *)
internal static let centerXWithinMargins: ConstraintAttributes = ConstraintAttributes(UInt(1) << 18)
@available(iOS 8.0, *)
internal static let centerYWithinMargins: ConstraintAttributes = ConstraintAttributes(UInt(1) << 19)
// aggregates
internal static let edges: ConstraintAttributes = [.horizontalEdges, .verticalEdges]
internal static let horizontalEdges: ConstraintAttributes = [.left, .right]
internal static let verticalEdges: ConstraintAttributes = [.top, .bottom]
internal static let directionalEdges: ConstraintAttributes = [.directionalHorizontalEdges, .directionalVerticalEdges]
internal static let directionalHorizontalEdges: ConstraintAttributes = [.leading, .trailing]
internal static let directionalVerticalEdges: ConstraintAttributes = [.top, .bottom]
internal static let size: ConstraintAttributes = [.width, .height]
internal static let center: ConstraintAttributes = [.centerX, .centerY]
@available(iOS 8.0, *)
internal static let margins: ConstraintAttributes = [.leftMargin, .topMargin, .rightMargin, .bottomMargin]
@available(iOS 8.0, *)
internal static let directionalMargins: ConstraintAttributes = [.leadingMargin, .topMargin, .trailingMargin, .bottomMargin]
@available(iOS 8.0, *)
internal static let centerWithinMargins: ConstraintAttributes = [.centerXWithinMargins, .centerYWithinMargins]
internal var layoutAttributes:[LayoutAttribute] {
var attrs = [LayoutAttribute]()
if (self.contains(ConstraintAttributes.left)) {
attrs.append(.left)
}
if (self.contains(ConstraintAttributes.top)) {
attrs.append(.top)
}
if (self.contains(ConstraintAttributes.right)) {
attrs.append(.right)
}
if (self.contains(ConstraintAttributes.bottom)) {
attrs.append(.bottom)
}
if (self.contains(ConstraintAttributes.leading)) {
attrs.append(.leading)
}
if (self.contains(ConstraintAttributes.trailing)) {
attrs.append(.trailing)
}
if (self.contains(ConstraintAttributes.width)) {
attrs.append(.width)
}
if (self.contains(ConstraintAttributes.height)) {
attrs.append(.height)
}
if (self.contains(ConstraintAttributes.centerX)) {
attrs.append(.centerX)
}
if (self.contains(ConstraintAttributes.centerY)) {
attrs.append(.centerY)
}
if (self.contains(ConstraintAttributes.lastBaseline)) {
attrs.append(.lastBaseline)
}
#if canImport(UIKit)
if (self.contains(ConstraintAttributes.firstBaseline)) {
attrs.append(.firstBaseline)
}
if (self.contains(ConstraintAttributes.leftMargin)) {
attrs.append(.leftMargin)
}
if (self.contains(ConstraintAttributes.rightMargin)) {
attrs.append(.rightMargin)
}
if (self.contains(ConstraintAttributes.topMargin)) {
attrs.append(.topMargin)
}
if (self.contains(ConstraintAttributes.bottomMargin)) {
attrs.append(.bottomMargin)
}
if (self.contains(ConstraintAttributes.leadingMargin)) {
attrs.append(.leadingMargin)
}
if (self.contains(ConstraintAttributes.trailingMargin)) {
attrs.append(.trailingMargin)
}
if (self.contains(ConstraintAttributes.centerXWithinMargins)) {
attrs.append(.centerXWithinMargins)
}
if (self.contains(ConstraintAttributes.centerYWithinMargins)) {
attrs.append(.centerYWithinMargins)
}
#endif
return attrs
}
}
internal func + (left: ConstraintAttributes, right: ConstraintAttributes) -> ConstraintAttributes {
return left.union(right)
}
internal func +=(left: inout ConstraintAttributes, right: ConstraintAttributes) {
left.formUnion(right)
}
internal func -=(left: inout ConstraintAttributes, right: ConstraintAttributes) {
left.subtract(right)
}
internal func ==(left: ConstraintAttributes, right: ConstraintAttributes) -> Bool {
return left.rawValue == right.rawValue
}

View File

@ -0,0 +1,37 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
public typealias ConstraintInterfaceLayoutDirection = UIUserInterfaceLayoutDirection
#else
import AppKit
public typealias ConstraintInterfaceLayoutDirection = NSUserInterfaceLayoutDirection
#endif
public struct ConstraintConfig {
public static var interfaceLayoutDirection: ConstraintInterfaceLayoutDirection = .leftToRight
}

View File

@ -0,0 +1,213 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
public protocol ConstraintConstantTarget {
}
extension CGPoint: ConstraintConstantTarget {
}
extension CGSize: ConstraintConstantTarget {
}
extension ConstraintInsets: ConstraintConstantTarget {
}
#if canImport(UIKit)
@available(iOS 11.0, tvOS 11.0, *)
extension ConstraintDirectionalInsets: ConstraintConstantTarget {
}
#endif
extension ConstraintConstantTarget {
internal func constraintConstantTargetValueFor(layoutAttribute: LayoutAttribute) -> CGFloat {
if let value = self as? CGFloat {
return value
}
if let value = self as? Float {
return CGFloat(value)
}
if let value = self as? Double {
return CGFloat(value)
}
if let value = self as? Int {
return CGFloat(value)
}
if let value = self as? UInt {
return CGFloat(value)
}
if let value = self as? CGSize {
if layoutAttribute == .width {
return value.width
} else if layoutAttribute == .height {
return value.height
} else {
return 0.0
}
}
if let value = self as? CGPoint {
#if canImport(UIKit)
switch layoutAttribute {
case .left, .right, .leading, .trailing, .centerX, .leftMargin, .rightMargin, .leadingMargin, .trailingMargin, .centerXWithinMargins:
return value.x
case .top, .bottom, .centerY, .topMargin, .bottomMargin, .centerYWithinMargins, .lastBaseline, .firstBaseline:
return value.y
case .width, .height, .notAnAttribute:
return 0.0
#if swift(>=5.0)
@unknown default:
return 0.0
#endif
}
#else
switch layoutAttribute {
case .left, .right, .leading, .trailing, .centerX:
return value.x
case .top, .bottom, .centerY, .lastBaseline, .firstBaseline:
return value.y
case .width, .height, .notAnAttribute:
return 0.0
#if swift(>=5.0)
@unknown default:
return 0.0
#endif
}
#endif
}
if let value = self as? ConstraintInsets {
#if canImport(UIKit)
switch layoutAttribute {
case .left, .leftMargin:
return value.left
case .top, .topMargin, .firstBaseline:
return value.top
case .right, .rightMargin:
return -value.right
case .bottom, .bottomMargin, .lastBaseline:
return -value.bottom
case .leading, .leadingMargin:
return (ConstraintConfig.interfaceLayoutDirection == .leftToRight) ? value.left : value.right
case .trailing, .trailingMargin:
return (ConstraintConfig.interfaceLayoutDirection == .leftToRight) ? -value.right : -value.left
case .centerX, .centerXWithinMargins:
return (value.left - value.right) / 2
case .centerY, .centerYWithinMargins:
return (value.top - value.bottom) / 2
case .width:
return -(value.left + value.right)
case .height:
return -(value.top + value.bottom)
case .notAnAttribute:
return 0.0
#if swift(>=5.0)
@unknown default:
return 0.0
#endif
}
#else
switch layoutAttribute {
case .left:
return value.left
case .top, .firstBaseline:
return value.top
case .right:
return -value.right
case .bottom, .lastBaseline:
return -value.bottom
case .leading:
return (ConstraintConfig.interfaceLayoutDirection == .leftToRight) ? value.left : value.right
case .trailing:
return (ConstraintConfig.interfaceLayoutDirection == .leftToRight) ? -value.right : -value.left
case .centerX:
return (value.left - value.right) / 2
case .centerY:
return (value.top - value.bottom) / 2
case .width:
return -(value.left + value.right)
case .height:
return -(value.top + value.bottom)
case .notAnAttribute:
return 0.0
#if swift(>=5.0)
@unknown default:
return 0.0
#endif
}
#endif
}
#if canImport(UIKit)
if #available(iOS 11.0, tvOS 11.0, *), let value = self as? ConstraintDirectionalInsets {
switch layoutAttribute {
case .left, .leftMargin:
return (ConstraintConfig.interfaceLayoutDirection == .leftToRight) ? value.leading : value.trailing
case .top, .topMargin, .firstBaseline:
return value.top
case .right, .rightMargin:
return (ConstraintConfig.interfaceLayoutDirection == .leftToRight) ? -value.trailing : -value.leading
case .bottom, .bottomMargin, .lastBaseline:
return -value.bottom
case .leading, .leadingMargin:
return value.leading
case .trailing, .trailingMargin:
return -value.trailing
case .centerX, .centerXWithinMargins:
return (value.leading - value.trailing) / 2
case .centerY, .centerYWithinMargins:
return (value.top - value.bottom) / 2
case .width:
return -(value.leading + value.trailing)
case .height:
return -(value.top + value.bottom)
case .notAnAttribute:
return 0.0
#if swift(>=5.0)
@unknown default:
return 0.0
#else
default:
return 0.0
#endif
}
}
#endif
return 0.0
}
}

View File

@ -0,0 +1,209 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
public protocol ConstraintDSL {
var target: AnyObject? { get }
func setLabel(_ value: String?)
func label() -> String?
}
extension ConstraintDSL {
public func setLabel(_ value: String?) {
objc_setAssociatedObject(self.target as Any, &labelKey, value, .OBJC_ASSOCIATION_COPY_NONATOMIC)
}
public func label() -> String? {
return objc_getAssociatedObject(self.target as Any, &labelKey) as? String
}
}
private var labelKey: UInt8 = 0
public protocol ConstraintBasicAttributesDSL : ConstraintDSL {
}
extension ConstraintBasicAttributesDSL {
// MARK: Basics
public var left: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.left)
}
public var top: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.top)
}
public var right: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.right)
}
public var bottom: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.bottom)
}
public var leading: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.leading)
}
public var trailing: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.trailing)
}
public var width: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.width)
}
public var height: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.height)
}
public var centerX: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.centerX)
}
public var centerY: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.centerY)
}
public var edges: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.edges)
}
public var directionalEdges: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.directionalEdges)
}
public var horizontalEdges: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.horizontalEdges)
}
public var verticalEdges: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.verticalEdges)
}
public var directionalHorizontalEdges: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.directionalHorizontalEdges)
}
public var directionalVerticalEdges: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.directionalVerticalEdges)
}
public var size: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.size)
}
public var center: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.center)
}
}
public protocol ConstraintAttributesDSL : ConstraintBasicAttributesDSL {
}
extension ConstraintAttributesDSL {
// MARK: Baselines
@available(*, deprecated, renamed:"lastBaseline")
public var baseline: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.lastBaseline)
}
@available(iOS 8.0, OSX 10.11, *)
public var lastBaseline: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.lastBaseline)
}
@available(iOS 8.0, OSX 10.11, *)
public var firstBaseline: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.firstBaseline)
}
// MARK: Margins
@available(iOS 8.0, *)
public var leftMargin: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.leftMargin)
}
@available(iOS 8.0, *)
public var topMargin: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.topMargin)
}
@available(iOS 8.0, *)
public var rightMargin: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.rightMargin)
}
@available(iOS 8.0, *)
public var bottomMargin: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.bottomMargin)
}
@available(iOS 8.0, *)
public var leadingMargin: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.leadingMargin)
}
@available(iOS 8.0, *)
public var trailingMargin: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.trailingMargin)
}
@available(iOS 8.0, *)
public var centerXWithinMargins: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.centerXWithinMargins)
}
@available(iOS 8.0, *)
public var centerYWithinMargins: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.centerYWithinMargins)
}
@available(iOS 8.0, *)
public var margins: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.margins)
}
@available(iOS 8.0, *)
public var directionalMargins: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.directionalMargins)
}
@available(iOS 8.0, *)
public var centerWithinMargins: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.centerWithinMargins)
}
}

View File

@ -0,0 +1,69 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
public class ConstraintDescription {
internal let item: LayoutConstraintItem
internal var attributes: ConstraintAttributes
internal var relation: ConstraintRelation? = nil
internal var sourceLocation: (String, UInt)? = nil
internal var label: String? = nil
internal var related: ConstraintItem? = nil
internal var multiplier: ConstraintMultiplierTarget = 1.0
internal var constant: ConstraintConstantTarget = 0.0
internal var priority: ConstraintPriorityTarget = 1000.0
internal lazy var constraint: Constraint? = {
guard let relation = self.relation,
let related = self.related,
let sourceLocation = self.sourceLocation else {
return nil
}
let from = ConstraintItem(target: self.item, attributes: self.attributes)
return Constraint(
from: from,
to: related,
relation: relation,
sourceLocation: sourceLocation,
label: self.label,
multiplier: self.multiplier,
constant: self.constant,
priority: self.priority
)
}()
// MARK: Initialization
internal init(item: LayoutConstraintItem, attributes: ConstraintAttributes) {
self.item = item
self.attributes = attributes
}
}

View File

@ -0,0 +1,49 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
#if canImport(UIKit)
public protocol ConstraintDirectionalInsetTarget: ConstraintConstantTarget {
}
@available(iOS 11.0, tvOS 11.0, *)
extension ConstraintDirectionalInsets: ConstraintDirectionalInsetTarget {
}
extension ConstraintDirectionalInsetTarget {
@available(iOS 11.0, tvOS 11.0, *)
internal var constraintDirectionalInsetTargetValue: ConstraintDirectionalInsets {
if let amount = self as? ConstraintDirectionalInsets {
return amount
} else {
return ConstraintDirectionalInsets(top: 0, leading: 0, bottom: 0, trailing: 0)
}
}
}
#endif

View File

@ -0,0 +1,34 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
#if canImport(UIKit)
@available(iOS 11.0, tvOS 11.0, *)
public typealias ConstraintDirectionalInsets = NSDirectionalEdgeInsets
#endif

View File

@ -0,0 +1,72 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
public protocol ConstraintInsetTarget: ConstraintConstantTarget {
}
extension Int: ConstraintInsetTarget {
}
extension UInt: ConstraintInsetTarget {
}
extension Float: ConstraintInsetTarget {
}
extension Double: ConstraintInsetTarget {
}
extension CGFloat: ConstraintInsetTarget {
}
extension ConstraintInsets: ConstraintInsetTarget {
}
extension ConstraintInsetTarget {
internal var constraintInsetTargetValue: ConstraintInsets {
if let amount = self as? ConstraintInsets {
return amount
} else if let amount = self as? Float {
return ConstraintInsets(top: CGFloat(amount), left: CGFloat(amount), bottom: CGFloat(amount), right: CGFloat(amount))
} else if let amount = self as? Double {
return ConstraintInsets(top: CGFloat(amount), left: CGFloat(amount), bottom: CGFloat(amount), right: CGFloat(amount))
} else if let amount = self as? CGFloat {
return ConstraintInsets(top: amount, left: amount, bottom: amount, right: amount)
} else if let amount = self as? Int {
return ConstraintInsets(top: CGFloat(amount), left: CGFloat(amount), bottom: CGFloat(amount), right: CGFloat(amount))
} else if let amount = self as? UInt {
return ConstraintInsets(top: CGFloat(amount), left: CGFloat(amount), bottom: CGFloat(amount), right: CGFloat(amount))
} else {
return ConstraintInsets(top: 0, left: 0, bottom: 0, right: 0)
}
}
}

View File

@ -0,0 +1,35 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
#if canImport(UIKit)
public typealias ConstraintInsets = UIEdgeInsets
#else
public typealias ConstraintInsets = NSEdgeInsets
#endif

View File

@ -0,0 +1,61 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
public final class ConstraintItem {
internal weak var target: AnyObject?
internal let attributes: ConstraintAttributes
internal init(target: AnyObject?, attributes: ConstraintAttributes) {
self.target = target
self.attributes = attributes
}
internal var layoutConstraintItem: LayoutConstraintItem? {
return self.target as? LayoutConstraintItem
}
}
public func ==(lhs: ConstraintItem, rhs: ConstraintItem) -> Bool {
// pointer equality
guard lhs !== rhs else {
return true
}
// must both have valid targets and identical attributes
guard let target1 = lhs.target,
let target2 = rhs.target,
target1 === target2 && lhs.attributes == rhs.attributes else {
return false
}
return true
}

View File

@ -0,0 +1,36 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#endif
@available(iOS 9.0, OSX 10.11, *)
public extension ConstraintLayoutGuide {
var snp: ConstraintLayoutGuideDSL {
return ConstraintLayoutGuideDSL(guide: self)
}
}

View File

@ -0,0 +1,37 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
#if canImport(UIKit)
@available(iOS 9.0, *)
public typealias ConstraintLayoutGuide = UILayoutGuide
#else
@available(OSX 10.11, *)
public typealias ConstraintLayoutGuide = NSLayoutGuide
#endif

View File

@ -0,0 +1,66 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
@available(iOS 9.0, OSX 10.11, *)
public struct ConstraintLayoutGuideDSL: ConstraintAttributesDSL {
@discardableResult
public func prepareConstraints(_ closure: (_ make: ConstraintMaker) -> Void) -> [Constraint] {
return ConstraintMaker.prepareConstraints(item: self.guide, closure: closure)
}
public func makeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) {
ConstraintMaker.makeConstraints(item: self.guide, closure: closure)
}
public func remakeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) {
ConstraintMaker.remakeConstraints(item: self.guide, closure: closure)
}
public func updateConstraints(_ closure: (_ make: ConstraintMaker) -> Void) {
ConstraintMaker.updateConstraints(item: self.guide, closure: closure)
}
public func removeConstraints() {
ConstraintMaker.removeConstraints(item: self.guide)
}
public var target: AnyObject? {
return self.guide
}
internal let guide: ConstraintLayoutGuide
internal init(guide: ConstraintLayoutGuide) {
self.guide = guide
}
}

View File

@ -0,0 +1,36 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
#if canImport(UIKit)
@available(iOS 8.0, *)
public typealias ConstraintLayoutSupport = UILayoutSupport
#else
public class ConstraintLayoutSupport {}
#endif

View File

@ -0,0 +1,56 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
@available(iOS 8.0, *)
public struct ConstraintLayoutSupportDSL: ConstraintDSL {
public var target: AnyObject? {
return self.support
}
internal let support: ConstraintLayoutSupport
internal init(support: ConstraintLayoutSupport) {
self.support = support
}
public var top: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.top)
}
public var bottom: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.bottom)
}
public var height: ConstraintItem {
return ConstraintItem(target: self.target, attributes: ConstraintAttributes.height)
}
}

View File

@ -0,0 +1,224 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
public class ConstraintMaker {
public var left: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.left)
}
public var top: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.top)
}
public var bottom: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.bottom)
}
public var right: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.right)
}
public var leading: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.leading)
}
public var trailing: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.trailing)
}
public var width: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.width)
}
public var height: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.height)
}
public var centerX: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.centerX)
}
public var centerY: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.centerY)
}
@available(*, deprecated, renamed:"lastBaseline")
public var baseline: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.lastBaseline)
}
public var lastBaseline: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.lastBaseline)
}
@available(iOS 8.0, OSX 10.11, *)
public var firstBaseline: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.firstBaseline)
}
@available(iOS 8.0, *)
public var leftMargin: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.leftMargin)
}
@available(iOS 8.0, *)
public var rightMargin: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.rightMargin)
}
@available(iOS 8.0, *)
public var topMargin: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.topMargin)
}
@available(iOS 8.0, *)
public var bottomMargin: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.bottomMargin)
}
@available(iOS 8.0, *)
public var leadingMargin: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.leadingMargin)
}
@available(iOS 8.0, *)
public var trailingMargin: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.trailingMargin)
}
@available(iOS 8.0, *)
public var centerXWithinMargins: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.centerXWithinMargins)
}
@available(iOS 8.0, *)
public var centerYWithinMargins: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.centerYWithinMargins)
}
public var edges: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.edges)
}
public var horizontalEdges: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.horizontalEdges)
}
public var verticalEdges: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.verticalEdges)
}
public var directionalEdges: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.directionalEdges)
}
public var directionalHorizontalEdges: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.directionalHorizontalEdges)
}
public var directionalVerticalEdges: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.directionalVerticalEdges)
}
public var size: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.size)
}
public var center: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.center)
}
@available(iOS 8.0, *)
public var margins: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.margins)
}
@available(iOS 8.0, *)
public var directionalMargins: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.directionalMargins)
}
@available(iOS 8.0, *)
public var centerWithinMargins: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.centerWithinMargins)
}
public let item: LayoutConstraintItem
private var descriptions = [ConstraintDescription]()
internal init(item: LayoutConstraintItem) {
self.item = item
self.item.prepare()
}
internal func makeExtendableWithAttributes(_ attributes: ConstraintAttributes) -> ConstraintMakerExtendable {
let description = ConstraintDescription(item: self.item, attributes: attributes)
self.descriptions.append(description)
return ConstraintMakerExtendable(description)
}
internal static func prepareConstraints(item: LayoutConstraintItem, closure: (_ make: ConstraintMaker) -> Void) -> [Constraint] {
let maker = ConstraintMaker(item: item)
closure(maker)
var constraints: [Constraint] = []
for description in maker.descriptions {
guard let constraint = description.constraint else {
continue
}
constraints.append(constraint)
}
return constraints
}
internal static func makeConstraints(item: LayoutConstraintItem, closure: (_ make: ConstraintMaker) -> Void) {
let constraints = prepareConstraints(item: item, closure: closure)
for constraint in constraints {
constraint.activateIfNeeded(updatingExisting: false)
}
}
internal static func remakeConstraints(item: LayoutConstraintItem, closure: (_ make: ConstraintMaker) -> Void) {
self.removeConstraints(item: item)
self.makeConstraints(item: item, closure: closure)
}
internal static func updateConstraints(item: LayoutConstraintItem, closure: (_ make: ConstraintMaker) -> Void) {
guard item.constraints.count > 0 else {
self.makeConstraints(item: item, closure: closure)
return
}
let constraints = prepareConstraints(item: item, closure: closure)
for constraint in constraints {
constraint.activateIfNeeded(updatingExisting: true)
}
}
internal static func removeConstraints(item: LayoutConstraintItem) {
let constraints = item.constraints
for constraint in constraints {
constraint.deactivateIfNeeded()
}
}
}

View File

@ -0,0 +1,64 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
public class ConstraintMakerEditable: ConstraintMakerPrioritizable {
@discardableResult
public func multipliedBy(_ amount: ConstraintMultiplierTarget) -> ConstraintMakerEditable {
self.description.multiplier = amount
return self
}
@discardableResult
public func dividedBy(_ amount: ConstraintMultiplierTarget) -> ConstraintMakerEditable {
return self.multipliedBy(1.0 / amount.constraintMultiplierTargetValue)
}
@discardableResult
public func offset(_ amount: ConstraintOffsetTarget) -> ConstraintMakerEditable {
self.description.constant = amount.constraintOffsetTargetValue
return self
}
@discardableResult
public func inset(_ amount: ConstraintInsetTarget) -> ConstraintMakerEditable {
self.description.constant = amount.constraintInsetTargetValue
return self
}
#if canImport(UIKit)
@discardableResult
@available(iOS 11.0, tvOS 11.0, *)
public func inset(_ amount: ConstraintDirectionalInsetTarget) -> ConstraintMakerEditable {
self.description.constant = amount.constraintDirectionalInsetTargetValue
return self
}
#endif
}

View File

@ -0,0 +1,195 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
public class ConstraintMakerExtendable: ConstraintMakerRelatable {
public var left: ConstraintMakerExtendable {
self.description.attributes += .left
return self
}
public var top: ConstraintMakerExtendable {
self.description.attributes += .top
return self
}
public var bottom: ConstraintMakerExtendable {
self.description.attributes += .bottom
return self
}
public var right: ConstraintMakerExtendable {
self.description.attributes += .right
return self
}
public var leading: ConstraintMakerExtendable {
self.description.attributes += .leading
return self
}
public var trailing: ConstraintMakerExtendable {
self.description.attributes += .trailing
return self
}
public var width: ConstraintMakerExtendable {
self.description.attributes += .width
return self
}
public var height: ConstraintMakerExtendable {
self.description.attributes += .height
return self
}
public var centerX: ConstraintMakerExtendable {
self.description.attributes += .centerX
return self
}
public var centerY: ConstraintMakerExtendable {
self.description.attributes += .centerY
return self
}
@available(*, deprecated, renamed:"lastBaseline")
public var baseline: ConstraintMakerExtendable {
self.description.attributes += .lastBaseline
return self
}
public var lastBaseline: ConstraintMakerExtendable {
self.description.attributes += .lastBaseline
return self
}
@available(iOS 8.0, OSX 10.11, *)
public var firstBaseline: ConstraintMakerExtendable {
self.description.attributes += .firstBaseline
return self
}
@available(iOS 8.0, *)
public var leftMargin: ConstraintMakerExtendable {
self.description.attributes += .leftMargin
return self
}
@available(iOS 8.0, *)
public var rightMargin: ConstraintMakerExtendable {
self.description.attributes += .rightMargin
return self
}
@available(iOS 8.0, *)
public var topMargin: ConstraintMakerExtendable {
self.description.attributes += .topMargin
return self
}
@available(iOS 8.0, *)
public var bottomMargin: ConstraintMakerExtendable {
self.description.attributes += .bottomMargin
return self
}
@available(iOS 8.0, *)
public var leadingMargin: ConstraintMakerExtendable {
self.description.attributes += .leadingMargin
return self
}
@available(iOS 8.0, *)
public var trailingMargin: ConstraintMakerExtendable {
self.description.attributes += .trailingMargin
return self
}
@available(iOS 8.0, *)
public var centerXWithinMargins: ConstraintMakerExtendable {
self.description.attributes += .centerXWithinMargins
return self
}
@available(iOS 8.0, *)
public var centerYWithinMargins: ConstraintMakerExtendable {
self.description.attributes += .centerYWithinMargins
return self
}
public var edges: ConstraintMakerExtendable {
self.description.attributes += .edges
return self
}
public var horizontalEdges: ConstraintMakerExtendable {
self.description.attributes += .horizontalEdges
return self
}
public var verticalEdges: ConstraintMakerExtendable {
self.description.attributes += .verticalEdges
return self
}
public var directionalEdges: ConstraintMakerExtendable {
self.description.attributes += .directionalEdges
return self
}
public var directionalHorizontalEdges: ConstraintMakerExtendable {
self.description.attributes += .directionalHorizontalEdges
return self
}
public var directionalVerticalEdges: ConstraintMakerExtendable {
self.description.attributes += .directionalVerticalEdges
return self
}
public var size: ConstraintMakerExtendable {
self.description.attributes += .size
return self
}
@available(iOS 8.0, *)
public var margins: ConstraintMakerExtendable {
self.description.attributes += .margins
return self
}
@available(iOS 8.0, *)
public var directionalMargins: ConstraintMakerExtendable {
self.description.attributes += .directionalMargins
return self
}
@available(iOS 8.0, *)
public var centerWithinMargins: ConstraintMakerExtendable {
self.description.attributes += .centerWithinMargins
return self
}
}

View File

@ -0,0 +1,49 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
public class ConstraintMakerFinalizable {
internal let description: ConstraintDescription
internal init(_ description: ConstraintDescription) {
self.description = description
}
@discardableResult
public func labeled(_ label: String) -> ConstraintMakerFinalizable {
self.description.label = label
return self
}
public var constraint: Constraint {
return self.description.constraint!
}
}

View File

@ -0,0 +1,70 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
@available(*, deprecated, message:"Use ConstraintMakerPrioritizable instead.")
public typealias ConstraintMakerPriortizable = ConstraintMakerPrioritizable
public class ConstraintMakerPrioritizable: ConstraintMakerFinalizable {
@discardableResult
public func priority(_ amount: ConstraintPriority) -> ConstraintMakerFinalizable {
self.description.priority = amount.value
return self
}
@discardableResult
public func priority(_ amount: ConstraintPriorityTarget) -> ConstraintMakerFinalizable {
self.description.priority = amount
return self
}
@available(*, deprecated, message:"Use priority(.required) instead.")
@discardableResult
public func priorityRequired() -> ConstraintMakerFinalizable {
return self.priority(.required)
}
@available(*, deprecated, message:"Use priority(.high) instead.")
@discardableResult
public func priorityHigh() -> ConstraintMakerFinalizable {
return self.priority(.high)
}
@available(*, deprecated, message:"Use priority(.medium) instead.")
@discardableResult
public func priorityMedium() -> ConstraintMakerFinalizable {
return self.priority(.medium)
}
@available(*, deprecated, message:"Use priority(.low) instead.")
@discardableResult
public func priorityLow() -> ConstraintMakerFinalizable {
return self.priority(.low)
}
}

View File

@ -0,0 +1,57 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
extension ConstraintMakerRelatable {
@discardableResult
public func equalToSuperview<T: ConstraintRelatableTarget>(_ closure: (ConstraintView) -> T, _ file: String = #file, line: UInt = #line) -> ConstraintMakerEditable {
guard let other = self.description.item.superview else {
fatalError("Expected superview but found nil when attempting make constraint `equalToSuperview`.")
}
return self.relatedTo(closure(other), relation: .equal, file: file, line: line)
}
@discardableResult
public func lessThanOrEqualToSuperview<T: ConstraintRelatableTarget>(_ closure: (ConstraintView) -> T, _ file: String = #file, line: UInt = #line) -> ConstraintMakerEditable {
guard let other = self.description.item.superview else {
fatalError("Expected superview but found nil when attempting make constraint `lessThanOrEqualToSuperview`.")
}
return self.relatedTo(closure(other), relation: .lessThanOrEqual, file: file, line: line)
}
@discardableResult
public func greaterThanOrEqualToSuperview<T: ConstraintRelatableTarget>(_ closure: (ConstraintView) -> T, _ file: String = #file, line: UInt = #line) -> ConstraintMakerEditable {
guard let other = self.description.item.superview else {
fatalError("Expected superview but found nil when attempting make constraint `greaterThanOrEqualToSuperview`.")
}
return self.relatedTo(closure(other), relation: .greaterThanOrEqual, file: file, line: line)
}
}

View File

@ -0,0 +1,115 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
public class ConstraintMakerRelatable {
internal let description: ConstraintDescription
internal init(_ description: ConstraintDescription) {
self.description = description
}
internal func relatedTo(_ other: ConstraintRelatableTarget, relation: ConstraintRelation, file: String, line: UInt) -> ConstraintMakerEditable {
let related: ConstraintItem
let constant: ConstraintConstantTarget
if let other = other as? ConstraintItem {
guard other.attributes == ConstraintAttributes.none ||
other.attributes.layoutAttributes.count <= 1 ||
other.attributes.layoutAttributes == self.description.attributes.layoutAttributes ||
other.attributes == .edges && self.description.attributes == .margins ||
other.attributes == .margins && self.description.attributes == .edges ||
other.attributes == .directionalEdges && self.description.attributes == .directionalMargins ||
other.attributes == .directionalMargins && self.description.attributes == .directionalEdges else {
fatalError("Cannot constraint to multiple non identical attributes. (\(file), \(line))");
}
related = other
constant = 0.0
} else if let other = other as? ConstraintView {
related = ConstraintItem(target: other, attributes: ConstraintAttributes.none)
constant = 0.0
} else if let other = other as? ConstraintConstantTarget {
related = ConstraintItem(target: nil, attributes: ConstraintAttributes.none)
constant = other
} else if #available(iOS 9.0, OSX 10.11, *), let other = other as? ConstraintLayoutGuide {
related = ConstraintItem(target: other, attributes: ConstraintAttributes.none)
constant = 0.0
} else {
fatalError("Invalid constraint. (\(file), \(line))")
}
let editable = ConstraintMakerEditable(self.description)
editable.description.sourceLocation = (file, line)
editable.description.relation = relation
editable.description.related = related
editable.description.constant = constant
return editable
}
@discardableResult
public func equalTo(_ other: ConstraintRelatableTarget, _ file: String = #file, _ line: UInt = #line) -> ConstraintMakerEditable {
return self.relatedTo(other, relation: .equal, file: file, line: line)
}
@discardableResult
public func equalToSuperview(_ file: String = #file, _ line: UInt = #line) -> ConstraintMakerEditable {
guard let other = self.description.item.superview else {
fatalError("Expected superview but found nil when attempting make constraint `equalToSuperview`.")
}
return self.relatedTo(other, relation: .equal, file: file, line: line)
}
@discardableResult
public func lessThanOrEqualTo(_ other: ConstraintRelatableTarget, _ file: String = #file, _ line: UInt = #line) -> ConstraintMakerEditable {
return self.relatedTo(other, relation: .lessThanOrEqual, file: file, line: line)
}
@discardableResult
public func lessThanOrEqualToSuperview(_ file: String = #file, _ line: UInt = #line) -> ConstraintMakerEditable {
guard let other = self.description.item.superview else {
fatalError("Expected superview but found nil when attempting make constraint `lessThanOrEqualToSuperview`.")
}
return self.relatedTo(other, relation: .lessThanOrEqual, file: file, line: line)
}
@discardableResult
public func greaterThanOrEqualTo(_ other: ConstraintRelatableTarget, _ file: String = #file, line: UInt = #line) -> ConstraintMakerEditable {
return self.relatedTo(other, relation: .greaterThanOrEqual, file: file, line: line)
}
@discardableResult
public func greaterThanOrEqualToSuperview(_ file: String = #file, line: UInt = #line) -> ConstraintMakerEditable {
guard let other = self.description.item.superview else {
fatalError("Expected superview but found nil when attempting make constraint `greaterThanOrEqualToSuperview`.")
}
return self.relatedTo(other, relation: .greaterThanOrEqual, file: file, line: line)
}
}

View File

@ -0,0 +1,75 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
public protocol ConstraintMultiplierTarget {
var constraintMultiplierTargetValue: CGFloat { get }
}
extension Int: ConstraintMultiplierTarget {
public var constraintMultiplierTargetValue: CGFloat {
return CGFloat(self)
}
}
extension UInt: ConstraintMultiplierTarget {
public var constraintMultiplierTargetValue: CGFloat {
return CGFloat(self)
}
}
extension Float: ConstraintMultiplierTarget {
public var constraintMultiplierTargetValue: CGFloat {
return CGFloat(self)
}
}
extension Double: ConstraintMultiplierTarget {
public var constraintMultiplierTargetValue: CGFloat {
return CGFloat(self)
}
}
extension CGFloat: ConstraintMultiplierTarget {
public var constraintMultiplierTargetValue: CGFloat {
return self
}
}

View File

@ -0,0 +1,69 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
public protocol ConstraintOffsetTarget: ConstraintConstantTarget {
}
extension Int: ConstraintOffsetTarget {
}
extension UInt: ConstraintOffsetTarget {
}
extension Float: ConstraintOffsetTarget {
}
extension Double: ConstraintOffsetTarget {
}
extension CGFloat: ConstraintOffsetTarget {
}
extension ConstraintOffsetTarget {
internal var constraintOffsetTargetValue: CGFloat {
let offset: CGFloat
if let amount = self as? Float {
offset = CGFloat(amount)
} else if let amount = self as? Double {
offset = CGFloat(amount)
} else if let amount = self as? CGFloat {
offset = CGFloat(amount)
} else if let amount = self as? Int {
offset = CGFloat(amount)
} else if let amount = self as? UInt {
offset = CGFloat(amount)
} else {
offset = 0.0
}
return offset
}
}

View File

@ -0,0 +1,77 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
public struct ConstraintPriority : ExpressibleByFloatLiteral, Equatable, Strideable {
public typealias FloatLiteralType = Float
public let value: Float
public init(floatLiteral value: Float) {
self.value = value
}
public init(_ value: Float) {
self.value = value
}
public static var required: ConstraintPriority {
return 1000.0
}
public static var high: ConstraintPriority {
return 750.0
}
public static var medium: ConstraintPriority {
#if os(OSX)
return 501.0
#else
return 500.0
#endif
}
public static var low: ConstraintPriority {
return 250.0
}
public static func ==(lhs: ConstraintPriority, rhs: ConstraintPriority) -> Bool {
return lhs.value == rhs.value
}
// MARK: Strideable
public func advanced(by n: FloatLiteralType) -> ConstraintPriority {
return ConstraintPriority(floatLiteral: value + n)
}
public func distance(to other: ConstraintPriority) -> FloatLiteralType {
return other.value - value
}
}

View File

@ -0,0 +1,85 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
public protocol ConstraintPriorityTarget {
var constraintPriorityTargetValue: Float { get }
}
extension Int: ConstraintPriorityTarget {
public var constraintPriorityTargetValue: Float {
return Float(self)
}
}
extension UInt: ConstraintPriorityTarget {
public var constraintPriorityTargetValue: Float {
return Float(self)
}
}
extension Float: ConstraintPriorityTarget {
public var constraintPriorityTargetValue: Float {
return self
}
}
extension Double: ConstraintPriorityTarget {
public var constraintPriorityTargetValue: Float {
return Float(self)
}
}
extension CGFloat: ConstraintPriorityTarget {
public var constraintPriorityTargetValue: Float {
return Float(self)
}
}
#if canImport(UIKit)
extension UILayoutPriority: ConstraintPriorityTarget {
public var constraintPriorityTargetValue: Float {
return self.rawValue
}
}
#endif

View File

@ -0,0 +1,72 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
public protocol ConstraintRelatableTarget {
}
extension Int: ConstraintRelatableTarget {
}
extension UInt: ConstraintRelatableTarget {
}
extension Float: ConstraintRelatableTarget {
}
extension Double: ConstraintRelatableTarget {
}
extension CGFloat: ConstraintRelatableTarget {
}
extension CGSize: ConstraintRelatableTarget {
}
extension CGPoint: ConstraintRelatableTarget {
}
extension ConstraintInsets: ConstraintRelatableTarget {
}
#if canImport(UIKit)
@available(iOS 11.0, tvOS 11.0, *)
extension ConstraintDirectionalInsets: ConstraintRelatableTarget {
}
#endif
extension ConstraintItem: ConstraintRelatableTarget {
}
extension ConstraintView: ConstraintRelatableTarget {
}
@available(iOS 9.0, OSX 10.11, *)
extension ConstraintLayoutGuide: ConstraintRelatableTarget {
}

View File

@ -0,0 +1,48 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
internal enum ConstraintRelation : Int {
case equal = 1
case lessThanOrEqual
case greaterThanOrEqual
internal var layoutRelation: LayoutRelation {
get {
switch(self) {
case .equal:
return .equal
case .lessThanOrEqual:
return .lessThanOrEqual
case .greaterThanOrEqual:
return .greaterThanOrEqual
}
}
}
}

View File

@ -0,0 +1,152 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
public extension ConstraintView {
@available(*, deprecated, renamed:"snp.left")
var snp_left: ConstraintItem { return self.snp.left }
@available(*, deprecated, renamed:"snp.top")
var snp_top: ConstraintItem { return self.snp.top }
@available(*, deprecated, renamed:"snp.right")
var snp_right: ConstraintItem { return self.snp.right }
@available(*, deprecated, renamed:"snp.bottom")
var snp_bottom: ConstraintItem { return self.snp.bottom }
@available(*, deprecated, renamed:"snp.leading")
var snp_leading: ConstraintItem { return self.snp.leading }
@available(*, deprecated, renamed:"snp.trailing")
var snp_trailing: ConstraintItem { return self.snp.trailing }
@available(*, deprecated, renamed:"snp.width")
var snp_width: ConstraintItem { return self.snp.width }
@available(*, deprecated, renamed:"snp.height")
var snp_height: ConstraintItem { return self.snp.height }
@available(*, deprecated, renamed:"snp.centerX")
var snp_centerX: ConstraintItem { return self.snp.centerX }
@available(*, deprecated, renamed:"snp.centerY")
var snp_centerY: ConstraintItem { return self.snp.centerY }
@available(*, deprecated, renamed:"snp.baseline")
var snp_baseline: ConstraintItem { return self.snp.baseline }
@available(*, deprecated, renamed:"snp.lastBaseline")
@available(iOS 8.0, OSX 10.11, *)
var snp_lastBaseline: ConstraintItem { return self.snp.lastBaseline }
@available(iOS, deprecated, renamed:"snp.firstBaseline")
@available(iOS 8.0, OSX 10.11, *)
var snp_firstBaseline: ConstraintItem { return self.snp.firstBaseline }
@available(iOS, deprecated, renamed:"snp.leftMargin")
@available(iOS 8.0, *)
var snp_leftMargin: ConstraintItem { return self.snp.leftMargin }
@available(iOS, deprecated, renamed:"snp.topMargin")
@available(iOS 8.0, *)
var snp_topMargin: ConstraintItem { return self.snp.topMargin }
@available(iOS, deprecated, renamed:"snp.rightMargin")
@available(iOS 8.0, *)
var snp_rightMargin: ConstraintItem { return self.snp.rightMargin }
@available(iOS, deprecated, renamed:"snp.bottomMargin")
@available(iOS 8.0, *)
var snp_bottomMargin: ConstraintItem { return self.snp.bottomMargin }
@available(iOS, deprecated, renamed:"snp.leadingMargin")
@available(iOS 8.0, *)
var snp_leadingMargin: ConstraintItem { return self.snp.leadingMargin }
@available(iOS, deprecated, renamed:"snp.trailingMargin")
@available(iOS 8.0, *)
var snp_trailingMargin: ConstraintItem { return self.snp.trailingMargin }
@available(iOS, deprecated, renamed:"snp.centerXWithinMargins")
@available(iOS 8.0, *)
var snp_centerXWithinMargins: ConstraintItem { return self.snp.centerXWithinMargins }
@available(iOS, deprecated, renamed:"snp.centerYWithinMargins")
@available(iOS 8.0, *)
var snp_centerYWithinMargins: ConstraintItem { return self.snp.centerYWithinMargins }
@available(*, deprecated, renamed:"snp.edges")
var snp_edges: ConstraintItem { return self.snp.edges }
@available(*, deprecated, renamed:"snp.size")
var snp_size: ConstraintItem { return self.snp.size }
@available(*, deprecated, renamed:"snp.center")
var snp_center: ConstraintItem { return self.snp.center }
@available(iOS, deprecated, renamed:"snp.margins")
@available(iOS 8.0, *)
var snp_margins: ConstraintItem { return self.snp.margins }
@available(iOS, deprecated, renamed:"snp.centerWithinMargins")
@available(iOS 8.0, *)
var snp_centerWithinMargins: ConstraintItem { return self.snp.centerWithinMargins }
@available(*, deprecated, renamed:"snp.prepareConstraints(_:)")
func snp_prepareConstraints(_ closure: (_ make: ConstraintMaker) -> Void) -> [Constraint] {
return self.snp.prepareConstraints(closure)
}
@available(*, deprecated, renamed:"snp.makeConstraints(_:)")
func snp_makeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) {
self.snp.makeConstraints(closure)
}
@available(*, deprecated, renamed:"snp.remakeConstraints(_:)")
func snp_remakeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) {
self.snp.remakeConstraints(closure)
}
@available(*, deprecated, renamed:"snp.updateConstraints(_:)")
func snp_updateConstraints(_ closure: (_ make: ConstraintMaker) -> Void) {
self.snp.updateConstraints(closure)
}
@available(*, deprecated, renamed:"snp.removeConstraints()")
func snp_removeConstraints() {
self.snp.removeConstraints()
}
var snp: ConstraintViewDSL {
return ConstraintViewDSL(view: self)
}
}

View File

@ -0,0 +1,35 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
#if canImport(UIKit)
public typealias ConstraintView = UIView
#else
public typealias ConstraintView = NSView
#endif

View File

@ -0,0 +1,101 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
public struct ConstraintViewDSL: ConstraintAttributesDSL {
@discardableResult
public func prepareConstraints(_ closure: (_ make: ConstraintMaker) -> Void) -> [Constraint] {
return ConstraintMaker.prepareConstraints(item: self.view, closure: closure)
}
public func makeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) {
ConstraintMaker.makeConstraints(item: self.view, closure: closure)
}
public func remakeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) {
ConstraintMaker.remakeConstraints(item: self.view, closure: closure)
}
public func updateConstraints(_ closure: (_ make: ConstraintMaker) -> Void) {
ConstraintMaker.updateConstraints(item: self.view, closure: closure)
}
public func removeConstraints() {
ConstraintMaker.removeConstraints(item: self.view)
}
public var contentHuggingHorizontalPriority: Float {
get {
return self.view.contentHuggingPriority(for: .horizontal).rawValue
}
nonmutating set {
self.view.setContentHuggingPriority(LayoutPriority(rawValue: newValue), for: .horizontal)
}
}
public var contentHuggingVerticalPriority: Float {
get {
return self.view.contentHuggingPriority(for: .vertical).rawValue
}
nonmutating set {
self.view.setContentHuggingPriority(LayoutPriority(rawValue: newValue), for: .vertical)
}
}
public var contentCompressionResistanceHorizontalPriority: Float {
get {
return self.view.contentCompressionResistancePriority(for: .horizontal).rawValue
}
nonmutating set {
self.view.setContentCompressionResistancePriority(LayoutPriority(rawValue: newValue), for: .horizontal)
}
}
public var contentCompressionResistanceVerticalPriority: Float {
get {
return self.view.contentCompressionResistancePriority(for: .vertical).rawValue
}
nonmutating set {
self.view.setContentCompressionResistancePriority(LayoutPriority(rawValue: newValue), for: .vertical)
}
}
public var target: AnyObject? {
return self.view
}
internal let view: ConstraintView
internal init(view: ConstraintView) {
self.view = view
}
}

View File

@ -0,0 +1,169 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
public extension LayoutConstraint {
override var description: String {
var description = "<"
description += descriptionForObject(self)
if let firstItem = conditionalOptional(from: self.firstItem) {
description += " \(descriptionForObject(firstItem))"
}
if self.firstAttribute != .notAnAttribute {
description += ".\(descriptionForAttribute(self.firstAttribute))"
}
description += " \(descriptionForRelation(self.relation))"
if let secondItem = self.secondItem {
description += " \(descriptionForObject(secondItem))"
}
if self.secondAttribute != .notAnAttribute {
description += ".\(descriptionForAttribute(self.secondAttribute))"
}
if self.multiplier != 1.0 {
description += " * \(self.multiplier)"
}
if self.secondAttribute == .notAnAttribute {
description += " \(self.constant)"
} else {
if self.constant > 0.0 {
description += " + \(self.constant)"
} else if self.constant < 0.0 {
description += " - \(abs(self.constant))"
}
}
if self.priority.rawValue != 1000.0 {
description += " ^\(self.priority)"
}
description += ">"
return description
}
}
private func descriptionForRelation(_ relation: LayoutRelation) -> String {
switch relation {
case .equal: return "=="
case .greaterThanOrEqual: return ">="
case .lessThanOrEqual: return "<="
#if swift(>=5.0)
@unknown default: return "unknown"
#endif
}
}
private func descriptionForAttribute(_ attribute: LayoutAttribute) -> String {
#if canImport(UIKit)
switch attribute {
case .notAnAttribute: return "notAnAttribute"
case .top: return "top"
case .left: return "left"
case .bottom: return "bottom"
case .right: return "right"
case .leading: return "leading"
case .trailing: return "trailing"
case .width: return "width"
case .height: return "height"
case .centerX: return "centerX"
case .centerY: return "centerY"
case .lastBaseline: return "lastBaseline"
case .firstBaseline: return "firstBaseline"
case .topMargin: return "topMargin"
case .leftMargin: return "leftMargin"
case .bottomMargin: return "bottomMargin"
case .rightMargin: return "rightMargin"
case .leadingMargin: return "leadingMargin"
case .trailingMargin: return "trailingMargin"
case .centerXWithinMargins: return "centerXWithinMargins"
case .centerYWithinMargins: return "centerYWithinMargins"
#if swift(>=5.0)
@unknown default: return "unknown"
#endif
}
#else
switch attribute {
case .notAnAttribute: return "notAnAttribute"
case .top: return "top"
case .left: return "left"
case .bottom: return "bottom"
case .right: return "right"
case .leading: return "leading"
case .trailing: return "trailing"
case .width: return "width"
case .height: return "height"
case .centerX: return "centerX"
case .centerY: return "centerY"
case .lastBaseline: return "lastBaseline"
case .firstBaseline: return "firstBaseline"
#if swift(>=5.0)
@unknown default: return "unknown"
#endif
}
#endif
}
private func conditionalOptional<T>(from object: Optional<T>) -> Optional<T> {
return object
}
private func conditionalOptional<T>(from object: T) -> Optional<T> {
return Optional.some(object)
}
private func descriptionForObject(_ object: AnyObject) -> String {
let pointerDescription = String(format: "%p", UInt(bitPattern: ObjectIdentifier(object)))
var desc = ""
desc += type(of: object).description()
if let object = object as? ConstraintView {
desc += ":\(object.snp.label() ?? pointerDescription)"
} else if let object = object as? LayoutConstraint {
desc += ":\(object.label ?? pointerDescription)"
} else {
desc += ":\(pointerDescription)"
}
if let object = object as? LayoutConstraint, let file = object.constraint?.sourceLocation.0, let line = object.constraint?.sourceLocation.1 {
desc += "@\((file as NSString).lastPathComponent)#\(line)"
}
desc += ""
return desc
}

View File

@ -0,0 +1,61 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
public class LayoutConstraint : NSLayoutConstraint {
public var label: String? {
get {
return self.identifier
}
set {
self.identifier = newValue
}
}
internal weak var constraint: Constraint? = nil
}
internal func ==(lhs: LayoutConstraint, rhs: LayoutConstraint) -> Bool {
// If firstItem or secondItem on either constraint has a dangling pointer
// this comparison can cause a crash. The solution for this is to ensure
// your layout code hold strong references to things like Views, LayoutGuides
// and LayoutAnchors as SnapKit will not keep strong references to any of these.
guard lhs.firstAttribute == rhs.firstAttribute &&
lhs.secondAttribute == rhs.secondAttribute &&
lhs.relation == rhs.relation &&
lhs.priority == rhs.priority &&
lhs.multiplier == rhs.multiplier &&
lhs.secondItem === rhs.secondItem &&
lhs.firstItem === rhs.firstItem else {
return false
}
return true
}

View File

@ -0,0 +1,93 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
public protocol LayoutConstraintItem: AnyObject {
}
@available(iOS 9.0, OSX 10.11, *)
extension ConstraintLayoutGuide : LayoutConstraintItem {
}
extension ConstraintView : LayoutConstraintItem {
}
extension LayoutConstraintItem {
internal func prepare() {
if let view = self as? ConstraintView {
view.translatesAutoresizingMaskIntoConstraints = false
}
}
internal var superview: ConstraintView? {
if let view = self as? ConstraintView {
return view.superview
}
if #available(iOS 9.0, OSX 10.11, *), let guide = self as? ConstraintLayoutGuide {
return guide.owningView
}
return nil
}
internal var constraints: [Constraint] {
return self.constraintsSet.allObjects as! [Constraint]
}
internal func add(constraints: [Constraint]) {
let constraintsSet = self.constraintsSet
for constraint in constraints {
constraintsSet.add(constraint)
}
}
internal func remove(constraints: [Constraint]) {
let constraintsSet = self.constraintsSet
for constraint in constraints {
constraintsSet.remove(constraint)
}
}
private var constraintsSet: NSMutableSet {
let constraintsSet: NSMutableSet
if let existing = objc_getAssociatedObject(self, &constraintsKey) as? NSMutableSet {
constraintsSet = existing
} else {
constraintsSet = NSMutableSet()
objc_setAssociatedObject(self, &constraintsKey, constraintsSet, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
return constraintsSet
}
}
private var constraintsKey: UInt8 = 0

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyTracking</key>
<false/>
<key>NSPrivacyAccessedAPITypes</key>
<array/>
<key>NSPrivacyCollectedDataTypes</key>
<array/>
<key>NSPrivacyTrackingDomains</key>
<array/>
</dict>
</plist>

View File

@ -0,0 +1,42 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
import Foundation
#if canImport(UIKit)
import UIKit
#if swift(>=4.2)
typealias LayoutRelation = NSLayoutConstraint.Relation
typealias LayoutAttribute = NSLayoutConstraint.Attribute
#else
typealias LayoutRelation = NSLayoutRelation
typealias LayoutAttribute = NSLayoutAttribute
#endif
typealias LayoutPriority = UILayoutPriority
#else
import AppKit
typealias LayoutRelation = NSLayoutConstraint.Relation
typealias LayoutAttribute = NSLayoutConstraint.Attribute
typealias LayoutPriority = NSLayoutConstraint.Priority
#endif

View File

@ -0,0 +1,36 @@
//
// SnapKit
//
// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
//
// 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.
#if canImport(UIKit)
import UIKit
#endif
@available(iOS 8.0, *)
public extension ConstraintLayoutSupport {
var snp: ConstraintLayoutSupportDSL {
return ConstraintLayoutSupportDSL(support: self)
}
}

View File

@ -53,6 +53,29 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
## SnapKit
Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
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.
## ZIPFoundation ## ZIPFoundation
MIT License MIT License

View File

@ -76,6 +76,35 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<key>Type</key> <key>Type</key>
<string>PSGroupSpecifier</string> <string>PSGroupSpecifier</string>
</dict> </dict>
<dict>
<key>FooterText</key>
<string>Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
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.
</string>
<key>License</key>
<string>MIT</string>
<key>Title</key>
<string>SnapKit</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict> <dict>
<key>FooterText</key> <key>FooterText</key>
<string>MIT License <string>MIT License

View File

@ -2,4 +2,6 @@ ${PODS_ROOT}/Target Support Files/Pods-ReadViewDemo/Pods-ReadViewDemo-frameworks
${BUILT_PRODUCTS_DIR}/DTCoreText/DTCoreText.framework ${BUILT_PRODUCTS_DIR}/DTCoreText/DTCoreText.framework
${BUILT_PRODUCTS_DIR}/DTFoundation/DTFoundation.framework ${BUILT_PRODUCTS_DIR}/DTFoundation/DTFoundation.framework
${BUILT_PRODUCTS_DIR}/RDEpubReaderView/RDEpubReaderView.framework ${BUILT_PRODUCTS_DIR}/RDEpubReaderView/RDEpubReaderView.framework
${BUILT_PRODUCTS_DIR}/RDPDFReaderView/RDPDFReaderView.framework
${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework
${BUILT_PRODUCTS_DIR}/ZIPFoundation/ZIPFoundation.framework ${BUILT_PRODUCTS_DIR}/ZIPFoundation/ZIPFoundation.framework

View File

@ -1,4 +1,6 @@
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DTCoreText.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DTCoreText.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DTFoundation.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DTFoundation.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RDEpubReaderView.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RDEpubReaderView.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RDPDFReaderView.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SnapKit.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ZIPFoundation.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ZIPFoundation.framework

View File

@ -2,4 +2,6 @@ ${PODS_ROOT}/Target Support Files/Pods-ReadViewDemo/Pods-ReadViewDemo-frameworks
${BUILT_PRODUCTS_DIR}/DTCoreText/DTCoreText.framework ${BUILT_PRODUCTS_DIR}/DTCoreText/DTCoreText.framework
${BUILT_PRODUCTS_DIR}/DTFoundation/DTFoundation.framework ${BUILT_PRODUCTS_DIR}/DTFoundation/DTFoundation.framework
${BUILT_PRODUCTS_DIR}/RDEpubReaderView/RDEpubReaderView.framework ${BUILT_PRODUCTS_DIR}/RDEpubReaderView/RDEpubReaderView.framework
${BUILT_PRODUCTS_DIR}/RDPDFReaderView/RDPDFReaderView.framework
${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework
${BUILT_PRODUCTS_DIR}/ZIPFoundation/ZIPFoundation.framework ${BUILT_PRODUCTS_DIR}/ZIPFoundation/ZIPFoundation.framework

View File

@ -1,4 +1,6 @@
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DTCoreText.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DTCoreText.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DTFoundation.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DTFoundation.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RDEpubReaderView.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RDEpubReaderView.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RDPDFReaderView.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SnapKit.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ZIPFoundation.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ZIPFoundation.framework

View File

@ -179,12 +179,16 @@ if [[ "$CONFIGURATION" == "Debug" ]]; then
install_framework "${BUILT_PRODUCTS_DIR}/DTCoreText/DTCoreText.framework" install_framework "${BUILT_PRODUCTS_DIR}/DTCoreText/DTCoreText.framework"
install_framework "${BUILT_PRODUCTS_DIR}/DTFoundation/DTFoundation.framework" install_framework "${BUILT_PRODUCTS_DIR}/DTFoundation/DTFoundation.framework"
install_framework "${BUILT_PRODUCTS_DIR}/RDEpubReaderView/RDEpubReaderView.framework" install_framework "${BUILT_PRODUCTS_DIR}/RDEpubReaderView/RDEpubReaderView.framework"
install_framework "${BUILT_PRODUCTS_DIR}/RDPDFReaderView/RDPDFReaderView.framework"
install_framework "${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework"
install_framework "${BUILT_PRODUCTS_DIR}/ZIPFoundation/ZIPFoundation.framework" install_framework "${BUILT_PRODUCTS_DIR}/ZIPFoundation/ZIPFoundation.framework"
fi fi
if [[ "$CONFIGURATION" == "Release" ]]; then if [[ "$CONFIGURATION" == "Release" ]]; then
install_framework "${BUILT_PRODUCTS_DIR}/DTCoreText/DTCoreText.framework" install_framework "${BUILT_PRODUCTS_DIR}/DTCoreText/DTCoreText.framework"
install_framework "${BUILT_PRODUCTS_DIR}/DTFoundation/DTFoundation.framework" install_framework "${BUILT_PRODUCTS_DIR}/DTFoundation/DTFoundation.framework"
install_framework "${BUILT_PRODUCTS_DIR}/RDEpubReaderView/RDEpubReaderView.framework" install_framework "${BUILT_PRODUCTS_DIR}/RDEpubReaderView/RDEpubReaderView.framework"
install_framework "${BUILT_PRODUCTS_DIR}/RDPDFReaderView/RDPDFReaderView.framework"
install_framework "${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework"
install_framework "${BUILT_PRODUCTS_DIR}/ZIPFoundation/ZIPFoundation.framework" install_framework "${BUILT_PRODUCTS_DIR}/ZIPFoundation/ZIPFoundation.framework"
fi fi
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then

View File

@ -0,0 +1,2 @@
${PODS_ROOT}/Target Support Files/Pods-ReadViewDemo/Pods-ReadViewDemo-resources.sh
${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView/RDEpubReaderViewAssets.bundle

View File

@ -0,0 +1 @@
${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RDEpubReaderViewAssets.bundle

View File

@ -0,0 +1,2 @@
${PODS_ROOT}/Target Support Files/Pods-ReadViewDemo/Pods-ReadViewDemo-resources.sh
${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView/RDEpubReaderViewAssets.bundle

View File

@ -0,0 +1 @@
${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RDEpubReaderViewAssets.bundle

View File

@ -0,0 +1,129 @@
#!/bin/sh
set -e
set -u
set -o pipefail
function on_error {
echo "$(realpath -mq "${0}"):$1: error: Unexpected failure"
}
trap 'on_error $LINENO' ERR
if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then
# If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy
# resources to, so exit 0 (signalling the script phase was successful).
exit 0
fi
mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
> "$RESOURCES_TO_COPY"
XCASSET_FILES=()
# This protects against multiple targets copying the same framework dependency at the same time. The solution
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
case "${TARGETED_DEVICE_FAMILY:-}" in
1,2)
TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone"
;;
1)
TARGET_DEVICE_ARGS="--target-device iphone"
;;
2)
TARGET_DEVICE_ARGS="--target-device ipad"
;;
3)
TARGET_DEVICE_ARGS="--target-device tv"
;;
4)
TARGET_DEVICE_ARGS="--target-device watch"
;;
*)
TARGET_DEVICE_ARGS="--target-device mac"
;;
esac
install_resource()
{
if [[ "$1" = /* ]] ; then
RESOURCE_PATH="$1"
else
RESOURCE_PATH="${PODS_ROOT}/$1"
fi
if [[ ! -e "$RESOURCE_PATH" ]] ; then
cat << EOM
error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script.
EOM
exit 1
fi
case $RESOURCE_PATH in
*.storyboard)
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.xib)
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.framework)
echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
;;
*.xcdatamodel)
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom"
;;
*.xcdatamodeld)
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd"
;;
*.xcmappingmodel)
echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true
xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm"
;;
*.xcassets)
ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH"
XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
;;
*)
echo "$RESOURCE_PATH" || true
echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY"
;;
esac
}
if [[ "$CONFIGURATION" == "Debug" ]]; then
install_resource "${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView/RDEpubReaderViewAssets.bundle"
fi
if [[ "$CONFIGURATION" == "Release" ]]; then
install_resource "${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView/RDEpubReaderViewAssets.bundle"
fi
mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then
mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
fi
rm -f "$RESOURCES_TO_COPY"
if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ]
then
# Find all other xcassets (this unfortunately includes those of path pods and other targets).
OTHER_XCASSETS=$(find -L "$PWD" -iname "*.xcassets" -type d)
while read line; do
if [[ $line != "${PODS_ROOT}*" ]]; then
XCASSET_FILES+=("$line")
fi
done <<<"$OTHER_XCASSETS"
if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then
printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
else
printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist"
fi
fi

View File

@ -1,12 +1,12 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DTCoreText" "${PODS_CONFIGURATION_BUILD_DIR}/DTFoundation" "${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView" "${PODS_CONFIGURATION_BUILD_DIR}/ZIPFoundation" FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DTCoreText" "${PODS_CONFIGURATION_BUILD_DIR}/DTFoundation" "${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView" "${PODS_CONFIGURATION_BUILD_DIR}/RDPDFReaderView" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" "${PODS_CONFIGURATION_BUILD_DIR}/ZIPFoundation"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DTCoreText/DTCoreText.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DTFoundation/DTFoundation.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView/RDEpubReaderView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ZIPFoundation/ZIPFoundation.framework/Headers" "$(SDKROOT)/usr/include/libxml2" HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DTCoreText/DTCoreText.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DTFoundation/DTFoundation.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView/RDEpubReaderView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RDPDFReaderView/RDPDFReaderView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ZIPFoundation/ZIPFoundation.framework/Headers" "$(SDKROOT)/usr/include/libxml2"
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks'
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift $(SDKROOT)/usr/lib/swift
OTHER_LDFLAGS = $(inherited) -l"xml2" -framework "CoreGraphics" -framework "CoreText" -framework "DTCoreText" -framework "DTFoundation" -framework "ImageIO" -framework "MediaPlayer" -framework "QuartzCore" -framework "RDEpubReaderView" -framework "ZIPFoundation" OTHER_LDFLAGS = $(inherited) -l"swiftCoreGraphics" -l"xml2" -framework "CoreGraphics" -framework "CoreImage" -framework "CoreText" -framework "DTCoreText" -framework "DTFoundation" -framework "ImageIO" -framework "MediaPlayer" -framework "PDFKit" -framework "QuartzCore" -framework "RDEpubReaderView" -framework "RDPDFReaderView" -framework "SnapKit" -framework "Vision" -framework "ZIPFoundation"
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/DTCoreText" "-F${PODS_CONFIGURATION_BUILD_DIR}/DTFoundation" "-F${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView" "-F${PODS_CONFIGURATION_BUILD_DIR}/ZIPFoundation" OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/DTCoreText" "-F${PODS_CONFIGURATION_BUILD_DIR}/DTFoundation" "-F${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView" "-F${PODS_CONFIGURATION_BUILD_DIR}/RDPDFReaderView" "-F${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" "-F${PODS_CONFIGURATION_BUILD_DIR}/ZIPFoundation"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR} PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)

View File

@ -1,12 +1,12 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DTCoreText" "${PODS_CONFIGURATION_BUILD_DIR}/DTFoundation" "${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView" "${PODS_CONFIGURATION_BUILD_DIR}/ZIPFoundation" FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DTCoreText" "${PODS_CONFIGURATION_BUILD_DIR}/DTFoundation" "${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView" "${PODS_CONFIGURATION_BUILD_DIR}/RDPDFReaderView" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" "${PODS_CONFIGURATION_BUILD_DIR}/ZIPFoundation"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DTCoreText/DTCoreText.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DTFoundation/DTFoundation.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView/RDEpubReaderView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ZIPFoundation/ZIPFoundation.framework/Headers" "$(SDKROOT)/usr/include/libxml2" HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DTCoreText/DTCoreText.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DTFoundation/DTFoundation.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView/RDEpubReaderView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/RDPDFReaderView/RDPDFReaderView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ZIPFoundation/ZIPFoundation.framework/Headers" "$(SDKROOT)/usr/include/libxml2"
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks'
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift $(SDKROOT)/usr/lib/swift
OTHER_LDFLAGS = $(inherited) -l"xml2" -framework "CoreGraphics" -framework "CoreText" -framework "DTCoreText" -framework "DTFoundation" -framework "ImageIO" -framework "MediaPlayer" -framework "QuartzCore" -framework "RDEpubReaderView" -framework "ZIPFoundation" OTHER_LDFLAGS = $(inherited) -l"swiftCoreGraphics" -l"xml2" -framework "CoreGraphics" -framework "CoreImage" -framework "CoreText" -framework "DTCoreText" -framework "DTFoundation" -framework "ImageIO" -framework "MediaPlayer" -framework "PDFKit" -framework "QuartzCore" -framework "RDEpubReaderView" -framework "RDPDFReaderView" -framework "SnapKit" -framework "Vision" -framework "ZIPFoundation"
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/DTCoreText" "-F${PODS_CONFIGURATION_BUILD_DIR}/DTFoundation" "-F${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView" "-F${PODS_CONFIGURATION_BUILD_DIR}/ZIPFoundation" OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/DTCoreText" "-F${PODS_CONFIGURATION_BUILD_DIR}/DTFoundation" "-F${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView" "-F${PODS_CONFIGURATION_BUILD_DIR}/RDPDFReaderView" "-F${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" "-F${PODS_CONFIGURATION_BUILD_DIR}/ZIPFoundation"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR} PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)

View File

@ -15,7 +15,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>FMWK</string> <string>FMWK</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>0.0.1</string> <string>0.0.2</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>

View File

@ -1,15 +1,15 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DTCoreText" "${PODS_CONFIGURATION_BUILD_DIR}/DTFoundation" "${PODS_CONFIGURATION_BUILD_DIR}/ZIPFoundation" FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DTCoreText" "${PODS_CONFIGURATION_BUILD_DIR}/DTFoundation" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" "${PODS_CONFIGURATION_BUILD_DIR}/ZIPFoundation"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "CoreText" -framework "DTCoreText" -framework "ImageIO" -framework "MediaPlayer" -framework "QuartzCore" -framework "ZIPFoundation" OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "CoreText" -framework "DTCoreText" -framework "ImageIO" -framework "MediaPlayer" -framework "QuartzCore" -framework "SnapKit" -framework "ZIPFoundation"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR} PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
PODS_ROOT = ${SRCROOT} PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. PODS_TARGET_SRCROOT = ${PODS_ROOT}/../../Sources/RDEpubReaderView
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES SKIP_INSTALL = YES

View File

@ -1,15 +1,15 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/RDEpubReaderView
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DTCoreText" "${PODS_CONFIGURATION_BUILD_DIR}/DTFoundation" "${PODS_CONFIGURATION_BUILD_DIR}/ZIPFoundation" FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/DTCoreText" "${PODS_CONFIGURATION_BUILD_DIR}/DTFoundation" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" "${PODS_CONFIGURATION_BUILD_DIR}/ZIPFoundation"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "CoreText" -framework "DTCoreText" -framework "ImageIO" -framework "MediaPlayer" -framework "QuartzCore" -framework "ZIPFoundation" OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "CoreText" -framework "DTCoreText" -framework "ImageIO" -framework "MediaPlayer" -framework "QuartzCore" -framework "SnapKit" -framework "ZIPFoundation"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR} PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
PODS_ROOT = ${SRCROOT} PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. PODS_TARGET_SRCROOT = ${PODS_ROOT}/../../Sources/RDEpubReaderView
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES SKIP_INSTALL = YES

View File

@ -13,7 +13,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>BNDL</string> <string>BNDL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>0.0.1</string> <string>0.0.2</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>${PODS_DEVELOPMENT_LANGUAGE}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.0.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View File

@ -0,0 +1,5 @@
#import <Foundation/Foundation.h>
@interface PodsDummy_RDPDFReaderView : NSObject
@end
@implementation PodsDummy_RDPDFReaderView
@end

View File

@ -0,0 +1,12 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif

View File

@ -0,0 +1,16 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
FOUNDATION_EXPORT double RDPDFReaderViewVersionNumber;
FOUNDATION_EXPORT const unsigned char RDPDFReaderViewVersionString[];

View File

@ -0,0 +1,16 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/RDPDFReaderView
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_LDFLAGS = $(inherited) -framework "CoreImage" -framework "PDFKit" -framework "SnapKit" -framework "Vision"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../../Sources/RDPDFReaderView
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

View File

@ -0,0 +1,6 @@
framework module RDPDFReaderView {
umbrella header "RDPDFReaderView-umbrella.h"
export *
module * { export * }
}

View File

@ -0,0 +1,16 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/RDPDFReaderView
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_LDFLAGS = $(inherited) -framework "CoreImage" -framework "PDFKit" -framework "SnapKit" -framework "Vision"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../../Sources/RDPDFReaderView
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>${PODS_DEVELOPMENT_LANGUAGE}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>5.7.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>${PODS_DEVELOPMENT_LANGUAGE}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>5.7.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View File

@ -0,0 +1,5 @@
#import <Foundation/Foundation.h>
@interface PodsDummy_SnapKit : NSObject
@end
@implementation PodsDummy_SnapKit
@end

View File

@ -0,0 +1,12 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif

View File

@ -0,0 +1,16 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
FOUNDATION_EXPORT double SnapKitVersionNumber;
FOUNDATION_EXPORT const unsigned char SnapKitVersionString[];

View File

@ -0,0 +1,15 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SnapKit
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift $(SDKROOT)/usr/lib/swift
OTHER_LDFLAGS = $(inherited) -l"swiftCoreGraphics"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/SnapKit
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

View File

@ -0,0 +1,6 @@
framework module SnapKit {
umbrella header "SnapKit-umbrella.h"
export *
module * { export * }
}

View File

@ -0,0 +1,15 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SnapKit
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift $(SDKROOT)/usr/lib/swift
OTHER_LDFLAGS = $(inherited) -l"swiftCoreGraphics"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/SnapKit
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

View File

@ -20,6 +20,7 @@
1A2B3C4D00000015AABBCC01 /* AsyncChapterLoadingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A2B3C4D00000016AABBCC01 /* AsyncChapterLoadingTests.swift */; }; 1A2B3C4D00000015AABBCC01 /* AsyncChapterLoadingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A2B3C4D00000016AABBCC01 /* AsyncChapterLoadingTests.swift */; };
1A2B3C4D00000021AABBCC01 /* MemoryFootprintTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A2B3C4D00000020AABBCC01 /* MemoryFootprintTests.swift */; }; 1A2B3C4D00000021AABBCC01 /* MemoryFootprintTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A2B3C4D00000020AABBCC01 /* MemoryFootprintTests.swift */; };
1A2B3C4D00000030AABBCC01 /* FixedLayoutRotationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A2B3C4D00000031AABBCC01 /* FixedLayoutRotationTests.swift */; }; 1A2B3C4D00000030AABBCC01 /* FixedLayoutRotationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A2B3C4D00000031AABBCC01 /* FixedLayoutRotationTests.swift */; };
1A2B3C4D00000033AABBCC01 /* PDFDrawingModeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A2B3C4D00000032AABBCC01 /* PDFDrawingModeTests.swift */; };
23BB1155EA379786DAA10A89 /* DisplayTypeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB49AFCCBC2BE04C82B8F286 /* DisplayTypeTests.swift */; }; 23BB1155EA379786DAA10A89 /* DisplayTypeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB49AFCCBC2BE04C82B8F286 /* DisplayTypeTests.swift */; };
369C9658D870DCAFC17EB7F7 /* SearchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFE01DBDCB8D790832A4DE3F /* SearchTests.swift */; }; 369C9658D870DCAFC17EB7F7 /* SearchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFE01DBDCB8D790832A4DE3F /* SearchTests.swift */; };
3BC5C96D7A0ACF35F2192CC7 /* XCUIApplication+Launch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74B4C44287820D68ED6570F8 /* XCUIApplication+Launch.swift */; }; 3BC5C96D7A0ACF35F2192CC7 /* XCUIApplication+Launch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74B4C44287820D68ED6570F8 /* XCUIApplication+Launch.swift */; };
@ -27,9 +28,22 @@
52A6A0C9941A4B5F9B88C6B0 /* ReaderAnnotationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20BD15E5D8F04E7E9A239E14 /* ReaderAnnotationTests.swift */; }; 52A6A0C9941A4B5F9B88C6B0 /* ReaderAnnotationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20BD15E5D8F04E7E9A239E14 /* ReaderAnnotationTests.swift */; };
63B2852E59996922386A3111 /* AccessibilityIdentifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00F495E17B90CCF1C7FE8C27 /* AccessibilityIdentifiers.swift */; }; 63B2852E59996922386A3111 /* AccessibilityIdentifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00F495E17B90CCF1C7FE8C27 /* AccessibilityIdentifiers.swift */; };
9AAFB855EC7AC09D1E0B6742 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 697A5BCF0D93DBEC18E21A09 /* Foundation.framework */; }; 9AAFB855EC7AC09D1E0B6742 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 697A5BCF0D93DBEC18E21A09 /* Foundation.framework */; };
A1C5E34F6B7192D400A1B234 /* PDFAnnotationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1C5E34F6B7192D400A1B235 /* PDFAnnotationTests.swift */; };
C08FF8D030048DC5147729E9 /* ReaderOpenCloseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EDF066BA12974E6CFBE519F /* ReaderOpenCloseTests.swift */; }; C08FF8D030048DC5147729E9 /* ReaderOpenCloseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EDF066BA12974E6CFBE519F /* ReaderOpenCloseTests.swift */; };
DE1437A969DA1C5F0CBB047D /* Pods_ReadViewDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 792DF85CE4A3DD80D67843C7 /* Pods_ReadViewDemo.framework */; }; DE1437A969DA1C5F0CBB047D /* Pods_ReadViewDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 792DF85CE4A3DD80D67843C7 /* Pods_ReadViewDemo.framework */; };
FEDB5937CEB858CB06E38E2D /* SettingsPanelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 201C2B482287866487EFAE66 /* SettingsPanelTests.swift */; }; FEDB5937CEB858CB06E38E2D /* SettingsPanelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 201C2B482287866487EFAE66 /* SettingsPanelTests.swift */; };
2B3C4D5E00000001AABBCC01 /* BookmarkChromeStateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B3C4D5E00000001AABBCC02 /* BookmarkChromeStateTests.swift */; };
2B3C4D5E00000002AABBCC01 /* BookmarkManagementTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B3C4D5E00000002AABBCC02 /* BookmarkManagementTests.swift */; };
2B3C4D5E00000003AABBCC01 /* ErrorAndEdgeCaseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B3C4D5E00000003AABBCC02 /* ErrorAndEdgeCaseTests.swift */; };
2B3C4D5E00000004AABBCC01 /* HighlightsManagementTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B3C4D5E00000004AABBCC02 /* HighlightsManagementTests.swift */; };
2B3C4D5E00000005AABBCC01 /* LargeBookOnDemandTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B3C4D5E00000005AABBCC02 /* LargeBookOnDemandTests.swift */; };
2B3C4D5E00000006AABBCC01 /* LocationPersistenceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B3C4D5E00000006AABBCC02 /* LocationPersistenceTests.swift */; };
2B3C4D5E00000007AABBCC01 /* NavigationBackwardTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B3C4D5E00000007AABBCC02 /* NavigationBackwardTests.swift */; };
2B3C4D5E00000008AABBCC01 /* SelectionAnnotateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B3C4D5E00000008AABBCC02 /* SelectionAnnotateTests.swift */; };
2B3C4D5E00000009AABBCC01 /* SelectionMenuTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B3C4D5E00000009AABBCC02 /* SelectionMenuTests.swift */; };
2B3C4D5E0000000AAABBCC01 /* SettingsEffectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B3C4D5E0000000AAABBCC02 /* SettingsEffectTests.swift */; };
2B3C4D5E0000000BAABBCC01 /* TOCInteractionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B3C4D5E0000000BAABBCC02 /* TOCInteractionTests.swift */; };
2B3C4D5E0000000CAABBCC01 /* ToolbarStateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B3C4D5E0000000CAABBCC02 /* ToolbarStateTests.swift */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
@ -57,6 +71,7 @@
1A2B3C4D00000016AABBCC01 /* AsyncChapterLoadingTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = AsyncChapterLoadingTests.swift; sourceTree = "<group>"; }; 1A2B3C4D00000016AABBCC01 /* AsyncChapterLoadingTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = AsyncChapterLoadingTests.swift; sourceTree = "<group>"; };
1A2B3C4D00000020AABBCC01 /* MemoryFootprintTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = MemoryFootprintTests.swift; sourceTree = "<group>"; }; 1A2B3C4D00000020AABBCC01 /* MemoryFootprintTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = MemoryFootprintTests.swift; sourceTree = "<group>"; };
1A2B3C4D00000031AABBCC01 /* FixedLayoutRotationTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = FixedLayoutRotationTests.swift; sourceTree = "<group>"; }; 1A2B3C4D00000031AABBCC01 /* FixedLayoutRotationTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = FixedLayoutRotationTests.swift; sourceTree = "<group>"; };
1A2B3C4D00000032AABBCC01 /* PDFDrawingModeTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = PDFDrawingModeTests.swift; sourceTree = "<group>"; };
201C2B482287866487EFAE66 /* SettingsPanelTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SettingsPanelTests.swift; sourceTree = "<group>"; }; 201C2B482287866487EFAE66 /* SettingsPanelTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SettingsPanelTests.swift; sourceTree = "<group>"; };
20BD15E5D8F04E7E9A239E14 /* ReaderAnnotationTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ReaderAnnotationTests.swift; sourceTree = "<group>"; }; 20BD15E5D8F04E7E9A239E14 /* ReaderAnnotationTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ReaderAnnotationTests.swift; sourceTree = "<group>"; };
3A43AED288BFCA3ADBA97DD7 /* Pods-ReadViewDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReadViewDemo.release.xcconfig"; path = "Target Support Files/Pods-ReadViewDemo/Pods-ReadViewDemo.release.xcconfig"; sourceTree = "<group>"; }; 3A43AED288BFCA3ADBA97DD7 /* Pods-ReadViewDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReadViewDemo.release.xcconfig"; path = "Target Support Files/Pods-ReadViewDemo/Pods-ReadViewDemo.release.xcconfig"; sourceTree = "<group>"; };
@ -66,10 +81,23 @@
792DF85CE4A3DD80D67843C7 /* Pods_ReadViewDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ReadViewDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 792DF85CE4A3DD80D67843C7 /* Pods_ReadViewDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ReadViewDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; };
8FFD606A5A1CBDCC3CA87F1C /* ReadViewDemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ReadViewDemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 8FFD606A5A1CBDCC3CA87F1C /* ReadViewDemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ReadViewDemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
9EDF066BA12974E6CFBE519F /* ReaderOpenCloseTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ReaderOpenCloseTests.swift; sourceTree = "<group>"; }; 9EDF066BA12974E6CFBE519F /* ReaderOpenCloseTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ReaderOpenCloseTests.swift; sourceTree = "<group>"; };
A1C5E34F6B7192D400A1B235 /* PDFAnnotationTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = PDFAnnotationTests.swift; sourceTree = "<group>"; };
BADF0A18AD034B74A482A4C1 /* ReaderToolbarTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ReaderToolbarTests.swift; sourceTree = "<group>"; }; BADF0A18AD034B74A482A4C1 /* ReaderToolbarTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ReaderToolbarTests.swift; sourceTree = "<group>"; };
CFE01DBDCB8D790832A4DE3F /* SearchTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SearchTests.swift; sourceTree = "<group>"; }; CFE01DBDCB8D790832A4DE3F /* SearchTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SearchTests.swift; sourceTree = "<group>"; };
DE070C1D2FBF0CC900ED065F /* ReadViewDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ReadViewDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; DE070C1D2FBF0CC900ED065F /* ReadViewDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ReadViewDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
FB49AFCCBC2BE04C82B8F286 /* DisplayTypeTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DisplayTypeTests.swift; sourceTree = "<group>"; }; FB49AFCCBC2BE04C82B8F286 /* DisplayTypeTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DisplayTypeTests.swift; sourceTree = "<group>"; };
2B3C4D5E00000001AABBCC02 /* BookmarkChromeStateTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = BookmarkChromeStateTests.swift; sourceTree = "<group>"; };
2B3C4D5E00000002AABBCC02 /* BookmarkManagementTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = BookmarkManagementTests.swift; sourceTree = "<group>"; };
2B3C4D5E00000003AABBCC02 /* ErrorAndEdgeCaseTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ErrorAndEdgeCaseTests.swift; sourceTree = "<group>"; };
2B3C4D5E00000004AABBCC02 /* HighlightsManagementTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = HighlightsManagementTests.swift; sourceTree = "<group>"; };
2B3C4D5E00000005AABBCC02 /* LargeBookOnDemandTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = LargeBookOnDemandTests.swift; sourceTree = "<group>"; };
2B3C4D5E00000006AABBCC02 /* LocationPersistenceTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = LocationPersistenceTests.swift; sourceTree = "<group>"; };
2B3C4D5E00000007AABBCC02 /* NavigationBackwardTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = NavigationBackwardTests.swift; sourceTree = "<group>"; };
2B3C4D5E00000008AABBCC02 /* SelectionAnnotateTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SelectionAnnotateTests.swift; sourceTree = "<group>"; };
2B3C4D5E00000009AABBCC02 /* SelectionMenuTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SelectionMenuTests.swift; sourceTree = "<group>"; };
2B3C4D5E0000000AAABBCC02 /* SettingsEffectTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SettingsEffectTests.swift; sourceTree = "<group>"; };
2B3C4D5E0000000BAABBCC02 /* TOCInteractionTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = TOCInteractionTests.swift; sourceTree = "<group>"; };
2B3C4D5E0000000CAABBCC02 /* ToolbarStateTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ToolbarStateTests.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ /* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
@ -184,6 +212,19 @@
1A2B3C4D00000002AABBCC01 /* BookmarkTests.swift */, 1A2B3C4D00000002AABBCC01 /* BookmarkTests.swift */,
FB49AFCCBC2BE04C82B8F286 /* DisplayTypeTests.swift */, FB49AFCCBC2BE04C82B8F286 /* DisplayTypeTests.swift */,
1A2B3C4D00000008AABBCC01 /* PageNavigationTests.swift */, 1A2B3C4D00000008AABBCC01 /* PageNavigationTests.swift */,
A1C5E34F6B7192D400A1B235 /* PDFAnnotationTests.swift */,
2B3C4D5E00000001AABBCC02 /* BookmarkChromeStateTests.swift */,
2B3C4D5E00000002AABBCC02 /* BookmarkManagementTests.swift */,
2B3C4D5E00000003AABBCC02 /* ErrorAndEdgeCaseTests.swift */,
2B3C4D5E00000004AABBCC02 /* HighlightsManagementTests.swift */,
2B3C4D5E00000005AABBCC02 /* LargeBookOnDemandTests.swift */,
2B3C4D5E00000006AABBCC02 /* LocationPersistenceTests.swift */,
2B3C4D5E00000007AABBCC02 /* NavigationBackwardTests.swift */,
2B3C4D5E00000008AABBCC02 /* SelectionAnnotateTests.swift */,
2B3C4D5E00000009AABBCC02 /* SelectionMenuTests.swift */,
2B3C4D5E0000000AAABBCC02 /* SettingsEffectTests.swift */,
2B3C4D5E0000000BAABBCC02 /* TOCInteractionTests.swift */,
2B3C4D5E0000000CAABBCC02 /* ToolbarStateTests.swift */,
20BD15E5D8F04E7E9A239E14 /* ReaderAnnotationTests.swift */, 20BD15E5D8F04E7E9A239E14 /* ReaderAnnotationTests.swift */,
1A2B3C4D0000000AAABBCC01 /* ReaderAnnotationExtendedTests.swift */, 1A2B3C4D0000000AAABBCC01 /* ReaderAnnotationExtendedTests.swift */,
9EDF066BA12974E6CFBE519F /* ReaderOpenCloseTests.swift */, 9EDF066BA12974E6CFBE519F /* ReaderOpenCloseTests.swift */,
@ -199,6 +240,7 @@
1A2B3C4D00000020AABBCC01 /* MemoryFootprintTests.swift */, 1A2B3C4D00000020AABBCC01 /* MemoryFootprintTests.swift */,
1A2B3C4D00000016AABBCC01 /* AsyncChapterLoadingTests.swift */, 1A2B3C4D00000016AABBCC01 /* AsyncChapterLoadingTests.swift */,
1A2B3C4D00000031AABBCC01 /* FixedLayoutRotationTests.swift */, 1A2B3C4D00000031AABBCC01 /* FixedLayoutRotationTests.swift */,
1A2B3C4D00000032AABBCC01 /* PDFDrawingModeTests.swift */,
); );
path = ReaderUITests; path = ReaderUITests;
sourceTree = "<group>"; sourceTree = "<group>";
@ -351,6 +393,19 @@
1A2B3C4D00000001AABBCC01 /* BookmarkTests.swift in Sources */, 1A2B3C4D00000001AABBCC01 /* BookmarkTests.swift in Sources */,
23BB1155EA379786DAA10A89 /* DisplayTypeTests.swift in Sources */, 23BB1155EA379786DAA10A89 /* DisplayTypeTests.swift in Sources */,
1A2B3C4D00000007AABBCC01 /* PageNavigationTests.swift in Sources */, 1A2B3C4D00000007AABBCC01 /* PageNavigationTests.swift in Sources */,
A1C5E34F6B7192D400A1B234 /* PDFAnnotationTests.swift in Sources */,
2B3C4D5E00000001AABBCC01 /* BookmarkChromeStateTests.swift in Sources */,
2B3C4D5E00000002AABBCC01 /* BookmarkManagementTests.swift in Sources */,
2B3C4D5E00000003AABBCC01 /* ErrorAndEdgeCaseTests.swift in Sources */,
2B3C4D5E00000004AABBCC01 /* HighlightsManagementTests.swift in Sources */,
2B3C4D5E00000005AABBCC01 /* LargeBookOnDemandTests.swift in Sources */,
2B3C4D5E00000006AABBCC01 /* LocationPersistenceTests.swift in Sources */,
2B3C4D5E00000007AABBCC01 /* NavigationBackwardTests.swift in Sources */,
2B3C4D5E00000008AABBCC01 /* SelectionAnnotateTests.swift in Sources */,
2B3C4D5E00000009AABBCC01 /* SelectionMenuTests.swift in Sources */,
2B3C4D5E0000000AAABBCC01 /* SettingsEffectTests.swift in Sources */,
2B3C4D5E0000000BAABBCC01 /* TOCInteractionTests.swift in Sources */,
2B3C4D5E0000000CAABBCC01 /* ToolbarStateTests.swift in Sources */,
52A6A0C9941A4B5F9B88C6B0 /* ReaderAnnotationTests.swift in Sources */, 52A6A0C9941A4B5F9B88C6B0 /* ReaderAnnotationTests.swift in Sources */,
1A2B3C4D00000009AABBCC01 /* ReaderAnnotationExtendedTests.swift in Sources */, 1A2B3C4D00000009AABBCC01 /* ReaderAnnotationExtendedTests.swift in Sources */,
C08FF8D030048DC5147729E9 /* ReaderOpenCloseTests.swift in Sources */, C08FF8D030048DC5147729E9 /* ReaderOpenCloseTests.swift in Sources */,
@ -366,6 +421,7 @@
1A2B3C4D00000021AABBCC01 /* MemoryFootprintTests.swift in Sources */, 1A2B3C4D00000021AABBCC01 /* MemoryFootprintTests.swift in Sources */,
1A2B3C4D00000015AABBCC01 /* AsyncChapterLoadingTests.swift in Sources */, 1A2B3C4D00000015AABBCC01 /* AsyncChapterLoadingTests.swift in Sources */,
1A2B3C4D00000030AABBCC01 /* FixedLayoutRotationTests.swift in Sources */, 1A2B3C4D00000030AABBCC01 /* FixedLayoutRotationTests.swift in Sources */,
1A2B3C4D00000033AABBCC01 /* PDFDrawingModeTests.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View File

@ -0,0 +1,294 @@
import UIKit
import PDFKit
import CryptoKit
import RDPDFReaderView
/// Demo 宿 PDF OCR
enum PDFDemoImageTextSource: String {
case hostFixture = "host-fixture"
case vision
case none
}
/// 宿 PDF
private final class PDFDemoPageProvider: RDPDFReaderPageProvider, RDPDFReaderOutlineProviding, RDPDFReaderAsyncOutlineProviding {
private let document: PDFDocument
private let identifier: String
private let title: String
private let textSource: PDFDemoImageTextSource
private let renderQueue = DispatchQueue(label: "com.readviewsdk.demo-pdf-render", qos: .userInitiated)
private let images = NSCache<NSNumber, UIImage>()
private var outlineItemsCache: [RDPDFReaderOutlineItem]?
init(document: PDFDocument, identifier: String, title: String, textSource: PDFDemoImageTextSource) {
self.document = document
self.identifier = identifier
self.title = title
self.textSource = textSource
images.countLimit = 6
images.totalCostLimit = 96 * 1024 * 1024
}
func readerBookDescriptor() -> RDPDFReaderBookDescriptor {
.init(identifier: identifier, title: title, totalPages: document.pageCount)
}
func readerPage(at index: Int, completion: @escaping (RDPDFReaderPageDescriptor) -> Void) {
let textRuns: [RDPDFReaderTextRun]?
switch textSource {
case .hostFixture: textRuns = fixtureTextRuns(for: index)
case .vision, .none: textRuns = nil
}
renderQueue.async { [weak self] in
guard let self else { return }
let image = self.image(at: index)
DispatchQueue.main.async { completion(.init(index: index, image: image, textRuns: textRuns)) }
}
}
func readerThumbnail(at index: Int, targetSize: CGSize, completion: @escaping (UIImage?) -> Void) {
renderQueue.async { [weak self] in
guard let self, let page = self.document.page(at: index) else {
DispatchQueue.main.async { completion(nil) }
return
}
let box = page.bounds(for: .mediaBox)
let scale = min(targetSize.width / box.width, targetSize.height / box.height) * UIScreen.main.scale
let size = CGSize(width: box.width * scale, height: box.height * scale)
let image = self.render(page, size: size, scale: scale)
DispatchQueue.main.async { completion(image) }
}
}
func readerOutlineItems() -> [RDPDFReaderOutlineItem] {
renderQueue.sync { outlineItemsLocked() }
}
func readerOutlineItems(completion: @escaping ([RDPDFReaderOutlineItem]) -> Void) {
renderQueue.async { [weak self] in
guard let self else { return }
let items = self.outlineItemsLocked()
DispatchQueue.main.async { completion(items) }
}
}
private func outlineItemsLocked() -> [RDPDFReaderOutlineItem] {
if let outlineItemsCache { return outlineItemsCache }
guard let root = document.outlineRoot else {
let items = pageOutlineItems()
outlineItemsCache = items
return items
}
var items: [RDPDFReaderOutlineItem] = []
func append(_ outline: PDFOutline, level: Int) {
for index in 0..<outline.numberOfChildren {
guard let child = outline.child(at: index) else { continue }
if let page = child.destination?.page {
let pageIndex = document.index(for: page)
items.append(.init(title: child.label ?? "\(pageIndex + 1)", pageIndex: pageIndex, level: level))
}
append(child, level: level + 1)
}
}
append(root, level: 0)
let resolved = items.isEmpty ? pageOutlineItems() : items
outlineItemsCache = resolved
return resolved
}
func transformed(_ image: UIImage, for theme: RDPDFReaderThemeOption) -> UIImage {
// PDFKit SDK
guard theme.identifier != 0 else { return image }
if theme.identifier == 5, let ciImage = CIImage(image: image), let filter = CIFilter(name: "CIColorInvert") {
filter.setValue(ciImage, forKey: kCIInputImageKey)
if let output = filter.outputImage, let cgImage = CIContext().createCGImage(output, from: output.extent) {
return UIImage(cgImage: cgImage, scale: image.scale, orientation: image.imageOrientation)
}
}
let renderer = UIGraphicsImageRenderer(size: image.size)
return renderer.image { _ in
theme.contentBackgroundColor.setFill()
UIBezierPath(rect: CGRect(origin: .zero, size: image.size)).fill()
image.draw(in: CGRect(origin: .zero, size: image.size), blendMode: .multiply, alpha: 1)
}
}
private func image(at index: Int) -> UIImage? {
if let image = images.object(forKey: NSNumber(value: index)) { return image }
guard let page = document.page(at: index) else { return nil }
let box = page.bounds(for: .mediaBox)
let scale = max(2, UIScreen.main.scale)
let image = render(page, size: CGSize(width: box.width * scale, height: box.height * scale), scale: scale)
let cost = image.cgImage.map { $0.bytesPerRow * $0.height }
?? Int(image.size.width * image.size.height * image.scale * image.scale * 4)
images.setObject(image, forKey: NSNumber(value: index), cost: cost)
return image
}
private func render(_ page: PDFPage, size: CGSize, scale: CGFloat) -> UIImage {
UIGraphicsImageRenderer(size: size).image { context in
UIColor.white.setFill()
context.fill(CGRect(origin: .zero, size: size))
context.cgContext.translateBy(x: 0, y: size.height)
context.cgContext.scaleBy(x: scale, y: -scale)
page.draw(with: .mediaBox, to: context.cgContext)
}
}
private func fixtureTextRuns(for page: Int) -> [RDPDFReaderTextRun] {
[
.init(text: page == 0 ? "PDF 图像文本选择测试" : "\(page + 1) 页图像文本", normalizedRect: CGRect(x: 0.12, y: 0.14, width: 0.76, height: 0.14), readingOrder: 0),
.init(text: "可复制、高亮与注释", normalizedRect: CGRect(x: 0.12, y: 0.30, width: 0.70, height: 0.08), readingOrder: 1)
]
}
private func pageOutlineItems() -> [RDPDFReaderOutlineItem] {
(0..<document.pageCount).map { .init(title: "\($0 + 1)", pageIndex: $0) }
}
}
/// Demo 宿
final class PDFDemoReaderViewController: UIViewController, RDPDFReaderViewControllerDelegate {
private static let annotationStorageFolderName = "RDPDFImageReaderAnnotations"
private let reader: RDPDFReaderViewController
private var navigationBarHiddenBeforeReader: Bool?
private var display = "pagecurl"
private var lastPageIndex = 0
private var lastCopiedText: String?
private let stateLabel: UILabel = {
let label = UILabel()
label.accessibilityIdentifier = "demo.reader.state"
label.isAccessibilityElement = true
label.alpha = 0.01
return label
}()
init(url: URL, bookIdentifier: String? = nil, textSource: PDFDemoImageTextSource = .vision) {
let identifier = bookIdentifier ?? url.lastPathComponent
let store = RDPDFReaderPersistenceStore(rootURL: Self.annotationStorageURL(for: identifier, legacyBookURL: url))
var configuration = RDPDFReaderViewController.Configuration()
configuration.enablesOCR = textSource == .vision
configuration.missingTextSource = .region
configuration.recognitionLanguages = ["zh-Hans", "en-US"]
if textSource != .vision {
guard let document = PDFDocument(url: url) else { fatalError("无法打开 PDF") }
let provider = PDFDemoPageProvider(
document: document,
identifier: identifier,
title: url.deletingPathExtension().lastPathComponent,
textSource: textSource
)
configuration.pageImageTransform = { [weak provider] image, theme in
provider?.transformed(image, for: theme) ?? image
}
reader = RDPDFReaderViewController(
pageProvider: provider,
annotationPersistence: store,
configuration: configuration
)
} else {
do {
reader = try RDPDFReaderViewController(
pdfURL: url,
bookIdentifier: identifier,
annotationPersistence: store,
configuration: configuration
)
} catch {
fatalError("无法打开 PDF\(error.localizedDescription)")
}
}
super.init(nibName: nil, bundle: nil)
reader.delegate = self
title = url.deletingPathExtension().lastPathComponent
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
override func viewDidLoad() {
super.viewDidLoad()
addChild(reader)
reader.view.frame = view.bounds
reader.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(reader.view)
reader.didMove(toParent: self)
stateLabel.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(stateLabel)
NSLayoutConstraint.activate([stateLabel.widthAnchor.constraint(equalToConstant: 1), stateLabel.heightAnchor.constraint(equalToConstant: 1), stateLabel.topAnchor.constraint(equalTo: view.topAnchor), stateLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor)])
updateState(page: 0)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if navigationBarHiddenBeforeReader == nil { navigationBarHiddenBeforeReader = navigationController?.isNavigationBarHidden }
navigationController?.setNavigationBarHidden(true, animated: animated)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if let hidden = navigationBarHiddenBeforeReader { navigationController?.setNavigationBarHidden(hidden, animated: animated) }
}
func applyDemoDisplayType(_ type: RDPDFReaderView.DisplayType) {
reader.switchDisplayType(type)
display = type == .pageCurl ? "pagecurl" : (type == .verticalScroll ? "verticalscroll" : "horizontalscroll")
updateState(page: 0)
}
func goToDemoPage(_ pageNumber: Int) { reader.goToPage(max(pageNumber - 1, 0)) }
func pdfReaderViewControllerDidRequestClose(_ controller: RDPDFReaderViewController) {
if let navigationController, navigationController.viewControllers.count > 1 { navigationController.popViewController(animated: true) }
else { dismiss(animated: true) }
}
func pdfReaderViewController(_ controller: RDPDFReaderViewController, didChangePage pageIndex: Int) { updateState(page: pageIndex) }
func pdfReaderViewController(_ controller: RDPDFReaderViewController, didCopyText text: String) {
lastCopiedText = text
updateState(page: lastPageIndex)
}
func pdfReaderViewController(_ controller: RDPDFReaderViewController, didFailAnnotationPersistence error: Error) {
stateLabel.text = "reader=opened mode=pdf annotationStorage=error"
guard presentedViewController == nil else { return }
let alert = UIAlertController(title: "标注未保存", message: error.localizedDescription, preferredStyle: .alert)
alert.addAction(.init(title: "知道了", style: .default))
present(alert, animated: true)
}
private func updateState(page: Int) {
lastPageIndex = page
var state = "reader=opened mode=pdf page=\(page + 1) display=\(display)"
if let lastCopiedText {
// UI
let encoded = lastCopiedText.addingPercentEncoding(withAllowedCharacters: .alphanumerics) ?? ""
state += " copy=success copiedText=\(encoded)"
}
stateLabel.text = state
}
private static func annotationStorageURL(for bookIdentifier: String, legacyBookURL: URL) -> URL {
let root = annotationStorageRoot()
let hash = SHA256.hash(data: bookIdentifier.data(using: .utf8) ?? Data()).map { String(format: "%02x", $0) }.joined()
let destination = root.appendingPathComponent(hash, isDirectory: true)
migrateLegacyAnnotationsIfNeeded(from: legacyBookURL, to: destination)
return destination
}
private static func annotationStorageRoot() -> URL {
(FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first ?? FileManager.default.temporaryDirectory).appendingPathComponent(annotationStorageFolderName, isDirectory: true)
}
private static func migrateLegacyAnnotationsIfNeeded(from url: URL, to destination: URL) {
let manager = FileManager.default
guard !manager.fileExists(atPath: destination.path) else { return }
let legacyName = (url.standardizedFileURL.path.data(using: .utf8) ?? Data()).base64EncodedString().replacingOccurrences(of: "/", with: "_").replacingOccurrences(of: "+", with: "-").replacingOccurrences(of: "=", with: "")
let legacy = annotationStorageRoot().appendingPathComponent(legacyName, isDirectory: true)
guard let data = try? Data(contentsOf: legacy.appendingPathComponent("annotations.json")), (try? JSONDecoder().decode([RDPDFReaderAnnotation].self, from: data)) != nil else { return }
try? manager.createDirectory(at: destination.deletingLastPathComponent(), withIntermediateDirectories: true)
try? manager.copyItem(at: legacy, to: destination)
}
static func resetPersistedAnnotations() { try? FileManager.default.removeItem(at: annotationStorageRoot()) }
}

View File

@ -1,5 +1,6 @@
import UIKit import UIKit
import RDEpubReaderView import RDEpubReaderView
import RDPDFReaderView
final class ViewController: UIViewController { final class ViewController: UIViewController {
private struct DemoBook: Equatable { private struct DemoBook: Equatable {
@ -22,6 +23,7 @@ final class ViewController: UIViewController {
let allowsInspectableWebViews: Bool let allowsInspectableWebViews: Bool
let enablesVerboseWebLogs: Bool let enablesVerboseWebLogs: Bool
let searchKeyword: String? let searchKeyword: String?
let pdfTextSource: String?
nonisolated private static func parseDisplayType(_ rawValue: String) -> RDEpubReaderView.DisplayType? { nonisolated private static func parseDisplayType(_ rawValue: String) -> RDEpubReaderView.DisplayType? {
switch rawValue.lowercased() { switch rawValue.lowercased() {
@ -64,6 +66,7 @@ final class ViewController: UIViewController {
let allowsInspectableWebViews = arguments.contains("--demo-allow-inspectable-webviews") let allowsInspectableWebViews = arguments.contains("--demo-allow-inspectable-webviews")
let enablesVerboseWebLogs = arguments.contains("--demo-enable-verbose-weblogs") let enablesVerboseWebLogs = arguments.contains("--demo-enable-verbose-weblogs")
let searchKeyword = value(after: "--demo-search-keyword") let searchKeyword = value(after: "--demo-search-keyword")
let pdfTextSource = value(after: "--demo-pdf-text-source")
return LaunchAutomationPlan( return LaunchAutomationPlan(
bookTitleQuery: bookTitleQuery, bookTitleQuery: bookTitleQuery,
@ -78,7 +81,8 @@ final class ViewController: UIViewController {
corruptsCache: corruptsCache, corruptsCache: corruptsCache,
allowsInspectableWebViews: allowsInspectableWebViews, allowsInspectableWebViews: allowsInspectableWebViews,
enablesVerboseWebLogs: enablesVerboseWebLogs, enablesVerboseWebLogs: enablesVerboseWebLogs,
searchKeyword: searchKeyword searchKeyword: searchKeyword,
pdfTextSource: pdfTextSource
) )
} }
} }
@ -108,7 +112,7 @@ final class ViewController: UIViewController {
label.textAlignment = .center label.textAlignment = .center
label.textColor = .secondaryLabel label.textColor = .secondaryLabel
label.font = .systemFont(ofSize: 15) label.font = .systemFont(ofSize: 15)
label.text = "book 目录下暂时没有可阅读的 txt 或 epub 文件" label.text = "book 目录下暂时没有可阅读的 EPUB、TXT、MOBI、CBZ 或 PDF 文件"
label.accessibilityIdentifier = "demo.books.empty" label.accessibilityIdentifier = "demo.books.empty"
return label return label
}() }()
@ -161,7 +165,7 @@ final class ViewController: UIViewController {
private func updateChrome() { private func updateChrome() {
if books.isEmpty { if books.isEmpty {
statusLabel.text = "ReadViewSDK Demo\nbook 目录下未找到 txt 或 epub 文件" statusLabel.text = "ReadViewSDK Demo\nbook 目录下未找到 EPUB、TXT、MOBI、CBZ 或 PDF 文件"
tableView.backgroundView = emptyStateLabel tableView.backgroundView = emptyStateLabel
} else { } else {
statusLabel.text = "ReadViewSDK Demo\n已发现 \(books.count) 本本地图书,点击即可进入阅读器" statusLabel.text = "ReadViewSDK Demo\n已发现 \(books.count) 本本地图书,点击即可进入阅读器"
@ -187,7 +191,7 @@ final class ViewController: UIViewController {
return fileURLs return fileURLs
.filter { url in .filter { url in
let ext = url.pathExtension.lowercased() let ext = url.pathExtension.lowercased()
return ext == "epub" || ext == "txt" return RDReaderDocumentFormat.supports(url) || ext == "pdf"
} }
.reduce(into: [URL]()) { result, url in .reduce(into: [URL]()) { result, url in
if !result.contains(url) { if !result.contains(url) {
@ -252,6 +256,47 @@ final class ViewController: UIViewController {
return controller return controller
} }
@discardableResult
private func openPDFBook(
_ book: DemoBook,
automationPlan: LaunchAutomationPlan? = nil
) -> PDFDemoReaderViewController {
let textSource = automationPlan?.pdfTextSource
.flatMap(PDFDemoImageTextSource.init(rawValue:)) ?? .vision
// Demo bundle 宿 ID
//
let controller = PDFDemoReaderViewController(
url: book.fileURL,
bookIdentifier: "demo.pdf.\(book.fileURL.lastPathComponent)",
textSource: textSource
)
if let navigationController {
navigationController.pushViewController(controller, animated: true)
} else {
let hostController = UINavigationController(rootViewController: controller)
hostController.modalPresentationStyle = .fullScreen
hostController.view.accessibilityIdentifier = "demo.pdf-reader.host"
present(hostController, animated: true)
}
if let automationPlan {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak controller] in
if let displayType = automationPlan.displayType {
let pdfDisplayType: RDPDFReaderView.DisplayType
switch displayType {
case .pageCurl: pdfDisplayType = .pageCurl
case .horizontalScroll: pdfDisplayType = .horizontalScroll
case .verticalScroll: pdfDisplayType = .verticalScroll
}
controller?.applyDemoDisplayType(pdfDisplayType)
}
if let pageNumber = automationPlan.pageNumber {
controller?.goToDemoPage(pageNumber)
}
}
}
return controller
}
private func runLaunchAutomationIfNeeded() { private func runLaunchAutomationIfNeeded() {
guard !didRunLaunchAutomation, guard !didRunLaunchAutomation,
let launchAutomationPlan, let launchAutomationPlan,
@ -287,7 +332,11 @@ final class ViewController: UIViewController {
} }
configuration.allowsInspectableWebViews = launchAutomationPlan.allowsInspectableWebViews configuration.allowsInspectableWebViews = launchAutomationPlan.allowsInspectableWebViews
configuration.enablesVerboseWebViewLogging = launchAutomationPlan.enablesVerboseWebLogs configuration.enablesVerboseWebViewLogging = launchAutomationPlan.enablesVerboseWebLogs
_ = openBook(book, configuration: configuration, automationPlan: launchAutomationPlan) if book.fileURL.pathExtension.lowercased() == "pdf" {
_ = openPDFBook(book, automationPlan: launchAutomationPlan)
} else {
_ = openBook(book, configuration: configuration, automationPlan: launchAutomationPlan)
}
} }
private func resetPersistedReaderState() { private func resetPersistedReaderState() {
@ -304,6 +353,7 @@ final class ViewController: UIViewController {
defaults.removeObject(forKey: key) defaults.removeObject(forKey: key)
} }
} }
PDFDemoReaderViewController.resetPersistedAnnotations()
} }
private func clearChapterSummaryCache() { private func clearChapterSummaryCache() {
@ -354,6 +404,11 @@ extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true) tableView.deselectRow(at: indexPath, animated: true)
guard books.indices.contains(indexPath.row) else { return } guard books.indices.contains(indexPath.row) else { return }
openBook(books[indexPath.row]) let book = books[indexPath.row]
if book.fileURL.pathExtension.lowercased() == "pdf" {
_ = openPDFBook(book)
} else {
openBook(book)
}
} }
} }

Binary file not shown.

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
<rootfiles>
<rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml"/>
</rootfiles>
</container>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 482 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 507 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 561 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 397 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 571 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 262 KiB

Some files were not shown because too many files have changed in this diff Show More