123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600 |
- //
- // YMUtilsMacro.h
- // MSYOUPAI
- //
- // Created by YoMi on 2024/2/4.
- // Copyright © 2024 MS. All rights reserved.
- //
- /** 字符串是否为空*/
- #define OCStringIsEmpty(str) ([str isKindOfClass:[NSNull class]] || str == nil || [str length] < 1 ? YES : NO )
- /** 数组是否为空*/
- #define OCArrayIsEmpty(array) (array == nil || [array isKindOfClass:[NSNull class]] || array.count == 0)
- /** 字典是否为空*/
- #define OCDictionaryIsEmpty(dic) (dic == nil || [dic isKindOfClass:[NSNull class]] || dic.allKeys.count == 0)
- #define stringFormat(format,...) [NSString stringWithFormat:format,##__VA_ARGS__]
- #define ImageByName(value) [UIImage imageNamed:NSLocalizedString((value), nil)]
- /** 创建weakSelf*/
- #define WS(weakSelf) __weak __typeof(&*self)weakSelf = self;
- /** 数据存储*/
- #define OCUserDefaults [NSUserDefaults standardUserDefaults]
- /** 通知*/
- #define OCNotificationCenter [NSNotificationCenter defaultCenter]
- /** 自定义打印log*/
- //#ifdef DEBUG
- #define YMLog(FORMAT, ...) {\
- NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];\
- [dateFormatter setDateStyle:NSDateFormatterMediumStyle];\
- [dateFormatter setTimeStyle:NSDateFormatterShortStyle];\
- NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Beijing"];\
- [dateFormatter setTimeZone:timeZone];\
- [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss.SSSZ"];\
- NSString *str = [dateFormatter stringFromDate:[NSDate date]];\
- fprintf(stderr,"[💻DEBUG信息打印]\n[打印时间:%s]\n[打印文件来源:%s--打印字段来源第%d行]\n[文件方法:%s]\n%s\n",[str UTF8String],[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__,__PRETTY_FUNCTION__,[[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);\
- }
- //#else
- //#define YMLog(...);
- //#endif
- /** 状态条高度*/
- #define OC_STATUSBAR_HEIGHT \
- ^(){\
- if (@available(iOS 13.0, *)) {\
- UIStatusBarManager *statusBarManager = [UIApplication sharedApplication].windows.firstObject.windowScene.statusBarManager;\
- return statusBarManager.statusBarFrame.size.height;\
- } else {\
- return [UIApplication sharedApplication].statusBarFrame.size.height;\
- }\
- }()
- /** 底部指示条*/
- #define OC_INDICATOR_HEIGHT \
- ^(){\
- if (@available(iOS 13.0, *)) {\
- NSSet *set = [UIApplication sharedApplication].connectedScenes;\
- UIWindowScene *windowScene = [set anyObject];\
- UIWindow *window = windowScene.windows.firstObject;\
- return window.safeAreaInsets.bottom;\
- } else if (@available(iOS 11.0, *)) {\
- UIWindow *window = [UIApplication sharedApplication].windows.firstObject;\
- return window.safeAreaInsets.bottom;\
- }\
- }()
- #define kYMStatusBarHeight OC_STATUSBAR_HEIGHT
- #define kYMTopSafeHeight OC_STATUSBAR_HEIGHT
- #define kYMBottomSafeHeight OC_INDICATOR_HEIGHT
- /// 导航条高度
- #define kYMContentNavBarHeight 44.0
- #define kYMNavHeight (kYMStatusBarHeight + kYMContentNavBarHeight)
- #define kYMTabBarHeight (49.0 + kYMBottomSafeHeight)
- /** 是否首次进入App*/
- #define kIS_FIRST_ENTER_APP @"IS_FIRST_ENTER_APP"
- #pragma mark - CGFloat
- /**
- * 某些地方可能会将 CGFLOAT_MIN 作为一个数值参与计算(但其实 CGFLOAT_MIN 更应该被视为一个标志位而不是数值),可能导致一些精度问题,所以提供这个方法快速将 CGFLOAT_MIN 转换为 0
- * issue: https://github.com/Tencent/QMUI_iOS/issues/203
- */
- CG_INLINE CGFloat
- removeFloatMin(CGFloat floatValue) {
- return floatValue == CGFLOAT_MIN ? 0 : floatValue;
- }
- /**
- * 基于指定的倍数,对传进来的 floatValue 进行像素取整。若指定倍数为0,则表示以当前设备的屏幕倍数为准。
- *
- * 例如传进来 “2.1”,在 2x 倍数下会返回 2.5(0.5pt 对应 1px),在 3x 倍数下会返回 2.333(0.333pt 对应 1px)。
- */
- CG_INLINE CGFloat
- flatSpecificScale(CGFloat floatValue, CGFloat scale) {
- floatValue = removeFloatMin(floatValue);
- scale = scale ?: ([[UIScreen mainScreen] scale]);
- CGFloat flattedValue = ceil(floatValue * scale) / scale;
- return flattedValue;
- }
- /**
- * 基于当前设备的屏幕倍数,对传进来的 floatValue 进行像素取整。
- *
- * 注意如果在 Core Graphic 绘图里使用时,要注意当前画布的倍数是否和设备屏幕倍数一致,若不一致,不可使用 flat() 函数,而应该用 flatSpecificScale
- */
- CG_INLINE CGFloat
- flat(CGFloat floatValue) {
- return flatSpecificScale(floatValue, 0);
- }
- /**
- * 类似flat(),只不过 flat 是向上取整,而 floorInPixel 是向下取整
- */
- CG_INLINE CGFloat
- floorInPixel(CGFloat floatValue) {
- floatValue = removeFloatMin(floatValue);
- CGFloat resultValue = floor(floatValue * ([[UIScreen mainScreen] scale])) / ([[UIScreen mainScreen] scale]);
- return resultValue;
- }
- CG_INLINE BOOL
- between(CGFloat minimumValue, CGFloat value, CGFloat maximumValue) {
- return minimumValue < value && value < maximumValue;
- }
- CG_INLINE BOOL
- betweenOrEqual(CGFloat minimumValue, CGFloat value, CGFloat maximumValue) {
- return minimumValue <= value && value <= maximumValue;
- }
- /**
- * 调整给定的某个 CGFloat 值的小数点精度,超过精度的部分按四舍五入处理。
- *
- * 例如 CGFloatToFixed(0.3333, 2) 会返回 0.33,而 CGFloatToFixed(0.6666, 2) 会返回 0.67
- *
- * @warning 参数类型为 CGFloat,也即意味着不管传进来的是 float 还是 double 最终都会被强制转换成 CGFloat 再做计算
- * @warning 该方法无法解决浮点数精度运算的问题,如需做浮点数的 == 判断,可用下方的 CGFloatEqualToFloat()
- */
- CG_INLINE CGFloat
- CGFloatToFixed(CGFloat value, NSUInteger precision) {
- NSString *formatString = [NSString stringWithFormat:@"%%.%@f", @(precision)];
- NSString *toString = [NSString stringWithFormat:formatString, value];
- #if CGFLOAT_IS_DOUBLE
- CGFloat result = [toString doubleValue];
- #else
- CGFloat result = [toString floatValue];
- #endif
- return result;
- }
- /**
- 用于两个 CGFloat 值之间的比较运算,支持 ==、>、<、>=、<= 5种,内部会将浮点数转成整型,从而避免浮点数精度导致的判断错误。
-
- CGFloatEqualToFloatWithPrecision()
- CGFloatEqualToFloat()
- CGFloatMoreThanFloatWithPrecision()
- CGFloatMoreThanFloat()
- CGFloatMoreThanOrEqualToFloatWithPrecision()
- CGFloatMoreThanOrEqualToFloat()
- CGFloatLessThanFloatWithPrecision()
- CGFloatLessThanFloat()
- CGFloatLessThanOrEqualToFloatWithPrecision()
- CGFloatLessThanOrEqualToFloat()
-
- 可通过参数 precision 指定要考虑的小数点后的精度,精度的定义是保证指定的那一位小数点不会因为浮点问题导致计算错误,例如当我们要获取一个 1.0 的浮点数时,有时候会得到 0.99999999,有时候会得到 1.000000001,所以需要对指定的那一位小数点的后一位数进行四舍五入操作。
- @code
- precision = 0,也即对小数点后0+1位四舍五入
- 0.999 -> 0.9 -> round(0.9) -> 1
- 1.011 -> 1.0 -> round(1.0) -> 1
- 1.033 -> 1.0 -> round(1.0) -> 1
- 1.099 -> 1.0 -> round(1.0) -> 1
- precision = 1,也即对小数点后1+1位四舍五入
- 0.999 -> 9.9 -> round(9.9) -> 10 -> 1.0
- 1.011 -> 10.1 -> round(10.1) -> 10 -> 1.0
- 1.033 -> 10.3 -> round(10.3) -> 10 -> 1.0
- 1.099 -> 10.9 -> round(10.9) -> 11 -> 1.1
- precision = 2,也即对小数点后2+1位四舍五入
- 0.999 -> 99.9 -> round(99.9) -> 100 -> 1.00
- 1.011 -> 101.1 -> round(101.1) -> 101 -> 1.01
- 1.033 -> 103.3 -> round(103.3) -> 103 -> 1.03
- 1.099 -> 109.9 -> round(109.9) -> 110 -> 1.1
- @endcode
- */
- CG_INLINE NSInteger _RoundedIntegerFromCGFloat(CGFloat value, NSUInteger precision) {
- return (NSInteger)(round(value * pow(10, precision)));
- }
- #define _CGFloatCalcGenerator(_operatorName, _operator) CG_INLINE BOOL CGFloat##_operatorName##FloatWithPrecision(CGFloat value1, CGFloat value2, NSUInteger precision) {\
- NSInteger a = _RoundedIntegerFromCGFloat(value1, precision);\
- NSInteger b = _RoundedIntegerFromCGFloat(value2, precision);\
- return a _operator b;\
- }\
- CG_INLINE BOOL CGFloat##_operatorName##Float(CGFloat value1, CGFloat value2) {\
- return CGFloat##_operatorName##FloatWithPrecision(value1, value2, 0);\
- }
- _CGFloatCalcGenerator(EqualTo, ==)
- _CGFloatCalcGenerator(LessThan, <)
- _CGFloatCalcGenerator(LessThanOrEqualTo, <=)
- _CGFloatCalcGenerator(MoreThan, >)
- _CGFloatCalcGenerator(MoreThanOrEqualTo, >=)
- /// 用于居中运算
- CG_INLINE CGFloat
- CGFloatGetCenter(CGFloat parent, CGFloat child) {
- return flat((parent - child) / 2.0);
- }
- /// 检测某个数值如果为 NaN 则将其转换为 0,避免布局中出现 crash
- CG_INLINE CGFloat
- CGFloatSafeValue(CGFloat value) {
- return isnan(value) ? 0 : value;
- }
- #pragma mark - CGPoint
- /// 两个point相加
- CG_INLINE CGPoint
- CGPointUnion(CGPoint point1, CGPoint point2) {
- return CGPointMake(flat(point1.x + point2.x), flat(point1.y + point2.y));
- }
- /// 获取rect的center,包括rect本身的x/y偏移
- CG_INLINE CGPoint
- CGPointGetCenterWithRect(CGRect rect) {
- return CGPointMake(flat(CGRectGetMidX(rect)), flat(CGRectGetMidY(rect)));
- }
- CG_INLINE CGPoint
- CGPointGetCenterWithSize(CGSize size) {
- return CGPointMake(flat(size.width / 2.0), flat(size.height / 2.0));
- }
- CG_INLINE CGPoint
- CGPointToFixed(CGPoint point, NSUInteger precision) {
- CGPoint result = CGPointMake(CGFloatToFixed(point.x, precision), CGFloatToFixed(point.y, precision));
- return result;
- }
- CG_INLINE CGPoint
- CGPointRemoveFloatMin(CGPoint point) {
- CGPoint result = CGPointMake(removeFloatMin(point.x), removeFloatMin(point.y));
- return result;
- }
- #pragma mark - UIEdgeInsets
- /// 获取UIEdgeInsets在水平方向上的值
- CG_INLINE CGFloat
- UIEdgeInsetsGetHorizontalValue(UIEdgeInsets insets) {
- return insets.left + insets.right;
- }
- /// 获取UIEdgeInsets在垂直方向上的值
- CG_INLINE CGFloat
- UIEdgeInsetsGetVerticalValue(UIEdgeInsets insets) {
- return insets.top + insets.bottom;
- }
- /// 将两个UIEdgeInsets合并为一个
- CG_INLINE UIEdgeInsets
- UIEdgeInsetsConcat(UIEdgeInsets insets1, UIEdgeInsets insets2) {
- insets1.top += insets2.top;
- insets1.left += insets2.left;
- insets1.bottom += insets2.bottom;
- insets1.right += insets2.right;
- return insets1;
- }
- CG_INLINE UIEdgeInsets
- UIEdgeInsetsSetTop(UIEdgeInsets insets, CGFloat top) {
- insets.top = flat(top);
- return insets;
- }
- CG_INLINE UIEdgeInsets
- UIEdgeInsetsSetLeft(UIEdgeInsets insets, CGFloat left) {
- insets.left = flat(left);
- return insets;
- }
- CG_INLINE UIEdgeInsets
- UIEdgeInsetsSetBottom(UIEdgeInsets insets, CGFloat bottom) {
- insets.bottom = flat(bottom);
- return insets;
- }
- CG_INLINE UIEdgeInsets
- UIEdgeInsetsSetRight(UIEdgeInsets insets, CGFloat right) {
- insets.right = flat(right);
- return insets;
- }
- CG_INLINE UIEdgeInsets
- UIEdgeInsetsToFixed(UIEdgeInsets insets, NSUInteger precision) {
- UIEdgeInsets result = UIEdgeInsetsMake(CGFloatToFixed(insets.top, precision), CGFloatToFixed(insets.left, precision), CGFloatToFixed(insets.bottom, precision), CGFloatToFixed(insets.right, precision));
- return result;
- }
- CG_INLINE UIEdgeInsets
- UIEdgeInsetsRemoveFloatMin(UIEdgeInsets insets) {
- UIEdgeInsets result = UIEdgeInsetsMake(removeFloatMin(insets.top), removeFloatMin(insets.left), removeFloatMin(insets.bottom), removeFloatMin(insets.right));
- return result;
- }
- #pragma mark - CGSize
- /// 判断一个 CGSize 是否存在 NaN
- CG_INLINE BOOL
- CGSizeIsNaN(CGSize size) {
- return isnan(size.width) || isnan(size.height);
- }
- /// 判断一个 CGSize 是否存在 infinite
- CG_INLINE BOOL
- CGSizeIsInf(CGSize size) {
- return isinf(size.width) || isinf(size.height);
- }
- /// 判断一个 CGSize 是否为空(宽或高为0)
- CG_INLINE BOOL
- CGSizeIsEmpty(CGSize size) {
- return size.width <= 0 || size.height <= 0;
- }
- /// 判断一个 CGSize 是否合法(例如不带无穷大的值、不带非法数字)
- CG_INLINE BOOL
- CGSizeIsValidated(CGSize size) {
- return !CGSizeIsEmpty(size) && !CGSizeIsInf(size) && !CGSizeIsNaN(size);
- }
- /// 将一个 CGSize 像素对齐
- CG_INLINE CGSize
- CGSizeFlatted(CGSize size) {
- return CGSizeMake(flat(size.width), flat(size.height));
- }
- /// 将一个 CGSize 以 pt 为单位向上取整
- CG_INLINE CGSize
- CGSizeCeil(CGSize size) {
- return CGSizeMake(ceil(size.width), ceil(size.height));
- }
- /// 将一个 CGSize 以 pt 为单位向下取整
- CG_INLINE CGSize
- CGSizeFloor(CGSize size) {
- return CGSizeMake(floor(size.width), floor(size.height));
- }
- CG_INLINE CGSize
- CGSizeToFixed(CGSize size, NSUInteger precision) {
- CGSize result = CGSizeMake(CGFloatToFixed(size.width, precision), CGFloatToFixed(size.height, precision));
- return result;
- }
- CG_INLINE CGSize
- CGSizeRemoveFloatMin(CGSize size) {
- CGSize result = CGSizeMake(removeFloatMin(size.width), removeFloatMin(size.height));
- return result;
- }
- #pragma mark - CGRect
- /// 判断一个 CGRect 是否存在 NaN
- CG_INLINE BOOL
- CGRectIsNaN(CGRect rect) {
- return isnan(rect.origin.x) || isnan(rect.origin.y) || isnan(rect.size.width) || isnan(rect.size.height);
- }
- /// 系统提供的 CGRectIsInfinite 接口只能判断 CGRectInfinite 的情况,而该接口可以用于判断 INFINITY 的值
- CG_INLINE BOOL
- CGRectIsInf(CGRect rect) {
- return isinf(rect.origin.x) || isinf(rect.origin.y) || isinf(rect.size.width) || isinf(rect.size.height);
- }
- /// 判断一个 CGRect 是否合法(例如不带无穷大的值、不带非法数字)
- CG_INLINE BOOL
- CGRectIsValidated(CGRect rect) {
- return !CGRectIsNull(rect) && !CGRectIsInfinite(rect) && !CGRectIsNaN(rect) && !CGRectIsInf(rect);
- }
- /// 检测某个 CGRect 如果存在数值为 NaN 的则将其转换为 0,避免布局中出现 crash
- CG_INLINE CGRect
- CGRectSafeValue(CGRect rect) {
- return CGRectMake(CGFloatSafeValue(CGRectGetMinX(rect)), CGFloatSafeValue(CGRectGetMinY(rect)), CGFloatSafeValue(CGRectGetWidth(rect)), CGFloatSafeValue(CGRectGetHeight(rect)));
- }
- /// 创建一个像素对齐的CGRect
- CG_INLINE CGRect
- CGRectFlatMake(CGFloat x, CGFloat y, CGFloat width, CGFloat height) {
- return CGRectMake(flat(x), flat(y), flat(width), flat(height));
- }
- /// 对CGRect的x/y、width/height都调用一次flat,以保证像素对齐
- CG_INLINE CGRect
- CGRectFlatted(CGRect rect) {
- return CGRectMake(flat(rect.origin.x), flat(rect.origin.y), flat(rect.size.width), flat(rect.size.height));
- }
- /// 计算目标点 targetPoint 围绕坐标点 coordinatePoint 通过 transform 之后此点的坐标
- CG_INLINE CGPoint
- CGPointApplyAffineTransformWithCoordinatePoint(CGPoint coordinatePoint, CGPoint targetPoint, CGAffineTransform t) {
- CGPoint p;
- p.x = (targetPoint.x - coordinatePoint.x) * t.a + (targetPoint.y - coordinatePoint.y) * t.c + coordinatePoint.x;
- p.y = (targetPoint.x - coordinatePoint.x) * t.b + (targetPoint.y - coordinatePoint.y) * t.d + coordinatePoint.y;
- p.x += t.tx;
- p.y += t.ty;
- return p;
- }
- /// 系统的 CGRectApplyAffineTransform 只会按照 anchorPoint 为 (0, 0) 的方式去计算,但通常情况下我们面对的是 UIView/CALayer,它们默认的 anchorPoint 为 (.5, .5),所以增加这个函数,在计算 transform 时可以考虑上 anchorPoint 的影响
- CG_INLINE CGRect
- CGRectApplyAffineTransformWithAnchorPoint(CGRect rect, CGAffineTransform t, CGPoint anchorPoint) {
- CGFloat width = CGRectGetWidth(rect);
- CGFloat height = CGRectGetHeight(rect);
- CGPoint oPoint = CGPointMake(rect.origin.x + width * anchorPoint.x, rect.origin.y + height * anchorPoint.y);
- CGPoint top_left = CGPointApplyAffineTransformWithCoordinatePoint(oPoint, CGPointMake(rect.origin.x, rect.origin.y), t);
- CGPoint bottom_left = CGPointApplyAffineTransformWithCoordinatePoint(oPoint, CGPointMake(rect.origin.x, rect.origin.y + height), t);
- CGPoint top_right = CGPointApplyAffineTransformWithCoordinatePoint(oPoint, CGPointMake(rect.origin.x + width, rect.origin.y), t);
- CGPoint bottom_right = CGPointApplyAffineTransformWithCoordinatePoint(oPoint, CGPointMake(rect.origin.x + width, rect.origin.y + height), t);
- CGFloat minX = MIN(MIN(MIN(top_left.x, bottom_left.x), top_right.x), bottom_right.x);
- CGFloat maxX = MAX(MAX(MAX(top_left.x, bottom_left.x), top_right.x), bottom_right.x);
- CGFloat minY = MIN(MIN(MIN(top_left.y, bottom_left.y), top_right.y), bottom_right.y);
- CGFloat maxY = MAX(MAX(MAX(top_left.y, bottom_left.y), top_right.y), bottom_right.y);
- CGFloat newWidth = maxX - minX;
- CGFloat newHeight = maxY - minY;
- CGRect result = CGRectMake(minX, minY, newWidth, newHeight);
- return result;
- }
- /// 为一个CGRect叠加scale计算
- CG_INLINE CGRect
- CGRectApplyScale(CGRect rect, CGFloat scale) {
- return CGRectFlatted(CGRectMake(CGRectGetMinX(rect) * scale, CGRectGetMinY(rect) * scale, CGRectGetWidth(rect) * scale, CGRectGetHeight(rect) * scale));
- }
- /// 计算view的水平居中,传入父view和子view的frame,返回子view在水平居中时的x值
- CG_INLINE CGFloat
- CGRectGetMinXHorizontallyCenterInParentRect(CGRect parentRect, CGRect childRect) {
- return flat((CGRectGetWidth(parentRect) - CGRectGetWidth(childRect)) / 2.0);
- }
- /// 计算view的垂直居中,传入父view和子view的frame,返回子view在垂直居中时的y值
- CG_INLINE CGFloat
- CGRectGetMinYVerticallyCenterInParentRect(CGRect parentRect, CGRect childRect) {
- return flat((CGRectGetHeight(parentRect) - CGRectGetHeight(childRect)) / 2.0);
- }
- /// 返回值:同一个坐标系内,想要layoutingRect和已布局完成的referenceRect保持垂直居中时,layoutingRect的originY
- CG_INLINE CGFloat
- CGRectGetMinYVerticallyCenter(CGRect referenceRect, CGRect layoutingRect) {
- return CGRectGetMinY(referenceRect) + CGRectGetMinYVerticallyCenterInParentRect(referenceRect, layoutingRect);
- }
- /// 返回值:同一个坐标系内,想要layoutingRect和已布局完成的referenceRect保持水平居中时,layoutingRect的originX
- CG_INLINE CGFloat
- CGRectGetMinXHorizontallyCenter(CGRect referenceRect, CGRect layoutingRect) {
- return CGRectGetMinX(referenceRect) + CGRectGetMinXHorizontallyCenterInParentRect(referenceRect, layoutingRect);
- }
- /// 为给定的rect往内部缩小insets的大小(系统那个方法的命名太难联想了,所以定义了一个新函数)
- CG_INLINE CGRect
- CGRectInsetEdges(CGRect rect, UIEdgeInsets insets) {
- return UIEdgeInsetsInsetRect(rect, insets);
- }
- /// 传入size,返回一个x/y为0的CGRect
- CG_INLINE CGRect
- CGRectMakeWithSize(CGSize size) {
- return CGRectMake(0, 0, size.width, size.height);
- }
- CG_INLINE CGRect
- CGRectFloatTop(CGRect rect, CGFloat top) {
- rect.origin.y = top;
- return rect;
- }
- CG_INLINE CGRect
- CGRectFloatBottom(CGRect rect, CGFloat bottom) {
- rect.origin.y = bottom - CGRectGetHeight(rect);
- return rect;
- }
- CG_INLINE CGRect
- CGRectFloatRight(CGRect rect, CGFloat right) {
- rect.origin.x = right - CGRectGetWidth(rect);
- return rect;
- }
- CG_INLINE CGRect
- CGRectFloatLeft(CGRect rect, CGFloat left) {
- rect.origin.x = left;
- return rect;
- }
- /// 保持rect的左边缘不变,改变其宽度,使右边缘靠在right上
- CG_INLINE CGRect
- CGRectLimitRight(CGRect rect, CGFloat rightLimit) {
- rect.size.width = rightLimit - rect.origin.x;
- return rect;
- }
- /// 保持rect右边缘不变,改变其宽度和origin.x,使其左边缘靠在left上。只适合那种右边缘不动的view
- /// 先改变origin.x,让其靠在offset上
- /// 再改变size.width,减少同样的宽度,以抵消改变origin.x带来的view移动,从而保证view的右边缘是不动的
- CG_INLINE CGRect
- CGRectLimitLeft(CGRect rect, CGFloat leftLimit) {
- CGFloat subOffset = leftLimit - rect.origin.x;
- rect.origin.x = leftLimit;
- rect.size.width = rect.size.width - subOffset;
- return rect;
- }
- /// 限制rect的宽度,超过最大宽度则截断,否则保持rect的宽度不变
- CG_INLINE CGRect
- CGRectLimitMaxWidth(CGRect rect, CGFloat maxWidth) {
- CGFloat width = CGRectGetWidth(rect);
- rect.size.width = width > maxWidth ? maxWidth : width;
- return rect;
- }
- CG_INLINE CGRect
- CGRectSetX(CGRect rect, CGFloat x) {
- rect.origin.x = flat(x);
- return rect;
- }
- CG_INLINE CGRect
- CGRectSetY(CGRect rect, CGFloat y) {
- rect.origin.y = flat(y);
- return rect;
- }
- CG_INLINE CGRect
- CGRectSetXY(CGRect rect, CGFloat x, CGFloat y) {
- rect.origin.x = flat(x);
- rect.origin.y = flat(y);
- return rect;
- }
- CG_INLINE CGRect
- CGRectSetWidth(CGRect rect, CGFloat width) {
- if (width < 0) {
- return rect;
- }
- rect.size.width = flat(width);
- return rect;
- }
- CG_INLINE CGRect
- CGRectSetHeight(CGRect rect, CGFloat height) {
- if (height < 0) {
- return rect;
- }
- rect.size.height = flat(height);
- return rect;
- }
- CG_INLINE CGRect
- CGRectSetSize(CGRect rect, CGSize size) {
- rect.size = CGSizeFlatted(size);
- return rect;
- }
- CG_INLINE CGRect
- CGRectToFixed(CGRect rect, NSUInteger precision) {
- CGRect result = CGRectMake(CGFloatToFixed(CGRectGetMinX(rect), precision),
- CGFloatToFixed(CGRectGetMinY(rect), precision),
- CGFloatToFixed(CGRectGetWidth(rect), precision),
- CGFloatToFixed(CGRectGetHeight(rect), precision));
- return result;
- }
- CG_INLINE CGRect
- CGRectRemoveFloatMin(CGRect rect) {
- CGRect result = CGRectMake(removeFloatMin(CGRectGetMinX(rect)),
- removeFloatMin(CGRectGetMinY(rect)),
- removeFloatMin(CGRectGetWidth(rect)),
- removeFloatMin(CGRectGetHeight(rect)));
- return result;
- }
- /// outerRange 是否包含了 innerRange
- CG_INLINE BOOL
- NSContainingRanges(NSRange outerRange, NSRange innerRange) {
- if (innerRange.location >= outerRange.location && outerRange.location + outerRange.length >= innerRange.location + innerRange.length) {
- return YES;
- }
- return NO;
- }
|