Coder Social home page Coder Social logo

linxunfeng / swiftyfitsize Goto Github PK

View Code? Open in Web Editor NEW
280.0 5.0 41.0 2.04 MB

📱 Swifty screen adaptation solution (Support Objective-C and Swift)

Home Page: https://fullstackaction.com

License: MIT License

Ruby 6.08% Swift 73.39% Objective-C 14.47% C 6.07%
swift ios screenadapter font number screen xib storyboard objcective-c objc

swiftyfitsize's Introduction

SwiftyFitsize

Author CI Status Version License Platform visitors

Example

克隆或下载仓库到本地后,请先运行 pod install , 再打开 SwiftyFitsize.xcworkspace

Requirements

  • iOS 9.0+
  • Xcode 10.2+
  • Swift 5+

Installation

  • Cocoapods
use_frameworks!
pod 'SwiftyFitsize'
  • Swift Package Manager
1. File > Add Packages
2. Search https://github.com/LinXunFeng/SwiftyFitsize.git
3. Select "Up to Next Major" with "1.4.1"

Exhibition

iPhone

iPad

Usage

一、运算符

无论是 ~ 还是 iPhone 的适配效果是一样的。而对 iPad 而言,iPad 的宽度太大,使用 还是会按宽度比例进行运算,就会显示特别臃肿,这时使用 ~ 在显示上就会比较合适。

  • ~ 的基础上针对 iPad 的适配大小后再去乘上 iPadFitMultiple
  • 一般情况下直接使用 ~ 即可。
  • 其它运算符亦是如此,具体请看下方的说明表
运算符 说明
~ 对比宽度,当设备为 iPad 时,适配后的 value 会再乘上 iPadFitMultiple
对比宽度,强制适配,不论是 iPhone 还是 iPad 都不会乘上 iPadFitMultiple
对比高度,对应 ~ ,整屏高度
对比高度,对应 ,整屏高度
∣= 对比高度,对应 ,安全区域内的高度
∥= 对比高度,对应 ,安全区域内的高度
∣- 对比高度,对应 ,除去刘海区域的安全区域内的高度
∥- 对比高度,对应 ,除去刘海区域的安全区域内的高度

各高度适配的对比

  • 红色: ,以整个屏幕的高度进行适配
  • 蓝色: ∣=∥= 以中心安全区域的高度进行适配
  • 绿色: ∣-∥- 以包括底部的安全区域进行适配

高度适配对比

举个例子

~ : 当设备为 iPad 时,适配后的值会与 iPadFitMultiple 相乘

100~
UIFont.systemFont(ofSize: 14)~
CGPoint(x: 10, y: 10)~
CGRect(x: 10, y: 10, width: 100, height: 100)~
UIEdgeInsetsMake(10, 10, 10, 10)~

: (option + x) 适配后的值不会与 iPadFitMultiple 相乘

100
UIFont.systemFont(ofSize: 14)
CGPoint(x: 10, y: 10)
CGRect(x: 10, y: 10, width: 100, height: 100)
UIEdgeInsetsMake(10, 10, 10, 10)

修改 参照宽度参照高度是否为iPhoneX系列的参照高度iPadFitMultiple 可以调用如下方法

/// 设置参照的相关参数
///
/// - Parameters:
///   - width: 参照的宽度
///   - height: 参照的高度
///   - isIPhoneXSeriesHeight: 是否为iPhoneX系列的参照高度
///   - iPadFitMultiple: iPad 在适配后所得值的倍数 (0 , 1]
SwiftyFitsize.reference(
  width: 414, 
  height: 896, 
  isIPhoneXSeriesHeight: true, 
  iPadFitMultiple: 0.5
)

二、支持 xib 和 storyboard

enum SwiftyFitType: Int {
    /// Original Value
    case none = 0
    /// ~
    case flexibleWidth = 1
    /// ≈
    case forceWidth = 2
    /// ∣
    case flexibleHeight = 3
    /// ∥
    case forceHeight = 4
    /// ∣=
    case flexibleSafeAreaCenterHeight = 5
    /// ∥=
    case forceSafeAreaCenterHeight = 6
    /// ∣-
    case flexibleSafeAreaWithoutTopHeight = 7
    /// ∥-
    case forceSafeAreaWithoutTopHeight = 8
}
  • Font Fitsize

支持的UI控件有: UILabel UIButton UITextView UITextField

FontFitType 的值请参考上方的 enum SwiftyFitType

xib-font

  • Constraint Fitsize

约束适配同上

xib-font

iPad 关于 ~ 在使用上的对比

~与≈的对比

三、Objective-C

  1. 由于 OC 不支持运算符重载,所以只能用宏来适配。

  2. XibStoryboard 则跟上方提及的使用方式相同。

