From 18924a30e255dbce112b231b42fec09fcb2e1042 Mon Sep 17 00:00:00 2001
From: LEE <18611401994@163.com>
Date: Mon, 11 Oct 2021 14:22:17 +0800
Subject: [PATCH] =?UTF-8?q?=E5=88=9B=E5=BB=BASPM=E5=92=8CFramework?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../contents.xcworkspacedata | 7 +
.../xcshareddata/IDEWorkspaceChecks.plist | 8 +
Package.swift | 28 +
README.md | 185 ++++++-
README_CN.md | 180 +++++++
Sources/Screen/UIAdapter.Screen.swift | 288 +++++++++++
Sources/UIAdapter.h | 18 +
Sources/Zoom/UIAdapter.Zoom.swift | 486 ++++++++++++++++++
Tests/UIAdapterTests/UIAdapterTests.swift | 11 +
UIAdapter.podspec | 25 +
UIAdapter.xcodeproj/project.pbxproj | 362 +++++++++++++
.../contents.xcworkspacedata | 7 +
.../xcshareddata/IDEWorkspaceChecks.plist | 8 +
13 files changed, 1611 insertions(+), 2 deletions(-)
create mode 100644 .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
create mode 100644 .swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
create mode 100644 Package.swift
create mode 100644 README_CN.md
create mode 100644 Sources/Screen/UIAdapter.Screen.swift
create mode 100644 Sources/UIAdapter.h
create mode 100644 Sources/Zoom/UIAdapter.Zoom.swift
create mode 100644 Tests/UIAdapterTests/UIAdapterTests.swift
create mode 100644 UIAdapter.podspec
create mode 100644 UIAdapter.xcodeproj/project.pbxproj
create mode 100644 UIAdapter.xcodeproj/project.xcworkspace/contents.xcworkspacedata
create mode 100644 UIAdapter.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
diff --git a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/Package.swift b/Package.swift
new file mode 100644
index 0000000..da09dc7
--- /dev/null
+++ b/Package.swift
@@ -0,0 +1,28 @@
+// swift-tools-version:5.5
+// The swift-tools-version declares the minimum version of Swift required to build this package.
+
+import PackageDescription
+
+let package = Package(
+ name: "UIAdapter",
+ platforms: [.iOS(.v9)],
+ products: [
+ // Products define the executables and libraries a package produces, and make them visible to other packages.
+ .library(
+ name: "UIAdapter",
+ targets: ["UIAdapter"]),
+ ],
+ dependencies: [
+ // Dependencies declare other packages that this package depends on.
+ // .package(url: /* package url */, from: "1.0.0"),
+ ],
+ targets: [
+ // Targets are the basic building blocks of a package. A target can define a module or a test suite.
+ // Targets can depend on other targets in this package, and on products in packages this package depends on.
+ .target(
+ name: "UIAdapter",
+ dependencies: [],
+ path: "Sources"
+ )
+ ]
+)
diff --git a/README.md b/README.md
index f4f200d..731eff0 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,183 @@
-# ScreenAdapter
-屏幕适配器
+# UIAdapter - 等比例缩放屏幕适配
+
+[![License](https://img.shields.io/cocoapods/l/UIAdapter.svg)](LICENSE)
+![Swift](https://img.shields.io/badge/Swift-5.2-orange.svg)
+![Platform](https://img.shields.io/cocoapods/p/UIAdapter.svg?style=flat)
+[![Swift Package Manager](https://img.shields.io/badge/Swift_Package_Manager-compatible-4BC51D.svg?style=flat")](https://swift.org/package-manager/)
+[![Carthage](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
+[![Cocoapods](https://img.shields.io/cocoapods/v/UIAdapter.svg)](https://cocoapods.org)
+
+## [:cn:天朝子民](README_CN.md)
+
+## Features
+
+- [x] Numerical type fast conversion
+- [x] Storyboard equal scale adaptation
+- [x] Xib equal scale adaptation
+- [x] Custom calculation processing
+- [x] Quick match for each screen size type
+
+
+## Installation
+
+**CocoaPods - Podfile**
+
+```ruby
+pod 'UIAdapter'
+```
+
+**Carthage - Cartfile**
+
+```ruby
+github "lixiang1994/UIAdapter"
+```
+
+#### [Swift Package Manager for Apple platforms](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app)
+
+Select Xcode menu `File > Swift Packages > Add Package Dependency` and enter repository URL with GUI.
+```
+Repository: https://github.com/lixiang1994/UIAdapter
+```
+
+#### [Swift Package Manager](https://swift.org/package-manager/)
+
+Add the following to the dependencies of your `Package.swift`:
+```swift
+.package(url: "https://github.com/lixiang1994/UIAdapter.git", from: "version")
+```
+
+## Usage
+
+First make sure to import the framework:
+
+```swift
+import UIAdapter
+```
+
+Here are some usage examples. All devices are also available as simulators:
+
+
+### Auto
+
+
+AutoLayout (SnapKit):
+
+```swift
+private func setupLayout() {
+ cardView.snp.makeConstraints { (make) in
+ make.top.equalTo(16.auto())
+ make.left.right.equalToSuperview().inset(15.auto())
+ make.bottom.equalTo(-26.auto())
+ }
+
+ lineView.snp.makeConstraints { (make) in
+ make.left.right.equalToSuperview().inset(15.auto())
+ make.top.equalTo(titleLabel.snp.bottom)
+ make.height.equalTo(1)
+ }
+
+ titleLabel.snp.makeConstraints { (make) in
+ make.top.equalToSuperview()
+ make.left.equalTo(15.auto())
+ make.height.equalTo(48.auto())
+ }
+
+ stateLabel.snp.makeConstraints { (make) in
+ make.top.equalTo(lineView).offset(10.auto())
+ make.left.equalTo(15.auto())
+ make.height.equalTo(15.auto())
+ }
+}
+```
+
+Property (Then):
+
+```swift
+private lazy var cardView = UIView().then {
+ $0.cornerRadius = 6.auto()
+ $0.backgroundColor = .white
+}
+
+private lazy var lineView = UIView().then {
+ $0.backgroundColor = .hex("000000", alpha: 0.05)
+}
+
+private lazy var titleLabel = UILabel().then {
+ $0.textColor = .black
+ $0.font = .systemFont(ofSize: 20.auto(), weight: .medium)
+}
+
+private lazy var stateLabel = UILabel().then {
+ $0.textColor = .gray
+ $0.font = .systemFont(ofSize: 12.auto(), weight: .medium)
+}
+```
+
+Storyboard / Xib:
+
+![Constraint](Resources/Storyboard%20Constraint.png)
+![UILabel Font](Resources/Storyboard%20Label%20Font.png)
+
+### Screen
+
+e.g.
+
+```swift
+// default other screen numberOfLines = 0
+// 3.5 inches screen numberOfLines = 1
+// 4.0 inches screen numberOfLines = 2
+label.numberOfLines = 0.screen.inch(._3_5, is: 1).inch(._4_0, is: 2).value
+```
+
+
+```swift
+// default other screen numberOfLines = 0
+// width 320 screen numberOfLines = 1
+// width 375 inches screen numberOfLines = 2
+label.numberOfLines = 0.screen.width(._320, is: 1).width(._375, is: 2).value
+```
+
+
+```swift
+print("this is " +
+ "default".screen
+ .width(._320, is: "width 320")
+ .width(._375, is: "width 375")
+ .height(._844, is: "height 844")
+ .height(._812, is: "height 812")
+ .inch(._4_7, is: "4.7 inches")
+ .inch(._5_8, is: "5.8 inches")
+ .inch(._6_5, is: "6.5 inches")
+ .level(.compact, is: "screen 3: 2")
+ .level(.regular, is: "screen 16: 9")
+ .level(.full, is: "screen 19.5: 9")
+ .value
+)
+```
+
+
+## Screenshot
+
+![TikTok 1](Resources/Storyboard%20TikTok%20Demo1.jpg)
+
+![TikTok 2](Resources/Storyboard%20TikTok%20Demo2.jpg)
+
+## Contributing
+
+If you have the need for a specific feature that you want implemented or if you experienced a bug, please open an issue.
+If you extended the functionality of UIAdapter yourself and want others to use it too, please submit a pull request.
+
+
+## License
+
+UIAdapter is under MIT license. See the [LICENSE](LICENSE) file for more info.
+
+
+>### [相关文章 Inch](https://www.jianshu.com/p/d2c09cb65ef7)
+>### [相关文章 Auto](https://www.jianshu.com/p/e0e12206e0c7)
+>### [相关文章 Auto](https://www.jianshu.com/p/48c67d0c95b6)
+
+-----
+
+> ## 欢迎入群交流
+![QQ](https://github.com/lixiang1994/Resources/blob/master/QQClub/QQClub.JPG)
diff --git a/README_CN.md b/README_CN.md
new file mode 100644
index 0000000..b16c0ed
--- /dev/null
+++ b/README_CN.md
@@ -0,0 +1,180 @@
+# UIAdapter - 等比例缩放屏幕适配
+
+[![License](https://img.shields.io/cocoapods/l/UIAdapter.svg)](LICENSE)
+![Swift](https://img.shields.io/badge/Swift-5.2-orange.svg)
+![Platform](https://img.shields.io/cocoapods/p/UIAdapter.svg?style=flat)
+[![Swift Package Manager](https://img.shields.io/badge/Swift_Package_Manager-compatible-4BC51D.svg?style=flat")](https://swift.org/package-manager/)
+[![Carthage](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
+[![Cocoapods](https://img.shields.io/cocoapods/v/UIAdapter.svg)](https://cocoapods.org)
+
+## 特性
+
+- [x] 数值类型快速转换
+- [x] Storyboard 等比例适配支持
+- [x] Xib 等比例适配支持
+- [x] 自定义计算处理
+- [x] 各个屏幕尺寸快速匹配
+
+
+## 安装
+
+**CocoaPods - Podfile**
+
+```ruby
+pod 'UIAdapter'
+```
+
+**Carthage - Cartfile**
+
+```ruby
+github "lixiang1994/UIAdapter"
+```
+
+#### [Swift Package Manager for Apple platforms](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app)
+
+选择 Xcode 菜单 `File > Swift Packages > Add Package Dependency` 输入仓库地址.
+```
+Repository: https://github.com/lixiang1994/UIAdapter
+```
+
+#### [Swift Package Manager](https://swift.org/package-manager/)
+
+将以下内容添加到你的 `Package.swift`:
+```swift
+.package(url: "https://github.com/lixiang1994/UIAdapter.git", from: "version")
+```
+
+## 使用
+
+首先导入
+
+```swift
+import UIAdapter
+```
+
+下面是一些简单示例. 支持所有设备和模拟器:
+
+### Auto
+
+
+AutoLayout (SnapKit):
+
+```swift
+private func setupLayout() {
+ cardView.snp.makeConstraints { (make) in
+ make.top.equalTo(16.auto())
+ make.left.right.equalToSuperview().inset(15.auto())
+ make.bottom.equalTo(-26.auto())
+ }
+
+ lineView.snp.makeConstraints { (make) in
+ make.left.right.equalToSuperview().inset(15.auto())
+ make.top.equalTo(titleLabel.snp.bottom)
+ make.height.equalTo(1)
+ }
+
+ titleLabel.snp.makeConstraints { (make) in
+ make.top.equalToSuperview()
+ make.left.equalTo(15.auto())
+ make.height.equalTo(48.auto())
+ }
+
+ stateLabel.snp.makeConstraints { (make) in
+ make.top.equalTo(lineView).offset(10.auto())
+ make.left.equalTo(15.auto())
+ make.height.equalTo(15.auto())
+ }
+}
+```
+
+属性设置 (Then):
+
+```swift
+private lazy var cardView = UIView().then {
+ $0.cornerRadius = 6.auto()
+ $0.backgroundColor = .white
+}
+
+private lazy var lineView = UIView().then {
+ $0.backgroundColor = .hex("000000", alpha: 0.05)
+}
+
+private lazy var titleLabel = UILabel().then {
+ $0.textColor = .black
+ $0.font = .systemFont(ofSize: 20.auto(), weight: .medium)
+}
+
+private lazy var stateLabel = UILabel().then {
+ $0.textColor = .gray
+ $0.font = .systemFont(ofSize: 12.auto(), weight: .medium)
+}
+```
+
+Storyboard / Xib:
+
+![约束](Resources/Storyboard%20Constraint.png)
+![UILabel 字体大小](Resources/Storyboard%20Label%20Font.png)
+
+### Inch
+
+例子
+
+```swift
+// default other screen numberOfLines = 0
+// 3.5 inches screen numberOfLines = 1
+// 4.0 inches screen numberOfLines = 2
+label.numberOfLines = 0.screen.inch(._3_5, is: 1).inch(._4_0, is: 2).value
+```
+
+
+```swift
+// default other screen numberOfLines = 0
+// width 320 screen numberOfLines = 1
+// width 375 inches screen numberOfLines = 2
+label.numberOfLines = 0.screen.width(._320, is: 1).width(._375, is: 2).value
+```
+
+
+```swift
+print("this is " +
+ "default".screen
+ .width(._320, is: "宽度 320")
+ .width(._375, is: "宽度 375")
+ .height(._844, is: "高度 844")
+ .height(._812, is: "高度 812")
+ .inch(._4_7, is: "4.7 英寸")
+ .inch(._5_8, is: "5.8 英寸")
+ .inch(._6_5, is: "6.5 英寸")
+ .level(.compact, is: "屏幕级别 紧凑屏")
+ .level(.regular, is: "屏幕级别 常规屏")
+ .level(.full, is: "屏幕级别 全面屏")
+ .value
+)
+```
+
+
+## 截屏
+
+![TikTok 1](Resources/Storyboard%20TikTok%20Demo1.jpg)
+
+![TikTok 2](Resources/Storyboard%20TikTok%20Demo2.jpg)
+
+## 贡献
+
+如果您需要实现特定功能或遇到错误,请打开issue。
+如果您自己扩展了UIAdapter的功能并希望其他人也使用它,请提交拉取请求。
+
+## 协议
+
+UIAdapter 使用 MIT 协议. 有关更多信息,请参阅[LICENSE](LICENSE)文件.
+
+
+>### [相关文章 Inch](https://www.jianshu.com/p/d2c09cb65ef7)
+>### [相关文章 Auto](https://www.jianshu.com/p/e0e12206e0c7)
+>### [相关文章 Auto](https://www.jianshu.com/p/48c67d0c95b6)
+
+
+-----
+
+> ## 欢迎入群交流
+![QQ](https://github.com/lixiang1994/Resources/blob/master/QQClub/QQClub.JPG)
diff --git a/Sources/Screen/UIAdapter.Screen.swift b/Sources/Screen/UIAdapter.Screen.swift
new file mode 100644
index 0000000..7d9736c
--- /dev/null
+++ b/Sources/Screen/UIAdapter.Screen.swift
@@ -0,0 +1,288 @@
+//
+// UIAdapter.Screen.swift
+// ┌─┐ ┌───────┐ ┌───────┐
+// │ │ │ ┌─────┘ │ ┌─────┘
+// │ │ │ └─────┐ │ └─────┐
+// │ │ │ ┌─────┘ │ ┌─────┘
+// │ └─────┐│ └─────┐ │ └─────┐
+// └───────┘└───────┘ └───────┘
+//
+// Created by lee on 2018/1/22.
+// Copyright © 2018年 lee. All rights reserved.
+//
+
+import Foundation
+
+#if os(iOS)
+
+import UIKit
+
+public class UIAdapterScreenWrapper {
+ let base: Base
+
+ public private(set) var value: Base
+
+ init(_ base: Base) {
+ self.base = base
+ self.value = base
+ }
+}
+
+public protocol UIAdapterScreenCompatible {
+ associatedtype ScreenCompatibleType
+ var screen: ScreenCompatibleType { get }
+}
+
+extension UIAdapterScreenCompatible {
+
+ public var screen: UIAdapterScreenWrapper {
+ get { return UIAdapterScreenWrapper(self) }
+ }
+}
+
+extension UIAdapterScreenWrapper {
+
+ public typealias Screen = UIAdapter.Screen
+
+ public func width(_ types: Screen.Width..., is value: Base) -> Self {
+ return width(types, is: value, zoomed: value)
+ }
+ public func width(_ types: Screen.Width..., is value: Base, zoomed: Base) -> Self {
+ return width(types, is: value, zoomed: zoomed)
+ }
+ private func width(_ types: [Screen.Width], is value: Base, zoomed: Base) -> Self {
+ for type in types where Screen.Width.current == type {
+ self.value = Screen.isZoomedMode ? zoomed : value
+ }
+ return self
+ }
+
+ public func height(_ types: Screen.Height..., is value: Base) -> Self {
+ return height(types, is: value, zoomed: value)
+ }
+ public func height(_ types: Screen.Height..., is value: Base, zoomed: Base) -> Self {
+ return height(types, is: value, zoomed: zoomed)
+ }
+ private func height(_ types: [Screen.Height], is value: Base, zoomed: Base) -> Self {
+ for type in types where Screen.Height.current == type {
+ self.value = Screen.isZoomedMode ? zoomed : value
+ }
+ return self
+ }
+
+ public func inch(_ types: Screen.Inch..., is value: Base) -> Self {
+ return inch(types, is: value, zoomed: value)
+ }
+ public func inch(_ types: Screen.Inch..., is value: Base, zoomed: Base) -> Self {
+ return inch(types, is: value, zoomed: zoomed)
+ }
+ private func inch(_ types: [Screen.Inch], is value: Base, zoomed: Base) -> Self {
+ for type in types where Screen.Inch.current == type {
+ self.value = Screen.isZoomedMode ? zoomed : value
+ }
+ return self
+ }
+
+ public func level(_ types: Screen.Level..., is value: Base) -> Self {
+ return level(types, is: value, zoomed: value)
+ }
+ public func level(_ types: Screen.Level..., is value: Base, zoomed: Base) -> Self {
+ return level(types, is: value, zoomed: zoomed)
+ }
+ private func level(_ types: [Screen.Level], is value: Base, zoomed: Base) -> Self {
+ for type in types where Screen.Level.current == type {
+ self.value = Screen.isZoomedMode ? zoomed : value
+ }
+ return self
+ }
+}
+
+extension UIAdapter {
+
+ public enum Screen {
+
+ static var size: CGSize {
+ UIScreen.main.bounds.size
+ }
+ static var nativeSize: CGSize {
+ UIScreen.main.nativeBounds.size
+ }
+ static var scale: CGFloat {
+ UIScreen.main.scale
+ }
+ static var nativeScale: CGFloat {
+ UIScreen.main.nativeScale
+ }
+ }
+}
+
+extension UIAdapter.Screen {
+
+ public static var isZoomedMode: Bool {
+ UIScreen.main.scale != UIScreen.main.nativeScale
+ }
+
+ public enum Width: CGFloat {
+ case unknown = -1
+ case _320 = 320
+ case _375 = 375
+ case _390 = 390
+ case _414 = 414
+ case _428 = 428
+
+ public static var current: Width {
+ return Width(rawValue: nativeSize.width / scale) ?? .unknown
+ }
+ }
+
+ public enum Height: CGFloat {
+ case unknown = -1
+ case _480 = 480
+ case _568 = 568
+ case _667 = 667
+ case _736 = 736
+ case _812 = 812
+ case _844 = 844
+ case _896 = 896
+ case _926 = 926
+
+ public static var current: Height {
+ return Height(rawValue: nativeSize.height / scale) ?? .unknown
+ }
+ }
+
+ public enum Inch: Double {
+ case unknown = -1
+ case _3_5 = 3.5
+ case _4_0 = 4.0
+ case _4_7 = 4.7
+ case _5_4 = 5.4
+ case _5_5 = 5.5
+ case _5_8 = 5.8
+ case _6_1 = 6.1
+ case _6_5 = 6.5
+ case _6_7 = 6.7
+
+ public static var current: Inch {
+ switch (nativeSize.width / scale, nativeSize.height / scale, scale) {
+ case (320, 480, 2):
+ return ._3_5
+
+ case (320, 568, 2):
+ return ._4_0
+
+ case (375, 667, 2):
+ return ._4_7
+
+ case (375, 812, 3) where UIDevice.iPhoneMini:
+ return ._5_4
+
+ case (414, 736, 3):
+ return ._5_5
+
+ case (375, 812, 3):
+ return ._5_8
+
+ case (414, 896, 2), (390, 844, 3):
+ return ._6_1
+
+ case (414, 896, 3):
+ return ._6_5
+
+ case (428, 926, 3):
+ return ._6_7
+
+ default:
+ return .unknown
+ }
+ }
+ }
+
+ public enum Level: Int {
+ case unknown = -1
+ /// 3: 2
+ case compact
+ /// 16: 9
+ case regular
+ /// 19.5: 9
+ case full
+
+ public static var current: Level {
+ switch (nativeSize.width / scale, nativeSize.height / scale) {
+ case (320, 480):
+ return .compact
+
+ case (320, 568), (375, 667), (414, 736):
+ return .regular
+
+ case (375, 812), (414, 896), (390, 844), (428, 926):
+ return .full
+
+ default:
+ return .unknown
+ }
+ }
+ }
+}
+
+extension UIAdapter.Screen {
+
+ public static var isCompact: Bool {
+ return Level.current == .compact
+ }
+
+ public static var isRegular: Bool {
+ return Level.current == .regular
+ }
+
+ public static var isFull: Bool {
+ return Level.current == .full
+ }
+}
+
+extension Int: UIAdapterScreenCompatible {}
+extension Bool: UIAdapterScreenCompatible {}
+extension Float: UIAdapterScreenCompatible {}
+extension Double: UIAdapterScreenCompatible {}
+extension String: UIAdapterScreenCompatible {}
+extension CGRect: UIAdapterScreenCompatible {}
+extension CGSize: UIAdapterScreenCompatible {}
+extension CGFloat: UIAdapterScreenCompatible {}
+extension CGPoint: UIAdapterScreenCompatible {}
+extension UIImage: UIAdapterScreenCompatible {}
+extension UIColor: UIAdapterScreenCompatible {}
+extension UIFont: UIAdapterScreenCompatible {}
+extension UIEdgeInsets: UIAdapterScreenCompatible {}
+
+
+fileprivate extension UIDevice {
+
+ static var iPhoneMini: Bool {
+ switch identifier {
+ case "iPhone13,1", "iPhone14,4":
+ return true
+
+ case "i386", "x86_64", "arm64":
+ return ["iPhone13,1", "iPhone14,4"].contains(
+ ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] ?? ""
+ )
+
+ default:
+ return false
+ }
+ }
+
+ private static let identifier: String = {
+ var systemInfo = utsname()
+ uname(&systemInfo)
+ let mirror = Mirror(reflecting: systemInfo.machine)
+
+ let identifier = mirror.children.reduce("") { identifier, element in
+ guard let value = element.value as? Int8, value != 0 else { return identifier }
+ return identifier + String(UnicodeScalar(UInt8(value)))
+ }
+ return identifier
+ } ()
+}
+
+#endif
diff --git a/Sources/UIAdapter.h b/Sources/UIAdapter.h
new file mode 100644
index 0000000..69c47ea
--- /dev/null
+++ b/Sources/UIAdapter.h
@@ -0,0 +1,18 @@
+//
+// UIAdapter.h
+// UIAdapter
+//
+// Created by 李响 on 2021/10/11.
+//
+
+#import
+
+//! Project version number for UIAdapter.
+FOUNDATION_EXPORT double UIAdapterVersionNumber;
+
+//! Project version string for UIAdapter.
+FOUNDATION_EXPORT const unsigned char UIAdapterVersionString[];
+
+// In this header, you should import all the public headers of your framework using statements like #import
+
+
diff --git a/Sources/Zoom/UIAdapter.Zoom.swift b/Sources/Zoom/UIAdapter.Zoom.swift
new file mode 100644
index 0000000..bdd955b
--- /dev/null
+++ b/Sources/Zoom/UIAdapter.Zoom.swift
@@ -0,0 +1,486 @@
+//
+// UIAdapter.Zoom.swift
+// ┌─┐ ┌───────┐ ┌───────┐
+// │ │ │ ┌─────┘ │ ┌─────┘
+// │ │ │ └─────┐ │ └─────┐
+// │ │ │ ┌─────┘ │ ┌─────┘
+// │ └─────┐│ └─────┐ │ └─────┐
+// └───────┘└───────┘ └───────┘
+//
+// Created by lee on 2018/11/2.
+// Copyright © 2018年 lee. All rights reserved.
+//
+
+#if canImport(Foundation)
+
+import Foundation
+
+#if os(iOS)
+
+import UIKit
+
+public enum UIAdapter {
+
+ enum Zoom {
+
+ /// 设置转换闭包
+ ///
+ /// - Parameter conversion: 转换闭包
+ public static func set(conversion: @escaping ((Double) -> Double)) {
+ conversionClosure = conversion
+ }
+
+ /// 转换 用于数值的等比例计算 如需自定义可重新设置
+ static var conversionClosure: ((Double) -> Double) = { (origin) in
+ guard UIDevice.current.userInterfaceIdiom == .phone else {
+ return origin
+ }
+
+ let base = 375.0
+ let screenWidth = Double(UIScreen.main.bounds.width)
+ let screenHeight = Double(UIScreen.main.bounds.height)
+ let width = min(screenWidth, screenHeight)
+ let result = origin * (width / base)
+ let scale = Double(UIScreen.main.scale)
+ return (result * scale).rounded(.up) / scale
+ }
+ }
+}
+
+extension UIAdapter.Zoom {
+
+ static func conversion(_ value: Double) -> Double {
+ return conversionClosure(value)
+ }
+}
+
+protocol UIAdapterZoomCalculationable {
+
+ /// 缩放计算
+ ///
+ /// - Returns: 结果
+ func zoom() -> Self
+}
+
+extension Double: UIAdapterZoomCalculationable {
+
+ func zoom() -> Double {
+ return UIAdapter.Zoom.conversion(self)
+ }
+}
+
+extension BinaryInteger {
+
+ public func zoom() -> Double {
+ let temp = Double("\(self)") ?? 0
+ return temp.zoom()
+ }
+ public func zoom() -> T where T : BinaryInteger {
+ let temp = Double("\(self)") ?? 0
+ return temp.zoom()
+ }
+ public func zoom() -> T where T : BinaryFloatingPoint {
+ let temp = Double("\(self)") ?? 0
+ return temp.zoom()
+ }
+}
+
+extension BinaryFloatingPoint {
+
+ public func zoom() -> Double {
+ let temp = Double("\(self)") ?? 0
+ return temp.zoom()
+ }
+ public func zoom() -> T where T : BinaryInteger {
+ let temp = Double("\(self)") ?? 0
+ return T(temp.zoom())
+ }
+ public func zoom() -> T where T : BinaryFloatingPoint {
+ let temp = Double("\(self)") ?? 0
+ return T(temp.zoom())
+ }
+}
+
+extension CGPoint: UIAdapterZoomCalculationable {
+
+ public func zoom() -> CGPoint {
+ return CGPoint(x: x.zoom(), y: y.zoom())
+ }
+}
+
+extension CGSize: UIAdapterZoomCalculationable {
+
+ public func zoom() -> CGSize {
+ return CGSize(width: width.zoom(), height: height.zoom())
+ }
+}
+
+extension CGRect: UIAdapterZoomCalculationable {
+
+ public func zoom() -> CGRect {
+ return CGRect(origin: origin.zoom(), size: size.zoom())
+ }
+}
+
+extension CGVector: UIAdapterZoomCalculationable {
+
+ public func zoom() -> CGVector {
+ return CGVector(dx: dx.zoom(), dy: dy.zoom())
+ }
+}
+
+extension UIOffset: UIAdapterZoomCalculationable {
+
+ public func zoom() -> UIOffset {
+ return UIOffset(horizontal: horizontal.zoom(), vertical: vertical.zoom())
+ }
+}
+
+extension UIEdgeInsets: UIAdapterZoomCalculationable {
+
+ public func zoom() -> UIEdgeInsets {
+ return UIEdgeInsets(
+ top: top.zoom(),
+ left: left.zoom(),
+ bottom: bottom.zoom(),
+ right: right.zoom()
+ )
+ }
+}
+
+
+extension NSLayoutConstraint {
+
+ @IBInspectable private var autoConstant: Bool {
+ get { return false }
+ set {
+ guard newValue else { return }
+
+ constant = constant.zoom()
+ }
+ }
+}
+
+extension UIView {
+
+ @IBInspectable private var autoCornerRadius: CGFloat {
+ get { return layer.cornerRadius }
+ set {
+ let value: CGFloat = newValue.zoom()
+ layer.masksToBounds = true
+ layer.cornerRadius = abs(CGFloat(Int(value * 100)) / 100)
+ }
+ }
+}
+
+extension UILabel {
+
+ @IBInspectable private var autoFont: Bool {
+ get { return false }
+ set {
+ guard newValue else { return }
+ guard let text = attributedText?.mutableCopy() as? NSMutableAttributedString else {
+ return
+ }
+
+ font = font.withSize(font.pointSize.zoom())
+ attributedText = text.reset(font: { $0.zoom() })
+ }
+ }
+
+ @IBInspectable private var autoLine: Bool {
+ get { return false }
+ set {
+ guard newValue else { return }
+ guard let text = attributedText else { return }
+
+ attributedText = text.reset(line: { $0.zoom() })
+ }
+ }
+
+ @IBInspectable private var autoShadowOffset: Bool {
+ get { return false }
+ set {
+ guard newValue else { return }
+
+ shadowOffset = shadowOffset.zoom()
+ }
+ }
+}
+
+extension UITextView {
+
+ @IBInspectable private var autoFont: Bool {
+ get { return false }
+ set {
+ guard newValue else { return }
+ guard let font = font else { return }
+
+ self.font = font.withSize(font.pointSize.zoom())
+ }
+ }
+}
+
+extension UITextField {
+
+ @IBInspectable private var autoFont: Bool {
+ get { return false }
+ set {
+ guard newValue else { return }
+ guard let font = font else { return }
+
+ self.font = font.withSize(font.pointSize.zoom())
+ }
+ }
+}
+
+extension UIImageView {
+
+ @IBInspectable private var autoImage: Bool {
+ get { return false }
+ set {
+ guard newValue else { return }
+
+ if let width = image?.size.width {
+ image = image?.scaled(to: width.zoom())
+ }
+ if let width = highlightedImage?.size.width {
+ highlightedImage = highlightedImage?.scaled(to: width.zoom())
+ }
+ }
+ }
+}
+
+extension UIButton {
+
+ @IBInspectable private var autoTitle: Bool {
+ get { return false }
+ set {
+ guard newValue else { return }
+
+ let states: [UIControl.State] = [
+ .normal,
+ .highlighted,
+ .selected,
+ .disabled
+ ]
+
+ if
+ let _ = title(for: state),
+ let label = titleLabel,
+ let font = label.font {
+ label.font = font.withSize(font.pointSize.zoom())
+ }
+
+ let titles = states.enumerated().compactMap {
+ (i, state) -> (Int, NSAttributedString)? in
+ guard let t = attributedTitle(for: state) else { return nil }
+ return (i, t)
+ }
+ titles.filtered(duplication: { $0.1 }).forEach {
+ setAttributedTitle(
+ $0.1.reset(font: { $0.zoom() }),
+ for: states[$0.0]
+ )
+ }
+ }
+ }
+
+ @IBInspectable private var autoImage: Bool {
+ get { return false }
+ set {
+ guard newValue else { return }
+
+ let states: [UIControl.State] = [
+ .normal,
+ .highlighted,
+ .selected,
+ .disabled
+ ]
+
+ let images = states.enumerated().compactMap {
+ (i, state) -> (Int, UIImage)? in
+ guard let v = image(for: state) else { return nil }
+ return (i, v)
+ }
+ images.filtered(duplication: { $0.1 }).forEach {
+ setImage(
+ $0.1.scaled(to: $0.1.size.width.zoom()),
+ for: states[$0.0]
+ )
+ }
+
+ let backgrounds = states.enumerated().compactMap {
+ (i, state) -> (Int, UIImage)? in
+ guard let v = backgroundImage(for: state) else { return nil }
+ return (i, v)
+ }
+ backgrounds.filtered(duplication: { $0.1 }).forEach {
+ setBackgroundImage(
+ $0.1.scaled(to: $0.1.size.width.zoom()),
+ for: states[$0.0]
+ )
+ }
+ }
+ }
+
+ @IBInspectable private var autoTitleInsets: Bool {
+ get { return false }
+ set {
+ guard newValue else { return }
+
+ titleEdgeInsets = titleEdgeInsets.zoom()
+ }
+ }
+
+ @IBInspectable private var autoImageInsets: Bool {
+ get { return false }
+ set {
+ guard newValue else { return }
+
+ imageEdgeInsets = imageEdgeInsets.zoom()
+ }
+ }
+
+ @IBInspectable private var autoContentInsets: Bool {
+ get { return false }
+ set {
+ guard newValue else { return }
+
+ contentEdgeInsets = contentEdgeInsets.zoom()
+ }
+ }
+}
+
+@available(iOS 9.0, *)
+extension UIStackView {
+
+ @IBInspectable private var autoSpacing: Bool {
+ get { return false }
+ set {
+ guard newValue else { return }
+
+ spacing = spacing.zoom()
+ }
+ }
+}
+
+fileprivate extension NSAttributedString {
+
+ func reset(font size: (CGFloat) -> CGFloat) -> NSAttributedString {
+ let string = NSMutableAttributedString(attributedString: self)
+ enumerateAttributes(
+ in: NSRange(location: 0, length: length),
+ options: .longestEffectiveRangeNotRequired
+ ) { (attributes, range, stop) in
+ var temp = attributes
+ if let font = attributes[.font] as? UIFont {
+ temp[.font] = font.withSize(size(font.pointSize))
+ }
+ string.setAttributes(temp, range: range)
+ }
+ return string
+ }
+
+ func reset(line spacing: (CGFloat) -> CGFloat) -> NSAttributedString {
+ let string = NSMutableAttributedString(attributedString: self)
+ enumerateAttributes(
+ in: NSRange(location: 0, length: length),
+ options: .longestEffectiveRangeNotRequired
+ ) { (attributes, range, stop) in
+ var temp = attributes
+ if let paragraph = attributes[.paragraphStyle] as? NSMutableParagraphStyle {
+ paragraph.lineSpacing = spacing(paragraph.lineSpacing)
+ temp[.paragraphStyle] = paragraph
+ }
+ string.setAttributes(temp, range: range)
+ }
+ return string
+ }
+}
+
+fileprivate extension UIImage {
+
+ func scaled(to width: CGFloat, opaque: Bool = false) -> UIImage? {
+ guard self.size.width > 0 else {
+ return nil
+ }
+
+ let scale = width / self.size.width
+ let size = CGSize(width: width, height: self.size.height * scale)
+ UIGraphicsBeginImageContextWithOptions(size, false, 0)
+ draw(in: CGRect(origin: .zero, size: size))
+ let new = UIGraphicsGetImageFromCurrentImageContext()
+ UIGraphicsEndImageContext()
+ return new
+ }
+}
+
+fileprivate extension Array {
+
+ func filtered(duplication closure: (Element) throws -> E) rethrows -> [Element] {
+ return try reduce(into: [Element]()) { (result, e) in
+ let contains = try result.contains { try closure($0) == closure(e) }
+ result += contains ? [] : [e]
+ }
+ }
+}
+
+public extension Double {
+
+ func rounded(_ decimalPlaces: Int) -> Double {
+ let divisor = pow(10.0, Double(max(0, decimalPlaces)))
+ return (self * divisor).rounded() / divisor
+ }
+}
+
+public extension BinaryFloatingPoint {
+
+ func rounded(_ decimalPlaces: Int) -> Double {
+ let temp = Double("\(self)") ?? 0
+ return temp.rounded(decimalPlaces)
+ }
+
+ func rounded(_ decimalPlaces: Int) -> T where T: BinaryFloatingPoint {
+ let temp = Double("\(self)") ?? 0
+ return T(temp.rounded(decimalPlaces))
+ }
+}
+
+public extension CGPoint {
+
+ func rounded(_ decimalPlaces: Int) -> CGPoint {
+ return CGPoint(x: x.rounded(decimalPlaces), y: y.rounded(decimalPlaces))
+ }
+}
+
+public extension CGSize {
+
+ func rounded(_ decimalPlaces: Int) -> CGSize {
+ return CGSize(width: width.rounded(decimalPlaces), height: height.rounded(decimalPlaces))
+ }
+}
+
+public extension CGRect {
+
+ func rounded(_ decimalPlaces: Int) -> CGRect {
+ return CGRect(origin: origin.rounded(decimalPlaces), size: size.rounded(decimalPlaces))
+ }
+}
+
+public extension UIEdgeInsets {
+
+ func rounded(_ decimalPlaces: Int) -> UIEdgeInsets {
+ return UIEdgeInsets(
+ top: top.rounded(decimalPlaces),
+ left: left.rounded(decimalPlaces),
+ bottom: bottom.rounded(decimalPlaces),
+ right: right.rounded(decimalPlaces)
+ )
+ }
+}
+
+#endif
+
+#endif
+
diff --git a/Tests/UIAdapterTests/UIAdapterTests.swift b/Tests/UIAdapterTests/UIAdapterTests.swift
new file mode 100644
index 0000000..f8726db
--- /dev/null
+++ b/Tests/UIAdapterTests/UIAdapterTests.swift
@@ -0,0 +1,11 @@
+import XCTest
+@testable import UIAdapter
+
+final class UIAdapterTests: XCTestCase {
+ func testExample() throws {
+ // This is an example of a functional test case.
+ // Use XCTAssert and related functions to verify your tests produce the correct
+ // results.
+ XCTAssertEqual(UIAdapter().text, "Hello, World!")
+ }
+}
diff --git a/UIAdapter.podspec b/UIAdapter.podspec
new file mode 100644
index 0000000..b6b8d95
--- /dev/null
+++ b/UIAdapter.podspec
@@ -0,0 +1,25 @@
+Pod::Spec.new do |s|
+
+s.name = "UIAdapter"
+s.version = "1.0.0"
+s.summary = "iOS屏幕适配工具"
+
+s.homepage = "https://github.com/lixiang1994/UIAdapter"
+
+s.license = { :type => "MIT", :file => "LICENSE" }
+
+s.author = { "LEE" => "18611401994@163.com" }
+
+s.platform = :ios, "9.0"
+
+s.source = { :git => "https://github.com/lixiang1994/UIAdapter.git", :tag => s.version }
+
+s.source_files = "Sources/**/*.swift"
+
+s.requires_arc = true
+
+s.swift_version = '5.3'
+
+s.cocoapods_version = '>= 1.4.0'
+
+end
diff --git a/UIAdapter.xcodeproj/project.pbxproj b/UIAdapter.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..5defa9f
--- /dev/null
+++ b/UIAdapter.xcodeproj/project.pbxproj
@@ -0,0 +1,362 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 55;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 9BEB034A27140DFD003CC3DD /* UIAdapter.Zoom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BEB034627140DFD003CC3DD /* UIAdapter.Zoom.swift */; };
+ 9BEB034B27140DFD003CC3DD /* UIAdapter.Screen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BEB034827140DFD003CC3DD /* UIAdapter.Screen.swift */; };
+ 9BEB034C27140ED7003CC3DD /* UIAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BEB034427140DFD003CC3DD /* UIAdapter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 9BEB03372713EEBA003CC3DD /* UIAdapter.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = UIAdapter.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 9BEB034427140DFD003CC3DD /* UIAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIAdapter.h; sourceTree = ""; };
+ 9BEB034627140DFD003CC3DD /* UIAdapter.Zoom.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIAdapter.Zoom.swift; sourceTree = ""; };
+ 9BEB034827140DFD003CC3DD /* UIAdapter.Screen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIAdapter.Screen.swift; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 9BEB03342713EEBA003CC3DD /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 9BEB032D2713EEBA003CC3DD = {
+ isa = PBXGroup;
+ children = (
+ 9BEB03392713EEBA003CC3DD /* Sources */,
+ 9BEB03382713EEBA003CC3DD /* Products */,
+ );
+ sourceTree = "";
+ };
+ 9BEB03382713EEBA003CC3DD /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 9BEB03372713EEBA003CC3DD /* UIAdapter.framework */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 9BEB03392713EEBA003CC3DD /* Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 9BEB034427140DFD003CC3DD /* UIAdapter.h */,
+ 9BEB034527140DFD003CC3DD /* Zoom */,
+ 9BEB034727140DFD003CC3DD /* Screen */,
+ );
+ path = Sources;
+ sourceTree = "";
+ };
+ 9BEB034527140DFD003CC3DD /* Zoom */ = {
+ isa = PBXGroup;
+ children = (
+ 9BEB034627140DFD003CC3DD /* UIAdapter.Zoom.swift */,
+ );
+ path = Zoom;
+ sourceTree = "";
+ };
+ 9BEB034727140DFD003CC3DD /* Screen */ = {
+ isa = PBXGroup;
+ children = (
+ 9BEB034827140DFD003CC3DD /* UIAdapter.Screen.swift */,
+ );
+ path = Screen;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ 9BEB03322713EEBA003CC3DD /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 9BEB034C27140ED7003CC3DD /* UIAdapter.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ 9BEB03362713EEBA003CC3DD /* UIAdapter */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 9BEB033E2713EEBA003CC3DD /* Build configuration list for PBXNativeTarget "UIAdapter" */;
+ buildPhases = (
+ 9BEB03322713EEBA003CC3DD /* Headers */,
+ 9BEB03332713EEBA003CC3DD /* Sources */,
+ 9BEB03342713EEBA003CC3DD /* Frameworks */,
+ 9BEB03352713EEBA003CC3DD /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = UIAdapter;
+ productName = UIAdapter;
+ productReference = 9BEB03372713EEBA003CC3DD /* UIAdapter.framework */;
+ productType = "com.apple.product-type.framework";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 9BEB032E2713EEBA003CC3DD /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ BuildIndependentTargetsInParallel = 1;
+ LastUpgradeCheck = 1300;
+ TargetAttributes = {
+ 9BEB03362713EEBA003CC3DD = {
+ CreatedOnToolsVersion = 13.0;
+ };
+ };
+ };
+ buildConfigurationList = 9BEB03312713EEBA003CC3DD /* Build configuration list for PBXProject "UIAdapter" */;
+ compatibilityVersion = "Xcode 13.0";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 9BEB032D2713EEBA003CC3DD;
+ productRefGroup = 9BEB03382713EEBA003CC3DD /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 9BEB03362713EEBA003CC3DD /* UIAdapter */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 9BEB03352713EEBA003CC3DD /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 9BEB03332713EEBA003CC3DD /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 9BEB034B27140DFD003CC3DD /* UIAdapter.Screen.swift in Sources */,
+ 9BEB034A27140DFD003CC3DD /* UIAdapter.Zoom.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 9BEB033C2713EEBA003CC3DD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ CURRENT_PROJECT_VERSION = 1;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 15.0;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ VERSIONING_SYSTEM = "apple-generic";
+ VERSION_INFO_PREFIX = "";
+ };
+ name = Debug;
+ };
+ 9BEB033D2713EEBA003CC3DD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ CURRENT_PROJECT_VERSION = 1;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 15.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ VALIDATE_PRODUCT = YES;
+ VERSIONING_SYSTEM = "apple-generic";
+ VERSION_INFO_PREFIX = "";
+ };
+ name = Release;
+ };
+ 9BEB033F2713EEBA003CC3DD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEFINES_MODULE = YES;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_KEY_NSHumanReadableCopyright = "";
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = com.lee.UIAdapter;
+ PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
+ SKIP_INSTALL = YES;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 9BEB03402713EEBA003CC3DD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEFINES_MODULE = YES;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_KEY_NSHumanReadableCopyright = "";
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = com.lee.UIAdapter;
+ PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
+ SKIP_INSTALL = YES;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 9BEB03312713EEBA003CC3DD /* Build configuration list for PBXProject "UIAdapter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 9BEB033C2713EEBA003CC3DD /* Debug */,
+ 9BEB033D2713EEBA003CC3DD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 9BEB033E2713EEBA003CC3DD /* Build configuration list for PBXNativeTarget "UIAdapter" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 9BEB033F2713EEBA003CC3DD /* Debug */,
+ 9BEB03402713EEBA003CC3DD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 9BEB032E2713EEBA003CC3DD /* Project object */;
+}
diff --git a/UIAdapter.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/UIAdapter.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/UIAdapter.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/UIAdapter.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/UIAdapter.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/UIAdapter.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+