Swift运算符OC宏 对应表

Swift运算符 OC宏
~ SF_xx
SFZ_xx
SF_FH_xx
SFZ_FH_xx
∣= SF_SCH_xx
∥= SFZ_SCH_xx
∣- SF_SBH_xx
∥- SFZ_SBH_xx

注: xx 支持如下类型 FontIntFloatPointSizeRectEdgeInsets

  • 导入
@import SwiftyFitsize;

注:如果你使用的是 SPM 添加的依赖,且需要使用到宏(如:SF_Float),

则需要导入 SwiftyFitsizeOCSupport ,而 SwiftyFitsize 可以不导入。

@import SwiftyFitsizeOCSupport;
  • 修改 参照宽度参照高度是否为iPhoneX系列的参照高度iPadFitMultiple
[SwiftyFitsize referenceWithWidth:414
                           height:896
            isIPhoneXSeriesHeight:YES
                  iPadFitMultiple:0.6];
  • ~
UIFont *font = [UIFont systemFontOfSize:14];

UIFont *font1 = font.sf;
UIFont *font2 = SF_Font(font);

CGFloat num = SF_Float(14);
CGPoint point = SF_Point(CGPointMake(10, 10));
CGSize size = SF_Size(CGSizeMake(100, 100));
CGRect rect = SF_Rect(CGRectMake(10, 10, 100, 100));
UIEdgeInsets edge = SF_EdgeInsets(UIEdgeInsetsMake(0, 0, 100, 100));
UIFont *font1 = font.sfz;
UIFont *font2 = SFZ_Font(font);

CGFloat num = SFZ_Float(14);
CGPoint point = SFZ_Point(CGPointMake(10, 10));
CGSize size = SFZ_Size(CGSizeMake(100, 100));
CGRect rect = SFZ_Rect(CGRectMake(10, 10, 100, 100));
UIEdgeInsets edge = SFZ_EdgeInsets(UIEdgeInsetsMake(0, 0, 100, 100));

其它运算符亦是如此使用

四、移除指定尺寸后适配

场景:tableView 的左右间距在屏幕大小不同的情况下都为 10,在排除左右为 10 的间距后,再对Cell 进行等比适配

使用思路:宽度一共减去 20 ,以剩下的大小来做适配

Swift

建议使用 PropertyWrapper 方案,供下面的调用方式一和二使用

struct Metric {
    static let tableViewLeftRightMargin: CGFloat = 10 // 定义 tableView 的左右间距
    ...
    static let tableViewHeight: CGFloat = Fit.$width(30) // 去掉左右边距后进行适配的值
    static let rowLeftViewWidth: CGFloat = Fit.$width(177.5)
    static let rowCenterViewWidth: CGFloat = Fit.$width(100.5)
    static let rowRightViewWidth: CGFloat = Fit.$width(77)
    ...
}

struct Fit {
//    @WrappedSwiftyFitsize(fitType: .flexibleWidth, reduceValue: Metric.tableViewLeftRightMargin)
//    fitType 默认值是 .flexibleWidth,所以可以不传
    @WrappedSwiftyFitsize(reduceValue: Metric.tableViewLeftRightMargin * 2)
    static var width: CGFloat = 375
}

375 是初始化值,没有特殊意义,只为调用 Fit.width 时可以取到值,如果用不到 Fit.width 的值可以不进行初始化

调用方式:

// 移除指定尺寸后的适配,调用方式:
// 以下都是以适配 tableView 为例,移除 tableView 左右两侧固定的边距,以剩余的宽度来做适配

// 方式一:先赋值再取值
// 将 20 进行适配
Fit.width = 20
print("适配后的值 -- \(Fit.width)")

// 方式二:使用 $ 将 width 当方法用,传入待适配的值
// 将 30 进行适配
let aVal = Fit.$width(30)
print("适配后的值 aVal -- \(aVal)")

// 方式三:调用 SwiftyFitsize.fit 方法
let bVal = SwiftyFitsize.fit(
  size: 40,
  fitType: .flexibleWidth,
  reduceValue: Metric.tableViewLeftRightMargin * 2
)
print("适配后的值 bVal -- \(bVal)")

Objective-C

这是还是以适配 tableView 为例,移除 tableView 左右两侧固定的边距,以剩余的宽度来做适配

CGFloat fitWidth = [SwiftyFitsize fitWithSize:40
                                      fitType:SwiftyFitTypeFlexibleWidth
                                  reduceValue:20];

可以将其做为宏,以方便使用

#define kFitWidth(value) \
[SwiftyFitsize fitWithSize:value fitType:SwiftyFitTypeFlexibleWidth reduceValue:20]

使用宏来做适配

CGFloat fitWidth = kFitWidth(40);
NSLog(@"fitWidth -- %f", fitWidth);

效果如包含红绿蓝的条视图所示:

高度适配对比

五、计算结果类型

定义

/// 计算结果类型
@objc public enum SwiftyFitCalcResultType: Int {
    /// 跟随全局配置
    case globalConfig
    /// 原始数据
    case raw
    /// 四舍五入
    case round
    /// 保留一位小数(根据第二位小数进行四舍五入)
    case oneDecimalPlace
}

影响范围

  • .raw : 影响忽略不计
  • .round : 影响范围 (-0.5, 0.5]
  • .oneDecimalPlace : 影响范围 (-0.05, 0.05]

全局配置

  • 不配置则默认为 .raw
  • .globalConfig 取的就是这里配置的类型
  • 如果在该处还是设置为 .globalConfig,则内部会将其重置为 .raw
SwiftyFitsize.reference(width: 375, calcResultType: .oneDecimalPlace) // 全局配置计算结果为保留一位小数

使用

以下在不指定 calcResultType 参数的情况下,默认都是跟随全局配置

单独指定 calcResultType

SwiftyFitsize.fit(
    size: 35, // 36
    fitType: .flexibleWidth,
    reduceValue: 10 * 2,
    calcResultType: .raw // .round .oneDecimalPlace
)

PropertyWrapper 方式

// calcResultType: .raw .round .oneDecimalPlace
@WrappedSwiftyFitsize(reduceValue: Metric.tableViewLeftRightMargin * 2, calcResultType: .raw)
static var width: CGFloat = 375

示例数据

  • 第一列为适配前的数值

  • 其它列为适配后根据不同的 SwiftyFitCalcResultType 计算得到的值

原值 raw round oneDecimalPlace
35 36.478873239436616 36.0 36.5
36 37.52112676056338 38.0 37.5

Misc

下面列出一些设备对应的分辨率,方便查找

设备 逻辑分辨率(point) 设备分辨率(pixel)
SE 320x568 640x1136
6(S)/7/8 / SE(第二代) 375x667 750x1334
6(S)+/7+/8+ 414x736 1080x1920
X(S) / 11Pro 375x812 1125x2436
XR / 11 414x896 828x1792
XS Max / 11Pro Max 414x896 1242x2688
12 mini / 13 mini 360x780 1080x2340
12(Pro) / 13(Pro) 390x844 1170x2532
12 Pro Max / 13 Pro Max 428x926 1284x2778

License

SwiftyFitsize is available under the MIT license. See the LICENSE file for more info.

Author

Other

swiftyfitsize's People

Contributors

linxunfeng avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

swiftyfitsize's Issues

SwiftyFitsize_Swift

SwiftyFitsize_Swift[64539:576664] Failed to set (swiftyFitsize) user defined inspected property on (NSLayoutConstraint): [<NSLayoutConstraint 0x600002c64ff0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key swiftyFitsize.

使用SceneDelegate时会闪退

场景

使用SceneDelegate管理App生命周期时,调用∣-方法App会闪退

代码

class FitsizeVC: UIViewController {

    // MARK: - Overrides
    override func viewDidLoad() {
        super.viewDidLoad()

        setupUI()
        test()
    }
    
    // MARK: - Private Methods
    private func setupUI() {
        view.backgroundColor = UIColor.white
    }

    private func test() {
        
        print("view.frame.width~:\(view.frame.width) => \(view.frame.width~)")
        print("view.frame.height∣-:\(view.frame.height) => \((view.frame.height)∣-)")
        
        print(self.view.frame~)
    }
}

闪退信息:

*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<UIWindowScene 0x7f83aff06ff0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key delegate.window.'

如何适配需要按照宽度和高度分别缩放的视图

我看了下该库的源码,缩放都是依照宽度的缩放比例来进行的,无论高还是宽。
但实际上我们会遇到固定屏幕(无法滑动)的设计图, 这种视图假设是按照375*667设计,现在将其适配到iphoneX(414,812)中 倘若按照此库的适配规则,看下面2图,高度并未覆盖整体高度,而是形成了(414,736)。原因就是只参考了宽比缩放。 如果这样适配 同一套设计图 进入到X中的时候会导致底部有大量空白区域。我想知道大佬是咋么来解决这种情况的?
我在做适配的时候是预设了两个比例的, 在滑动屏幕中无论宽高都按照宽比来进行就是此库的方式,但是在固定屏幕中我是横向以宽比缩放,垂直方向以高比缩放, 来达到让iphonX此类全面屏达到预期效果

预期:应该是和6s一样的覆盖整屏的效果。

image
image

请问横屏的时候改怎么写呢

比如我现在视频播放器时横屏了
这时候我是应该, 如果我边距写 50~, 但是系统会把屏幕长的一侧当成宽度来计算吧

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.