增加换肤功能
This commit is contained in:
19
QXLive/Tools/Category/NSDate+QX.h
Normal file
19
QXLive/Tools/Category/NSDate+QX.h
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// NSDate+Category.h
|
||||
// YSDTrucksProject
|
||||
//
|
||||
// Created by 党凯 on 2020/8/20.
|
||||
// Copyright © 2020 党凯. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
|
||||
|
||||
@interface NSDate (QX)
|
||||
+ (NSString *)timeStringWithTimeInterval:(NSString *)timeStr;
|
||||
@end
|
||||
|
||||
|
||||
151
QXLive/Tools/Category/NSDate+QX.m
Normal file
151
QXLive/Tools/Category/NSDate+QX.m
Normal file
@@ -0,0 +1,151 @@
|
||||
//
|
||||
// NSDate+Category.m
|
||||
// YSDTrucksProject
|
||||
//
|
||||
// Created by 党凯 on 2020/8/20.
|
||||
// Copyright © 2020 党凯. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NSDate+QX.h"
|
||||
|
||||
@implementation NSDate (QX)
|
||||
+ (NSString *)timeStringWithTimeInterval:(NSString *)timeInterval
|
||||
{
|
||||
|
||||
NSDate *date = [NSDate dateWithTimeIntervalSince1970:timeInterval.longLongValue]; //此处根据项目需求,选择是否除以1000 , 如果时间戳精确到秒则去掉1000
|
||||
|
||||
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
|
||||
|
||||
//今天
|
||||
if ([date isToday]) {
|
||||
|
||||
// formatter.dateFormat = @"HH:mm";
|
||||
//
|
||||
// return [formatter stringFromDate:date];
|
||||
return @"今天";
|
||||
}else{
|
||||
|
||||
//昨天
|
||||
if ([date isYesterday]) {
|
||||
|
||||
// formatter.dateFormat = @"昨天HH:mm";
|
||||
// return [formatter stringFromDate:date];
|
||||
|
||||
//一周内 [date weekdayStringFromDate]
|
||||
return @"昨天";
|
||||
}else if ([date isInWeak]){
|
||||
|
||||
// formatter.dateFormat = [NSString stringWithFormat:@"%@%@",[date weekdayStringFromDate],@"HH:mm"];
|
||||
// return [formatter stringFromDate:date];
|
||||
return @"一周内";
|
||||
//直接显示年月日
|
||||
}else{
|
||||
|
||||
// formatter.dateFormat = @"yy-MM-dd HH:mm";
|
||||
formatter.dateFormat = @"yyyy-MM-dd";
|
||||
return [formatter stringFromDate:date];
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
//- (BOOL)isInWeek{
|
||||
// NSTimeInterval *time = [self ]
|
||||
//}
|
||||
|
||||
//是否在同一周
|
||||
- (BOOL)isSameWeek
|
||||
{
|
||||
|
||||
NSCalendar *calendar = [NSCalendar currentCalendar];
|
||||
int unit = NSCalendarUnitWeekday | NSCalendarUnitMonth | NSCalendarUnitYear ;
|
||||
|
||||
//1.获得当前时间的 年月日
|
||||
NSDateComponents *nowCmps = [calendar components:unit fromDate:[NSDate date]];
|
||||
|
||||
//2.获得self
|
||||
NSDateComponents *selfCmps = [calendar components:unit fromDate:self];
|
||||
|
||||
return (selfCmps.year == nowCmps.year) && (selfCmps.month == nowCmps.month) && (selfCmps.day == nowCmps.day);
|
||||
}
|
||||
|
||||
|
||||
//根据日期求星期几
|
||||
- (NSString *)weekdayStringFromDate{
|
||||
|
||||
NSArray *weekdays = [NSArray arrayWithObjects: [NSNull null], @"星期天", @"星期一", @"星期二", @"星期三", @"星期四", @"星期五", @"星期六", nil];
|
||||
|
||||
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
|
||||
|
||||
NSTimeZone *timeZone = [[NSTimeZone alloc] initWithName:@"Asia/Shanghai"];
|
||||
|
||||
[calendar setTimeZone: timeZone];
|
||||
|
||||
NSCalendarUnit calendarUnit = NSCalendarUnitWeekday;
|
||||
|
||||
NSDateComponents *theComponents = [calendar components:calendarUnit fromDate:self];
|
||||
|
||||
return [weekdays objectAtIndex:theComponents.weekday];
|
||||
|
||||
}
|
||||
|
||||
//是否在一周内
|
||||
- (BOOL)isInWeak
|
||||
{
|
||||
//2014-05-01
|
||||
NSDate *nowDate = [[NSDate date] dateWithYMD];
|
||||
|
||||
//2014-04-30
|
||||
NSDate *selfDate = [self dateWithYMD];
|
||||
|
||||
//获得nowDate和selfDate的差距
|
||||
NSCalendar *calendar = [NSCalendar currentCalendar];
|
||||
NSDateComponents *cmps = [calendar components:NSCalendarUnitDay fromDate:selfDate toDate:nowDate options:0];
|
||||
|
||||
return ((cmps.day > 1) && (cmps.day < 7));
|
||||
}
|
||||
|
||||
|
||||
//是否为今天
|
||||
- (BOOL)isToday
|
||||
{
|
||||
//now: 2015-09-05 11:23:00
|
||||
//self 调用这个方法的对象本身
|
||||
|
||||
NSCalendar *calendar = [NSCalendar currentCalendar];
|
||||
int unit = NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear ;
|
||||
|
||||
//1.获得当前时间的 年月日
|
||||
NSDateComponents *nowCmps = [calendar components:unit fromDate:[NSDate date]];
|
||||
|
||||
//2.获得self
|
||||
NSDateComponents *selfCmps = [calendar components:unit fromDate:self];
|
||||
|
||||
return (selfCmps.year == nowCmps.year) && (selfCmps.month == nowCmps.month) && (selfCmps.day == nowCmps.day);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//是否为昨天
|
||||
- (BOOL)isYesterday
|
||||
{
|
||||
//2014-05-01
|
||||
NSDate *nowDate = [[NSDate date] dateWithYMD];
|
||||
|
||||
//2014-04-30
|
||||
NSDate *selfDate = [self dateWithYMD];
|
||||
|
||||
//获得nowDate和selfDate的差距
|
||||
NSCalendar *calendar = [NSCalendar currentCalendar];
|
||||
NSDateComponents *cmps = [calendar components:NSCalendarUnitDay fromDate:selfDate toDate:nowDate options:0];
|
||||
|
||||
return cmps.day == 1;
|
||||
}
|
||||
//格式化
|
||||
- (NSDate *)dateWithYMD
|
||||
{
|
||||
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
|
||||
fmt.dateFormat = @"yyyy-MM-dd";
|
||||
NSString *selfStr = [fmt stringFromDate:self];
|
||||
return [fmt dateFromString:selfStr];
|
||||
}
|
||||
@end
|
||||
183
QXLive/Tools/Category/NSString+QX.h
Normal file
183
QXLive/Tools/Category/NSString+QX.h
Normal file
@@ -0,0 +1,183 @@
|
||||
//
|
||||
// NSString+QX.h
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/5/7.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface NSString (QX)
|
||||
/**
|
||||
* 检查是否是有效字符串
|
||||
**/
|
||||
- (BOOL)isExist;
|
||||
|
||||
/**
|
||||
有效数字控制
|
||||
|
||||
@param number 原始数据
|
||||
@return 返回字符串
|
||||
*/
|
||||
+ (NSString *)effectiveNum:(double)number;
|
||||
|
||||
/// 当前字符串是否是数字
|
||||
- (BOOL)isNumber;
|
||||
|
||||
/**
|
||||
获得富文本字符串
|
||||
|
||||
@param attriFont 字体大小
|
||||
@param attriColor 字体颜色
|
||||
@param attriRange 富文本区域
|
||||
@return 富文本字符串
|
||||
*/
|
||||
- (NSMutableAttributedString *)getNSMutableAttributedStringWithAttriFont:(UIFont *)attriFont attriColor:(UIColor *)attriColor isline:(BOOL)isline attriBackgroundColor:(nullable UIColor *)attriBackgroundColor lineSpacing:(CGFloat)lineSpacing attriRange:(NSRange)attriRange;
|
||||
|
||||
/**
|
||||
删除线
|
||||
|
||||
@param textColor 文本颜色
|
||||
@param lineColor 删除线颜色
|
||||
@param range 删除范围
|
||||
@return 富文本字符串
|
||||
*/
|
||||
|
||||
- (NSAttributedString *)deleteLineWithTextColor: (nullable UIColor *)textColor lineColor: (nullable UIColor *)lineColor range: (NSRange)range;
|
||||
- (NSAttributedString *)deleteLineWithTextColor: (nullable UIColor *)textColor lineColor: (nullable UIColor *)lineColor;
|
||||
- (NSAttributedString *)deleteLineWithTextColor: (nullable UIColor *)textColor;
|
||||
- (NSAttributedString *)deleteLine;
|
||||
/**
|
||||
验证有效手机号
|
||||
|
||||
@param phoneNum 手机号
|
||||
@return 是否有效
|
||||
*/
|
||||
+ (BOOL)effectivePhoneNum:(NSString *)phoneNum;
|
||||
|
||||
+ (BOOL)effectivePhoneNum:(NSString *)phoneNum validLength:(NSInteger)length;
|
||||
/**
|
||||
生成uuid
|
||||
追加字符串
|
||||
*/
|
||||
//+ (instancetype)effectivePhoneNumeffectivePhoneNum;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取时间
|
||||
[@"y"]; // 2017
|
||||
[@"yy"]; // 17
|
||||
[@"yyy"]; // 2017
|
||||
[@"yyyy"]; // 2017
|
||||
|
||||
[@"M"]; // 8
|
||||
[@"MM"]; // 08
|
||||
[@"MMM"]; // 8月
|
||||
[@"MMMM"]; // 八月
|
||||
|
||||
[@"d"]; // 3
|
||||
[@"dd"]; // 03
|
||||
[@"D"]; // 215,一年中的第几天
|
||||
|
||||
[@"h"]; // 4
|
||||
[@"hh"]; // 04
|
||||
[@"H"]; // 16 24小时制
|
||||
[@"HH"]; // 16
|
||||
|
||||
[@"m"]; // 28
|
||||
[@"mm"]; // 28
|
||||
[@"s"]; // 57
|
||||
[@"ss"]; // 04
|
||||
|
||||
[@"E"]; // 周四
|
||||
[@"EEEE"]; // 星期四
|
||||
[@"EEEEE"]; // 四
|
||||
[@"e"]; // 5 (显示的是一周的第几天(weekday),1为周日。)
|
||||
[@"ee"]; // 05
|
||||
[@"eee"]; // 周四
|
||||
[@"eeee"]; // 星期四
|
||||
[@"eeeee"]; // 四
|
||||
|
||||
[@"z"]; // GMT+8
|
||||
[@"zzzz"]; // 中国标准时间
|
||||
|
||||
[@"ah"]; // 下午5
|
||||
[@"aH"]; // 下午17
|
||||
[@"am"]; // 下午53
|
||||
[@"as"]; // 下午52
|
||||
*/
|
||||
//+ (NSString *)transformTimeInterval:(NSTimeInterval)sec byFormatter:(NSString *)formatter;
|
||||
//
|
||||
///// 今天显示(时:分)(9:00) 昨日显示(昨天 时:分)(昨天 10:00) 其余显示(年/月/日)(2019/11/06)
|
||||
///// @param sec 时间戳
|
||||
//+ (NSString *)transformTodayYesterdayAndOtherTimeInterval:(NSTimeInterval)sec;
|
||||
/**
|
||||
转换为升序key排列的URL参数格式的key=Value形式的字符串
|
||||
|
||||
@param dict 参数列表
|
||||
@return 格式化后的字符串
|
||||
*/
|
||||
+ (NSString *)transformByAscendingWithDict:(NSDictionary *)dict;
|
||||
|
||||
|
||||
/**
|
||||
判断data的类型
|
||||
|
||||
@return content-Type
|
||||
*/
|
||||
+ (NSString *)contentTypeWithImageData:(NSData *)data;
|
||||
|
||||
|
||||
/// 手机号脱敏
|
||||
- (NSString *)showMoblePhoneNumber;
|
||||
|
||||
- (NSDictionary<NSString *,NSString *> *)parseParameters;
|
||||
|
||||
/// 格式化字符串的长短
|
||||
/// @param limit 限制显示几个字符
|
||||
/// @param suffix 超出部分的显示字符
|
||||
- (NSString *)formatterToLimitNumStrWith:(NSUInteger)limit suffixStr:(nullable NSString *)suffix;
|
||||
- (NSString *)formatterToLimitNumStrWith:(NSUInteger)limit;
|
||||
|
||||
|
||||
/**
|
||||
显示热度值
|
||||
|
||||
@param count 热度值
|
||||
@return 返回字符串
|
||||
*/
|
||||
+ (NSString *)qx_showHotCountNum:(int64_t)count;
|
||||
/// 保留两位
|
||||
+ (NSString *)qx_showHotCountNumDouble:(int64_t)count ;
|
||||
/**
|
||||
* 显示房间名字
|
||||
*/
|
||||
- (NSString *)qx_showRoomName;
|
||||
|
||||
/**
|
||||
订单倒计时
|
||||
type == 1 返回 00:00:00
|
||||
type == 2 返回 00时00分00秒
|
||||
*/
|
||||
|
||||
+ (NSString *)timeStrFromInterval:(long)lastTime type:(NSInteger)type;
|
||||
|
||||
+ (BOOL)inputShouldLetterOrNum:(NSString *)inputString;
|
||||
|
||||
|
||||
+ (NSString *)safeString:(NSString *)string ByAppendingString:(NSString *)aString;
|
||||
|
||||
/**
|
||||
超过9999数量用w显示并保留1位小数(如14500 = 1.5w)
|
||||
*/
|
||||
- (NSString *)tenThousandFormatString;
|
||||
|
||||
- (NSInteger)ageWithDateOfBirth;
|
||||
/// 传入秒 得到 几天 几小时
|
||||
+ (NSString*)getTimeWithSecond:(long long)second;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
405
QXLive/Tools/Category/NSString+QX.m
Normal file
405
QXLive/Tools/Category/NSString+QX.m
Normal file
@@ -0,0 +1,405 @@
|
||||
//
|
||||
// NSString+QX.m
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/5/7.
|
||||
//
|
||||
|
||||
#import "NSString+QX.h"
|
||||
#import "NSDate+BRPickerView.h"
|
||||
@implementation NSString (QX)
|
||||
- (BOOL)isExist {
|
||||
if (!self) {
|
||||
return NO;
|
||||
}
|
||||
if ([self isKindOfClass:[NSNull class]]) {
|
||||
return NO;
|
||||
}
|
||||
NSCharacterSet *set = [NSCharacterSet whitespaceAndNewlineCharacterSet];
|
||||
NSString *trimmedStr = [self stringByTrimmingCharactersInSet:set];
|
||||
if (trimmedStr.length == 0 || trimmedStr.length == NSNotFound) {
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
/**
|
||||
有效数字控制
|
||||
|
||||
@param number 原始数据
|
||||
@return 返回字符串
|
||||
*/
|
||||
+ (NSString *)effectiveNum:(double)number {
|
||||
if (fmodf(number, 1) == 0 || fmodf(number * 10, 1) == 0) {
|
||||
return [NSString notRounding:number afterPoint:1];
|
||||
}else{
|
||||
return [NSString notRounding:number afterPoint:2];
|
||||
}
|
||||
}
|
||||
// 转换不四舍五入
|
||||
+ (NSString *)notRounding:(double)price afterPoint:(int)position{
|
||||
NSDecimalNumberHandler* roundingBehavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundDown scale:position raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO];
|
||||
NSDecimalNumber *ouncesDecimal;
|
||||
NSDecimalNumber *roundedOunces;
|
||||
ouncesDecimal = [[NSDecimalNumber alloc] initWithDouble:price];
|
||||
roundedOunces = [ouncesDecimal decimalNumberByRoundingAccordingToBehavior:roundingBehavior];
|
||||
return [NSString stringWithFormat:@"%@",roundedOunces];
|
||||
}
|
||||
|
||||
- (BOOL)isNumber {
|
||||
if (self.length ==0 ) {
|
||||
return NO;
|
||||
}
|
||||
unichar c;
|
||||
for (int i=0; i<self.length; i++) {
|
||||
c=[self characterAtIndex:i];
|
||||
if (!isdigit(c)) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSMutableAttributedString *)getNSMutableAttributedStringWithAttriFont:(UIFont *)attriFont attriColor:(UIColor *)attriColor isline:(BOOL)isline attriBackgroundColor:(UIColor *)attriBackgroundColor lineSpacing:(CGFloat)lineSpacing attriRange:(NSRange)attriRange {
|
||||
NSMutableAttributedString *getStr = [[NSMutableAttributedString alloc]initWithString:self];
|
||||
|
||||
NSMutableDictionary <NSAttributedStringKey, id>*dict = [NSMutableDictionary dictionaryWithCapacity:1];
|
||||
dict[NSFontAttributeName] = attriFont;
|
||||
dict[NSForegroundColorAttributeName] = attriColor;
|
||||
|
||||
if (isline) {
|
||||
dict[NSStrikethroughStyleAttributeName] = [NSNumber numberWithInteger:NSUnderlineStyleSingle];
|
||||
}
|
||||
if (attriBackgroundColor) {
|
||||
dict[NSBackgroundColorAttributeName] = attriBackgroundColor;
|
||||
}
|
||||
if (lineSpacing > 0) {//行间距
|
||||
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
|
||||
paragraphStyle.lineSpacing = lineSpacing;
|
||||
dict[NSParagraphStyleAttributeName] = paragraphStyle;
|
||||
}
|
||||
|
||||
[getStr addAttributes:dict range:attriRange];
|
||||
|
||||
return getStr;
|
||||
}
|
||||
|
||||
- (NSAttributedString *)deleteLineWithTextColor:(UIColor *)textColor lineColor:(UIColor *)lineColor range:(NSRange)range {
|
||||
if (!self || self.length == 0) {
|
||||
return nil;
|
||||
}
|
||||
NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:self
|
||||
attributes:@{NSStrikethroughStyleAttributeName: @(NSUnderlineStyleNone)}];
|
||||
[attrStr setAttributes:@{NSStrikethroughStyleAttributeName: @(NSUnderlineStyleSingle),
|
||||
NSBaselineOffsetAttributeName: @0}
|
||||
range:range];
|
||||
if (textColor) {
|
||||
[attrStr addAttribute:NSForegroundColorAttributeName value:textColor range: range];
|
||||
}
|
||||
if (lineColor) {
|
||||
[attrStr addAttribute:NSStrikethroughColorAttributeName value:lineColor range:range];
|
||||
}
|
||||
return attrStr;
|
||||
}
|
||||
|
||||
- (NSAttributedString *)deleteLineWithTextColor:(UIColor *)textColor lineColor:(UIColor *)lineColor {
|
||||
return [self deleteLineWithTextColor:textColor lineColor:lineColor range:NSMakeRange(0, self.length)];
|
||||
}
|
||||
|
||||
- (NSAttributedString *)deleteLineWithTextColor:(UIColor *)textColor {
|
||||
return [self deleteLineWithTextColor:textColor lineColor:textColor range:NSMakeRange(0, self.length)];
|
||||
}
|
||||
|
||||
- (NSAttributedString *)deleteLine {
|
||||
return [self deleteLineWithTextColor:nil lineColor:nil range:NSMakeRange(0, self.length)];
|
||||
}
|
||||
|
||||
+ (BOOL)effectivePhoneNum:(NSString *)phoneNum {
|
||||
return [self effectivePhoneNum:phoneNum validLength:11];
|
||||
}
|
||||
|
||||
+ (BOOL)effectivePhoneNum:(NSString *)phoneNum validLength:(NSInteger)length {
|
||||
NSScanner* scan = [NSScanner scannerWithString:phoneNum];
|
||||
int val;
|
||||
return [scan scanInt:&val] && [scan isAtEnd] && phoneNum.length == length;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+ (instancetype)generateUUIDString {
|
||||
CFUUIDRef puuid = CFUUIDCreate(nil);
|
||||
CFStringRef uuidString = CFUUIDCreateString(nil, puuid);
|
||||
NSString * result = (NSString *)CFBridgingRelease(CFStringCreateCopy( NULL, uuidString));
|
||||
CFRelease(puuid);
|
||||
CFRelease(uuidString);
|
||||
return result;
|
||||
}
|
||||
|
||||
//+ (NSString *)transformTimeInterval:(NSTimeInterval)sec byFormatter:(NSString *)formatter {
|
||||
// NSDate * dt = [NSDate dateWithTimeIntervalSince1970:sec];
|
||||
// NSDateFormatter * df = [NSDateFormatter shared];
|
||||
// [df setDateFormat:formatter];
|
||||
// NSString *regStr = [df stringFromDate:dt];
|
||||
// return regStr;
|
||||
//}
|
||||
//
|
||||
//+ (NSString *)transformTodayYesterdayAndOtherTimeInterval:(NSTimeInterval)sec {
|
||||
// NSDate *dt = [NSDate dateWithTimeIntervalSince1970:sec];
|
||||
// NSCalendar *calendar =[NSCalendar currentCalendar];
|
||||
// NSDateFormatter * df = [NSDateFormatter shared];
|
||||
// NSString *prefix = @"";
|
||||
// if ([calendar isDateInToday:dt]) {
|
||||
// df.dateFormat = @"HH:mm";
|
||||
// }else if ([calendar isDateInYesterday:dt]) {
|
||||
// prefix = @"昨天 ";
|
||||
// df.dateFormat = @"HH:mm";
|
||||
// }else {
|
||||
// df.dateFormat = @"yyyy/MM/dd";
|
||||
// }
|
||||
// return [NSString stringWithFormat:@"%@%@",prefix,[df stringFromDate:dt]];
|
||||
//}
|
||||
|
||||
|
||||
+ (NSString *)transformByAscendingWithDict:(NSDictionary *)dict {
|
||||
NSArray*keys = [dict allKeys];
|
||||
|
||||
NSArray*sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1,id obj2) {
|
||||
return[obj1 compare:obj2 options:NSNumericSearch];//正序
|
||||
}];
|
||||
|
||||
NSString*str =@"";
|
||||
|
||||
for(NSString*key in sortedArray) {
|
||||
|
||||
id value = [dict objectForKey:key];
|
||||
|
||||
if([value isKindOfClass:[NSDictionary class]]) {
|
||||
|
||||
value = [self transformByAscendingWithDict:value];
|
||||
|
||||
}
|
||||
|
||||
if([str length] !=0) {
|
||||
|
||||
str = [str stringByAppendingString:@"&"];
|
||||
|
||||
}
|
||||
|
||||
str = [str stringByAppendingFormat:@"%@=%@",key,value];
|
||||
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
+ (NSString *)contentTypeWithImageData:(NSData *)data {
|
||||
if (!data) {
|
||||
return @"jpeg";
|
||||
}
|
||||
|
||||
// File signatures table: http://www.garykessler.net/library/file_sigs.html
|
||||
uint8_t c;
|
||||
[data getBytes:&c length:1];
|
||||
switch (c) {
|
||||
case 0xFF:
|
||||
return @"jpeg";
|
||||
case 0x89:
|
||||
return @"png";
|
||||
case 0x47:
|
||||
return @"gif";
|
||||
case 0x49:
|
||||
case 0x4D:
|
||||
return @"tiff";
|
||||
case 0x52: {
|
||||
if (data.length >= 12) {
|
||||
//RIFF....WEBP
|
||||
NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding];
|
||||
if ([testString hasPrefix:@"RIFF"] && [testString hasSuffix:@"WEBP"]) {
|
||||
return @"webp";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x00: {
|
||||
if (data.length >= 12) {
|
||||
//....ftypheic ....ftypheix ....ftyphevc ....ftyphevx
|
||||
NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(4, 8)] encoding:NSASCIIStringEncoding];
|
||||
if ([testString isEqualToString:@"ftypheic"]
|
||||
|| [testString isEqualToString:@"ftypheix"]
|
||||
|| [testString isEqualToString:@"ftyphevc"]
|
||||
|| [testString isEqualToString:@"ftyphevx"]) {
|
||||
return @"HEIC";
|
||||
}
|
||||
//....ftypmif1 ....ftypmsf1
|
||||
if ([testString isEqualToString:@"ftypmif1"] || [testString isEqualToString:@"ftypmsf1"]) {
|
||||
return @"HEIF";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return @"jpeg";
|
||||
}
|
||||
|
||||
- (NSString *)showMoblePhoneNumber {
|
||||
if (self.length >= 7) {
|
||||
return [self stringByReplacingCharactersInRange:NSMakeRange(self.length-8, 4) withString:@"****"];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSDictionary<NSString *,NSString *> *)parseParameters{
|
||||
NSMutableDictionary *parm = [NSMutableDictionary dictionary];
|
||||
NSURLComponents *urlComponents = [[NSURLComponents alloc] initWithString:self];
|
||||
//回调遍历所有参数,添加入字典
|
||||
[urlComponents.queryItems enumerateObjectsUsingBlock:^(NSURLQueryItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
parm[obj.name] = obj.value;
|
||||
}];
|
||||
return parm;
|
||||
|
||||
}
|
||||
|
||||
- (NSString *)formatterToLimitNumStrWith:(NSUInteger)limit suffixStr:(NSString *)suffix {
|
||||
if (self.length > limit) {
|
||||
return [NSString stringWithFormat:@"%@%@",[self substringToIndex:limit],suffix ?: @""];
|
||||
}else{
|
||||
return self;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)formatterToLimitNumStrWith:(NSUInteger)limit {
|
||||
return [self formatterToLimitNumStrWith:limit suffixStr:nil];
|
||||
}
|
||||
|
||||
|
||||
|
||||
+ (NSString *)qx_showHotCountNum:(int64_t)count {
|
||||
if (count > 9999 || count < -9999) {
|
||||
// return [NSString stringWithFormat:@"%@w",[self effectiveNum:(double)count/10000.0]];
|
||||
return [NSString stringWithFormat:@"%.1fw",(double)count/10000.0];
|
||||
}else {
|
||||
return [NSString stringWithFormat:@"%lld",count];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+ (NSString *)qx_showHotCountNumDouble:(int64_t)count {
|
||||
if (count > 9999 || count < -9999) {
|
||||
// return [NSString stringWithFormat:@"%@w",[self effectiveNum:(double)count/10000.0]];
|
||||
return [NSString stringWithFormat:@"%.2fw",(double)count/10000.0];
|
||||
}else {
|
||||
return [NSString stringWithFormat:@"%lld",count];
|
||||
}
|
||||
}
|
||||
- (NSString *)qx_showRoomName {
|
||||
if (self.length > 10) {
|
||||
return [NSString stringWithFormat:@"%@...",[self formatterToLimitNumStrWith:10]];
|
||||
}else {
|
||||
return self;
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSString *)timeStrFromInterval:(long)lastTime type:(NSInteger)type{
|
||||
if (lastTime < 60) {
|
||||
NSString *secondStr = [NSString stringWithFormat:@"%ld",lastTime];
|
||||
if (lastTime < 10) {
|
||||
secondStr = [NSString stringWithFormat:@"0%@",secondStr];
|
||||
}
|
||||
if (type == 1) {
|
||||
return [NSString stringWithFormat:@"00:%@",secondStr];
|
||||
}
|
||||
return [NSString stringWithFormat:@"%ld秒",lastTime];
|
||||
}
|
||||
if (lastTime < 3600) {
|
||||
NSString *minuteStr = [NSString stringWithFormat:@"%ld",lastTime / 60];
|
||||
NSString *secondStr = [NSString stringWithFormat:@"%ld",lastTime % 60];
|
||||
if (minuteStr.length == 1) {
|
||||
minuteStr = [NSString stringWithFormat:@"0%@",minuteStr];
|
||||
}
|
||||
if (secondStr.length == 1) {
|
||||
secondStr = [NSString stringWithFormat:@"0%@",secondStr];
|
||||
}
|
||||
if (type == 1) {
|
||||
return [NSString stringWithFormat:@"%@:%@",minuteStr,secondStr];
|
||||
}
|
||||
return [NSString stringWithFormat:@"%ld分%ld秒",lastTime / 60,lastTime % 60];
|
||||
}
|
||||
NSString *hourStr = [NSString stringWithFormat:@"%ld",lastTime / 3600];
|
||||
NSString *minuteStr = [NSString stringWithFormat:@"%ld",(lastTime % 3600) / 60];
|
||||
if (minuteStr.length == 1) {
|
||||
minuteStr = [NSString stringWithFormat:@"0%@",minuteStr];
|
||||
}
|
||||
if (type == 1) {
|
||||
return [NSString stringWithFormat:@"%@:%@",hourStr,minuteStr];
|
||||
}
|
||||
return [NSString stringWithFormat:@"%ld时%ld分",lastTime / 3600,(lastTime % 3600) / 60];
|
||||
}
|
||||
|
||||
+ (BOOL)inputShouldLetterOrNum:(NSString *)inputString {
|
||||
if (inputString.length == 0) return NO;
|
||||
NSString *regex =@"[a-zA-Z0-9]*";
|
||||
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];
|
||||
return [pred evaluateWithObject:inputString];
|
||||
}
|
||||
|
||||
+ (NSString *)safeString:(NSString *)string ByAppendingString:(NSString *)aString{
|
||||
if ([string isKindOfClass:[NSString class]]) {
|
||||
if (![string isExist]) {
|
||||
string = @"";
|
||||
}
|
||||
}else {
|
||||
string = @"";
|
||||
}
|
||||
if ([aString isKindOfClass:[NSString class]]) {
|
||||
if (![aString isExist]) {
|
||||
aString = @"";
|
||||
}
|
||||
}else {
|
||||
aString = @"";
|
||||
}
|
||||
return [NSString stringWithFormat:@"%@%@",string,aString];
|
||||
}
|
||||
|
||||
- (NSString *)tenThousandFormatString {
|
||||
NSInteger number = [self integerValue];
|
||||
if (number < 10000) {
|
||||
return number < 0 ? @"0" : [NSString stringWithFormat:@"%ld",(long)number];
|
||||
}else {
|
||||
double temp = number / 10000.0;
|
||||
NSDecimalNumberHandler *roundingBehavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain scale:1 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO];
|
||||
NSDecimalNumber *decimal = [[NSDecimalNumber alloc] initWithDouble:temp];
|
||||
NSNumber *ratio = [decimal decimalNumberByRoundingAccordingToBehavior:roundingBehavior];
|
||||
return [[NSNumberFormatter localizedStringFromNumber:ratio numberStyle:NSNumberFormatterDecimalStyle] stringByAppendingString:@"w"];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSInteger)ageWithDateOfBirth{
|
||||
NSDate *date = [NSDate br_dateFromString:self dateFormat:@"yyyy-MM-dd"];
|
||||
// 出生日期转换 年月日
|
||||
NSDateComponents *components1 = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:date];
|
||||
NSInteger brithDateYear = [components1 year];
|
||||
NSInteger brithDateDay = [components1 day];
|
||||
NSInteger brithDateMonth = [components1 month];
|
||||
|
||||
// 获取系统当前 年月日
|
||||
NSDateComponents *components2 = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:[NSDate date]];
|
||||
NSInteger currentDateYear = [components2 year];
|
||||
NSInteger currentDateDay = [components2 day];
|
||||
NSInteger currentDateMonth = [components2 month];
|
||||
|
||||
// 计算年龄
|
||||
NSInteger iAge = currentDateYear - brithDateYear - 1;
|
||||
if ((currentDateMonth > brithDateMonth) || (currentDateMonth == brithDateMonth && currentDateDay >= brithDateDay)) {
|
||||
iAge++;
|
||||
}
|
||||
|
||||
return iAge;
|
||||
}
|
||||
+(NSString *)getTimeWithSecond:(long long)second{
|
||||
NSInteger day = second/(60*60*24);
|
||||
NSInteger hour = second%(60*60*24)/(60*60);
|
||||
return [NSString stringWithFormat:@"%ld天%ld小时",day,hour];
|
||||
}
|
||||
@end
|
||||
34
QXLive/Tools/Category/UIButton+QX.h
Normal file
34
QXLive/Tools/Category/UIButton+QX.h
Normal file
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// UIButton+QX.h
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/4/28.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
typedef NS_ENUM(NSUInteger, QXButtonEdgeInsetsStyle) {
|
||||
QXButtonEdgeInsetsStyleTop, ///< image在上,label在下
|
||||
QXButtonEdgeInsetsStyleLeft, ///< image在左,label在右
|
||||
QXButtonEdgeInsetsStyleBottom, ///< image在下,label在上
|
||||
QXButtonEdgeInsetsStyleRight ///< image在右,label在左
|
||||
};
|
||||
@interface UIButton (QX)
|
||||
|
||||
/**
|
||||
设置button的titleLabel和imageView的布局样式及间距
|
||||
|
||||
@param style titleLabel和imageView的布局样式
|
||||
@param space titleLabel和imageView的b间距
|
||||
*/
|
||||
- (void)qx_layoutButtonWithEdgeInsetsStyle:(QXButtonEdgeInsetsStyle)style
|
||||
imageTitleSpace:(CGFloat)space;
|
||||
|
||||
- (void)qx_layoutButtonNOSizeToFitWithEdgeInsetsStyle:(QXButtonEdgeInsetsStyle)style
|
||||
imageTitleSpace:(CGFloat)space;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
127
QXLive/Tools/Category/UIButton+QX.m
Normal file
127
QXLive/Tools/Category/UIButton+QX.m
Normal file
@@ -0,0 +1,127 @@
|
||||
//
|
||||
// UIButton+QX.m
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/4/28.
|
||||
//
|
||||
|
||||
#import "UIButton+QX.h"
|
||||
|
||||
@implementation UIButton (QX)
|
||||
- (void)qx_layoutButtonWithEdgeInsetsStyle:(QXButtonEdgeInsetsStyle)style
|
||||
imageTitleSpace:(CGFloat)space{
|
||||
[self sizeToFit];
|
||||
[self qx_layoutButtonNOSizeToFitWithEdgeInsetsStyle:style imageTitleSpace:space];
|
||||
}
|
||||
|
||||
- (void)qx_layoutButtonNOSizeToFitWithEdgeInsetsStyle:(QXButtonEdgeInsetsStyle)style
|
||||
imageTitleSpace:(CGFloat)space {
|
||||
/**
|
||||
* 前置知识点:titleEdgeInsets是title相对于其上下左右的inset,跟tableView的contentInset是类似的,
|
||||
* 如果只有title,那它的上下左右都是相对于button的,image也是一样;
|
||||
* 如果同时有image和label,那这时候image的上左下是相对于button,右边是相对于label的;title的上右下是相对于button,左边是相对于image的。
|
||||
*/
|
||||
|
||||
CGFloat spacef = ceilf(space);
|
||||
|
||||
|
||||
// 1.得到imageView和titleLabel的宽、高
|
||||
CGFloat imageWidth = self.imageView.frame.size.width;
|
||||
CGFloat imageHeight = self.imageView.frame.size.height;
|
||||
|
||||
CGFloat labelWidth = 0.0;
|
||||
CGFloat labelHeight = 0.0;
|
||||
if (@available(iOS 8.0, *)) {
|
||||
// 由于iOS8中titleLabel的size为0,用下面的设置
|
||||
labelWidth = self.titleLabel.intrinsicContentSize.width;
|
||||
labelHeight = self.titleLabel.intrinsicContentSize.height;
|
||||
}else {
|
||||
labelWidth = self.titleLabel.frame.size.width;
|
||||
labelHeight = self.titleLabel.frame.size.height;
|
||||
}
|
||||
|
||||
// 2.声明全局的imageEdgeInsets和labelEdgeInsets
|
||||
UIEdgeInsets imageEdgeInsets = UIEdgeInsetsZero;
|
||||
UIEdgeInsets labelEdgeInsets = UIEdgeInsetsZero;
|
||||
UIEdgeInsets contentEdgeInsets = UIEdgeInsetsZero;
|
||||
|
||||
CGFloat imageOffSetX = labelWidth / 2.0;
|
||||
CGFloat labelOffSetX = imageWidth / 2.0;
|
||||
|
||||
CGFloat maxWidth = MAX(imageWidth,labelWidth); // 上下排布宽度肯定变小 获取最大宽度的那个
|
||||
CGFloat changeWidth = imageWidth + labelWidth - maxWidth; // 横向缩小的总宽度
|
||||
CGFloat maxHeight = MAX(imageHeight,labelHeight); // 获取最大高度那个 (就是水平默认排布的时候的原始高度)
|
||||
|
||||
// 3.根据style和spacef得到imageEdgeInsets和labelEdgeInsets的值
|
||||
switch (style) {
|
||||
case QXButtonEdgeInsetsStyleTop:
|
||||
{
|
||||
CGFloat gap = (maxHeight - MIN(imageHeight, labelHeight))/2.0;
|
||||
if (imageHeight >= labelHeight) {
|
||||
imageEdgeInsets = UIEdgeInsetsMake(0, imageOffSetX, 0, -imageOffSetX);
|
||||
labelEdgeInsets = UIEdgeInsetsMake(labelHeight + gap + spacef, -labelOffSetX, -(labelHeight + gap + spacef), labelOffSetX);
|
||||
contentEdgeInsets = UIEdgeInsetsMake(0, - changeWidth / 2.0, spacef + labelHeight, -changeWidth / 2.0);
|
||||
}else{
|
||||
imageEdgeInsets = UIEdgeInsetsMake(-(gap + imageHeight + spacef), imageOffSetX, gap + imageHeight + spacef, -imageOffSetX);
|
||||
labelEdgeInsets = UIEdgeInsetsMake(0, -labelOffSetX, 0, labelOffSetX);
|
||||
contentEdgeInsets = UIEdgeInsetsMake(spacef + imageHeight, - changeWidth / 2.0, 0, -changeWidth / 2.0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QXButtonEdgeInsetsStyleLeft:
|
||||
{
|
||||
imageEdgeInsets = UIEdgeInsetsMake(0, -spacef/2.0, 0, spacef/2.0);
|
||||
labelEdgeInsets = UIEdgeInsetsMake(0, spacef/2.0, 0, -spacef/2.0);
|
||||
contentEdgeInsets = UIEdgeInsetsMake(0, spacef/2.0, 0, spacef/2.0);
|
||||
}
|
||||
break;
|
||||
case QXButtonEdgeInsetsStyleBottom:
|
||||
{
|
||||
CGFloat gap = (maxHeight - MIN(imageHeight, labelHeight))/2.0;
|
||||
if (imageHeight >= labelHeight) {
|
||||
imageEdgeInsets = UIEdgeInsetsMake(0,
|
||||
imageOffSetX,
|
||||
0,
|
||||
-imageOffSetX);
|
||||
labelEdgeInsets = UIEdgeInsetsMake(-(labelHeight + gap + spacef),
|
||||
-labelOffSetX,
|
||||
labelHeight + gap + spacef,
|
||||
labelOffSetX);
|
||||
contentEdgeInsets = UIEdgeInsetsMake(spacef + labelHeight,
|
||||
- changeWidth / 2.0,
|
||||
0,
|
||||
-changeWidth / 2.0);
|
||||
}else{
|
||||
imageEdgeInsets = UIEdgeInsetsMake(gap + imageHeight + spacef,
|
||||
imageOffSetX,
|
||||
-(gap + imageHeight + spacef),
|
||||
-imageOffSetX);
|
||||
labelEdgeInsets = UIEdgeInsetsMake(0,
|
||||
-labelOffSetX,
|
||||
0,
|
||||
labelOffSetX);
|
||||
contentEdgeInsets = UIEdgeInsetsMake(0,
|
||||
- changeWidth / 2.0,
|
||||
spacef + imageHeight,
|
||||
-changeWidth / 2.0);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case QXButtonEdgeInsetsStyleRight:
|
||||
{
|
||||
imageEdgeInsets = UIEdgeInsetsMake(0, labelWidth+spacef/2.0, 0, -labelWidth-spacef/2.0);
|
||||
labelEdgeInsets = UIEdgeInsetsMake(0, -imageWidth-spacef/2.0, 0, imageWidth+spacef/2.0);
|
||||
contentEdgeInsets = UIEdgeInsetsMake(0, spacef/2.0, 0, spacef/2.0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// 4.赋值
|
||||
self.titleEdgeInsets = labelEdgeInsets;
|
||||
self.imageEdgeInsets = imageEdgeInsets;
|
||||
self.contentEdgeInsets = contentEdgeInsets;
|
||||
}
|
||||
@end
|
||||
25
QXLive/Tools/Category/UIColor+QX.h
Executable file
25
QXLive/Tools/Category/UIColor+QX.h
Executable file
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// UIColor+Hex.h
|
||||
// OCThemeDemo
|
||||
//
|
||||
// Created by 阿飞 on 2019/5/7.
|
||||
// Copyright © 2020 阿飞. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface UIColor (QX)
|
||||
|
||||
//随机色
|
||||
+ (UIColor *)sh_colorArc4random;
|
||||
|
||||
//从十六进制字符串获取颜色,
|
||||
+ (UIColor *)sh_colorWithHexString:(NSString *)color;
|
||||
|
||||
//color:支持@“#123456”、 @“0X123456”、 @“123456”三种格式
|
||||
+ (UIColor *)sh_colorWithHexString:(NSString *)color alpha:(CGFloat)alpha;
|
||||
|
||||
//渐变色
|
||||
+ (UIColor *)sh_getColorOfPercent:(CGFloat)percent between:(UIColor *)color1 and:(UIColor *)color2;
|
||||
|
||||
@end
|
||||
94
QXLive/Tools/Category/UIColor+QX.m
Executable file
94
QXLive/Tools/Category/UIColor+QX.m
Executable file
@@ -0,0 +1,94 @@
|
||||
//
|
||||
// UIColor+Hex.m
|
||||
// OCThemeDemo
|
||||
//
|
||||
// Created by 阿飞 on 2019/5/7.
|
||||
// Copyright © 2020 阿飞. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIColor+QX.h"
|
||||
|
||||
@implementation UIColor (QX)
|
||||
|
||||
+ (UIColor *)sh_colorWithHexString:(NSString *)color alpha:(CGFloat)alpha {
|
||||
//删除字符串中的空格
|
||||
NSString *cString = [[color stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString];
|
||||
// String should be 6 or 8 characters
|
||||
if ([cString length] < 6)
|
||||
{
|
||||
return [UIColor clearColor];
|
||||
}
|
||||
// strip 0X if it appears
|
||||
//如果是0x开头的,那么截取字符串,字符串从索引为2的位置开始,一直到末尾
|
||||
if ([cString hasPrefix:@"0X"])
|
||||
{
|
||||
cString = [cString substringFromIndex:2];
|
||||
}
|
||||
//如果是#开头的,那么截取字符串,字符串从索引为1的位置开始,一直到末尾
|
||||
if ([cString hasPrefix:@"#"])
|
||||
{
|
||||
cString = [cString substringFromIndex:1];
|
||||
}
|
||||
if ([cString length] != 6)
|
||||
{
|
||||
return [UIColor clearColor];
|
||||
}
|
||||
|
||||
// Separate into r, g, b substrings
|
||||
NSRange range;
|
||||
range.location = 0;
|
||||
range.length = 2;
|
||||
//r
|
||||
NSString *rString = [cString substringWithRange:range];
|
||||
//g
|
||||
range.location = 2;
|
||||
NSString *gString = [cString substringWithRange:range];
|
||||
//b
|
||||
range.location = 4;
|
||||
NSString *bString = [cString substringWithRange:range];
|
||||
|
||||
// Scan values
|
||||
unsigned int r, g, b;
|
||||
[[NSScanner scannerWithString:rString] scanHexInt:&r];
|
||||
[[NSScanner scannerWithString:gString] scanHexInt:&g];
|
||||
[[NSScanner scannerWithString:bString] scanHexInt:&b];
|
||||
return [UIColor colorWithRed:((float)r / 255.0f) green:((float)g / 255.0f) blue:((float)b / 255.0f) alpha:alpha];
|
||||
}
|
||||
|
||||
//默认alpha值为1
|
||||
+ (UIColor *)sh_colorWithHexString:(NSString *)color {
|
||||
return [self sh_colorWithHexString:color alpha:1.0f];
|
||||
}
|
||||
|
||||
+ (UIColor *)sh_colorArc4random {
|
||||
|
||||
float red = arc4random()%256 / 255.0;
|
||||
float bule = arc4random()%256 / 255.0;
|
||||
float green = arc4random()%256 / 255.0;
|
||||
|
||||
return [UIColor colorWithRed:red green:green blue:bule alpha:1.0];
|
||||
}
|
||||
|
||||
#pragma mark - 两种颜色之间的渐变
|
||||
/**
|
||||
* 两种颜色之间的渐变
|
||||
*
|
||||
* @param percent 渐变百分率
|
||||
* @param color1 颜色1(高亮颜色)
|
||||
* @param color2 颜色2(普通状态颜色)
|
||||
*
|
||||
*/
|
||||
+ (UIColor *)sh_getColorOfPercent:(CGFloat)percent between:(UIColor *)color1 and:(UIColor *)color2{
|
||||
CGFloat red1, green1, blue1, alpha1;
|
||||
[color1 getRed:&red1 green:&green1 blue:&blue1 alpha:&alpha1];
|
||||
|
||||
CGFloat red2, green2, blue2, alpha2;
|
||||
[color2 getRed:&red2 green:&green2 blue:&blue2 alpha:&alpha2];
|
||||
|
||||
CGFloat p1 = percent;
|
||||
CGFloat p2 = 1.0 - percent;
|
||||
UIColor *mid = [UIColor colorWithRed:red1*p1+red2*p2 green:green1*p1+green2*p2 blue:blue1*p1+blue2*p2 alpha:1.0f];
|
||||
return mid;
|
||||
}
|
||||
|
||||
@end
|
||||
24
QXLive/Tools/Category/UIControl+QX.h
Normal file
24
QXLive/Tools/Category/UIControl+QX.h
Normal file
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// UIControl+QX.h
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/5/19.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
static const char *UIControl_acceptEventInterval = "UIControl_acceptEventInterval";
|
||||
static const void *BandNameKey = &BandNameKey;
|
||||
|
||||
|
||||
@interface UIControl (QX)
|
||||
|
||||
@property (nonatomic, assign)NSTimeInterval needEventInterval; /* 多少秒后再次响应 */
|
||||
@property (nonatomic, assign, readonly)BOOL ignoreEvent; /*查看当前是否已经停止响应 如果停止响应为YES, 可以再次交互响应为NO; 不是固定的, 取到的值是动态变化的 和needEventIntervaly有关*/
|
||||
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
86
QXLive/Tools/Category/UIControl+QX.m
Normal file
86
QXLive/Tools/Category/UIControl+QX.m
Normal file
@@ -0,0 +1,86 @@
|
||||
//
|
||||
// UIControl+QX.m
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/5/19.
|
||||
//
|
||||
|
||||
#import "UIControl+QX.h"
|
||||
static inline void swizzling_exchangeMethodWithSelector(Class clazz, SEL originalSelector, SEL exchangeSelector) {
|
||||
// 获取原方法
|
||||
Method originalMethod = class_getInstanceMethod(clazz, originalSelector);
|
||||
|
||||
// 获取需要交换的方法
|
||||
Method exchangeMethod = class_getInstanceMethod(clazz, exchangeSelector);
|
||||
|
||||
if (!originalMethod || !exchangeMethod) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (class_addMethod(clazz, originalSelector, method_getImplementation(exchangeMethod), method_getTypeEncoding(exchangeMethod))) {
|
||||
class_replaceMethod(clazz, exchangeSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
|
||||
}else{
|
||||
method_exchangeImplementations(originalMethod, exchangeMethod);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static inline void swizzling_exchangeMethodWithMethod(Method originalMethod, Method exchangeMethod) {
|
||||
method_exchangeImplementations(originalMethod, exchangeMethod);
|
||||
}
|
||||
|
||||
@implementation UIControl (QX)
|
||||
|
||||
|
||||
- (NSTimeInterval)needEventInterval
|
||||
{
|
||||
|
||||
return [objc_getAssociatedObject(self, UIControl_acceptEventInterval) doubleValue];
|
||||
|
||||
}
|
||||
|
||||
- (void)setNeedEventInterval:(NSTimeInterval)needEventInterval
|
||||
{
|
||||
objc_setAssociatedObject(self, UIControl_acceptEventInterval, @(needEventInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
|
||||
}
|
||||
|
||||
- (BOOL)ignoreEvent
|
||||
{
|
||||
return [objc_getAssociatedObject(self, BandNameKey) boolValue];
|
||||
}
|
||||
|
||||
- (void)setIgnoreEvent:(BOOL)ignoreEvent
|
||||
{
|
||||
objc_setAssociatedObject(self, BandNameKey, [NSNumber numberWithBool:ignoreEvent], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
|
||||
+(void)load
|
||||
{
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
swizzling_exchangeMethodWithSelector([self class],
|
||||
@selector(sendAction:to:forEvent:),
|
||||
@selector(__uxy_sendAction:to:forEvent:));
|
||||
});
|
||||
}
|
||||
|
||||
- (void)__uxy_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event
|
||||
{
|
||||
|
||||
if (self.ignoreEvent) return; /*当ignoreEvent为no时, 此时会检测时间响应*/
|
||||
if (self.needEventInterval > 0)
|
||||
{
|
||||
self.ignoreEvent = YES;
|
||||
[self performSelector:@selector(changeIgnoreEvent) withObject:@(NO) afterDelay:self.needEventInterval];
|
||||
}
|
||||
[self __uxy_sendAction:action to:target forEvent:event]; //此时交换走原来方法;
|
||||
}
|
||||
|
||||
- (void)changeIgnoreEvent
|
||||
{
|
||||
self.ignoreEvent = NO;
|
||||
}
|
||||
|
||||
@end
|
||||
80
QXLive/Tools/Category/UIImage+QX.h
Normal file
80
QXLive/Tools/Category/UIImage+QX.h
Normal file
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// UIImage+QX.h
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/4/28.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface UIImage (QX)
|
||||
typedef NS_ENUM(NSUInteger, GradientType) {
|
||||
GradientTypeTopToBottom = 0,//从上到小
|
||||
GradientTypeLeftToRight = 1,//从左到右
|
||||
GradientTypeUpleftToLowright = 2,//左上到右下
|
||||
GradientTypeUprightToLowleft = 3,//右上到左下
|
||||
};
|
||||
|
||||
|
||||
// 指定尺寸 进行图片压缩
|
||||
- (NSData *)qx_compressImageQualityWithToByte:(NSInteger)maxLength;
|
||||
|
||||
|
||||
/**
|
||||
把view生成UIImage图片
|
||||
|
||||
@param view 传入view
|
||||
@return 生成的UIImage
|
||||
*/
|
||||
+ (UIImage *)qx_convertViewToImageWith:(UIView *)view;
|
||||
|
||||
+ (UIImage *)qx_gradientColorImageFromColors:(NSArray*)colors gradientType:(GradientType)gradientType imgSize:(CGSize)imgSize;
|
||||
|
||||
/**
|
||||
根据颜色,生成UIImage对象
|
||||
|
||||
@param color color对象
|
||||
@return UIImage 实例对象
|
||||
*/
|
||||
+ (instancetype)qx_imageWithColor:(UIColor *)color;
|
||||
|
||||
/**
|
||||
把图片image对象的size 缩放到控件的实际大小
|
||||
|
||||
@param size 控件实际尺寸
|
||||
@param fillColor 周围颜色
|
||||
@return 新的image对象
|
||||
*/
|
||||
- (instancetype)qx_imageFitWithSize:(CGSize)size fillColor:(UIColor *)fillColor;
|
||||
|
||||
/**
|
||||
把图片image对象,处理成圆角
|
||||
|
||||
@param radius 圆角半径
|
||||
@param corners 控制圆角的位置
|
||||
@param fillColor 被裁减掉区域的颜色
|
||||
@param zoomSize 缩放尺寸,应等于控件的尺寸
|
||||
@return 新的image对象
|
||||
*/
|
||||
- (instancetype)qx_imageCornerWithRadius:(CGFloat)radius byRoundingCorners:(UIRectCorner)corners fillColor:(UIColor *)fillColor zoomSize:(CGSize)zoomSize;
|
||||
|
||||
/**
|
||||
设置图片圆角
|
||||
|
||||
@param radius 圆角半径
|
||||
@param fillColor 被裁减掉区域的颜色
|
||||
@param zoomSize 缩放尺寸,应等于控件的尺寸
|
||||
@return 新的image对象
|
||||
*/
|
||||
- (instancetype)qx_imageCornerWithRadius:(CGFloat)radius fillColor:(UIColor *)fillColor zoomSize:(CGSize)zoomSize;
|
||||
|
||||
/*
|
||||
获取系统启动页的图片
|
||||
*/
|
||||
+ (instancetype)qx_getAppLauchImage;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
139
QXLive/Tools/Category/UIImage+QX.m
Normal file
139
QXLive/Tools/Category/UIImage+QX.m
Normal file
@@ -0,0 +1,139 @@
|
||||
//
|
||||
// UIImage+QX.m
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/4/28.
|
||||
//
|
||||
|
||||
#import "UIImage+QX.h"
|
||||
|
||||
@implementation UIImage (QX)
|
||||
// 指定尺寸 进行图片压缩
|
||||
- (NSData *)qx_compressImageQualityWithToByte:(NSInteger)maxLength {
|
||||
CGFloat compression = 1;
|
||||
NSData *data = UIImageJPEGRepresentation(self, compression);
|
||||
if (data.length <= maxLength) {
|
||||
return data;
|
||||
}
|
||||
compression = (CGFloat)maxLength / data.length;
|
||||
return UIImageJPEGRepresentation(self, compression);
|
||||
}
|
||||
|
||||
+ (UIImage *)qx_convertViewToImageWith:(UIView *)view {
|
||||
//UIGraphicsBeginImageContextWithOptions(区域大小, 是否是非透明的, 屏幕密度);
|
||||
UIGraphicsBeginImageContextWithOptions(view.frame.size, YES, [UIScreen mainScreen].scale);
|
||||
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
|
||||
UIImage *imageRet = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
return imageRet;
|
||||
}
|
||||
|
||||
+ (UIImage *)qx_imageWithColor:(UIColor *)color {
|
||||
CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
UIGraphicsBeginImageContext(rect.size);
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
|
||||
CGContextSetFillColorWithColor(context, [color CGColor]);
|
||||
CGContextFillRect(context, rect);
|
||||
|
||||
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
+ (UIImage *)qx_gradientColorImageFromColors:(NSArray *)colors gradientType:(GradientType)gradientType imgSize:(CGSize)imgSize {
|
||||
NSMutableArray *ar = [NSMutableArray array];
|
||||
for (UIColor *c in colors) {
|
||||
[ar addObject:(id)c.CGColor];
|
||||
}
|
||||
|
||||
UIGraphicsBeginImageContextWithOptions(imgSize, YES, 1);
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
CGContextSaveGState(context);
|
||||
CGColorSpaceRef colorSpace = CGColorGetColorSpace([[colors lastObject] CGColor]);
|
||||
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)ar, NULL);
|
||||
CGPoint start;
|
||||
CGPoint end;
|
||||
|
||||
switch (gradientType) {
|
||||
case GradientTypeTopToBottom:
|
||||
start = CGPointMake(0.0, 0.0);
|
||||
end = CGPointMake(0.0, imgSize.height);
|
||||
break;
|
||||
case GradientTypeLeftToRight:
|
||||
start = CGPointMake(0.0, 0.0);
|
||||
end = CGPointMake(imgSize.width, 0.0);
|
||||
break;
|
||||
case GradientTypeUpleftToLowright:
|
||||
start = CGPointMake(0.0, 0.0);
|
||||
end = CGPointMake(imgSize.width, imgSize.height);
|
||||
break;
|
||||
case GradientTypeUprightToLowleft:
|
||||
start = CGPointMake(imgSize.width, 0.0);
|
||||
end = CGPointMake(0.0, imgSize.height);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
CGContextDrawLinearGradient(context, gradient, start, end, kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
|
||||
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
CGGradientRelease(gradient);
|
||||
CGContextRestoreGState(context);
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
UIGraphicsEndImageContext();
|
||||
return image;
|
||||
}
|
||||
|
||||
- (instancetype)qx_imageFitWithSize:(CGSize)size fillColor:(UIColor *)fillColor {
|
||||
UIGraphicsBeginImageContextWithOptions(size, YES, 0);
|
||||
CGRect rect = (CGRect) { CGPointZero, size };
|
||||
[fillColor setFill];
|
||||
UIRectFill(rect);
|
||||
[self drawInRect:rect];
|
||||
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
return image;
|
||||
}
|
||||
|
||||
- (instancetype)qx_imageCornerWithRadius:(CGFloat)radius byRoundingCorners:(UIRectCorner)corners fillColor:(UIColor *)fillColor zoomSize:(CGSize)zoomSize {
|
||||
UIGraphicsBeginImageContextWithOptions(zoomSize, YES, 0);
|
||||
CGRect rect = (CGRect) { CGPointZero, zoomSize };
|
||||
[fillColor setFill];
|
||||
UIRectFill(rect);
|
||||
CGSize size = CGSizeMake(radius, radius);
|
||||
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:corners cornerRadii:size];
|
||||
[path addClip];
|
||||
[self drawInRect:rect];
|
||||
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
|
||||
return img;
|
||||
}
|
||||
|
||||
- (instancetype)qx_imageCornerWithRadius:(CGFloat)radius fillColor:(UIColor *)fillColor zoomSize:(CGSize)zoomSize {
|
||||
return [self qx_imageCornerWithRadius:radius byRoundingCorners:UIRectCornerAllCorners fillColor:fillColor zoomSize:zoomSize];
|
||||
}
|
||||
|
||||
+ (instancetype)qx_getAppLauchImage {
|
||||
CGSize viewSize = [UIScreen mainScreen].bounds.size;
|
||||
NSString *viewOrienttation = @"Portrait";
|
||||
NSString *launchImage = nil;
|
||||
NSArray *imageDict = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"UILaunchImages"];
|
||||
for (NSDictionary *dict in imageDict) {
|
||||
if (launchImage) {
|
||||
return [UIImage imageNamed:launchImage];
|
||||
}
|
||||
|
||||
CGSize imageSize = CGSizeFromString(dict[@"UILaunchImageSize"]);
|
||||
if (CGSizeEqualToSize(imageSize, viewSize) && [viewOrienttation isEqualToString:dict[@"UILaunchImageOrientation"]]) {
|
||||
launchImage = dict[@"UILaunchImageName"];
|
||||
}
|
||||
}
|
||||
if (!launchImage) {
|
||||
// 取不到就直接取,6s的
|
||||
return [UIImage imageNamed:@"LaunchImage-800-667h"];
|
||||
}
|
||||
return [UIImage imageNamed:launchImage];
|
||||
}
|
||||
|
||||
@end
|
||||
158
QXLive/Tools/Category/UIView+QX.h
Normal file
158
QXLive/Tools/Category/UIView+QX.h
Normal file
@@ -0,0 +1,158 @@
|
||||
//
|
||||
// UIView+QX.h
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/4/27.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
typedef NS_ENUM(NSInteger , ShadowPathType) {
|
||||
ShadowPathTop = 1,
|
||||
ShadowPathBottom = 2,
|
||||
ShadowPathLeft = 3,
|
||||
ShadowPathRight = 4,
|
||||
ShadowPathCommon = 5,
|
||||
ShadowPathAround = 6,
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSUInteger, SRGradientDirection) {
|
||||
SRGradientDirectionTopToBottom, // 渐变色从上到下
|
||||
SRGradientDirectionLeftToRight, // 渐变色从左到右
|
||||
};
|
||||
@interface UIView (QX)
|
||||
/** 起点x坐标 */
|
||||
@property (nonatomic, assign) CGFloat x;
|
||||
/** 起点y坐标 */
|
||||
@property (nonatomic, assign) CGFloat y;
|
||||
/** 中心点x坐标 */
|
||||
@property (nonatomic, assign) CGFloat centerX;
|
||||
/** 中心点y坐标 */
|
||||
@property (nonatomic, assign) CGFloat centerY;
|
||||
/** 宽度 */
|
||||
@property (nonatomic, assign) CGFloat width;
|
||||
/** 高度 */
|
||||
@property (nonatomic, assign) CGFloat height;
|
||||
/** 顶部 */
|
||||
@property (nonatomic, assign) CGFloat top;
|
||||
/** 底部 */
|
||||
@property (nonatomic, assign) CGFloat bottom;
|
||||
/** 左边 */
|
||||
@property (nonatomic, assign) CGFloat left;
|
||||
/** 右边 */
|
||||
@property (nonatomic, assign) CGFloat right;
|
||||
/** size */
|
||||
@property (nonatomic, assign) CGSize size;
|
||||
/** origin */
|
||||
@property (nonatomic, assign) CGPoint origin;
|
||||
|
||||
/**
|
||||
快速给View添加4边阴影
|
||||
参数:阴影透明度,默认0
|
||||
*/
|
||||
- (void)addProjectionWithShadowOpacity:(CGFloat)shadowOpacity;
|
||||
/**
|
||||
快速给View添加4边阴影
|
||||
*/
|
||||
- (void)addShadowWithColor:(UIColor*)color radius:(CGFloat)radius;
|
||||
|
||||
- (void)addShadowWithColor:(UIColor*)color radius:(CGFloat)radius frame:(CGRect)frame;
|
||||
/**
|
||||
快速给View添加4边框
|
||||
参数:边框宽度
|
||||
*/
|
||||
- (void)addBorderWithWidth:(CGFloat)width;
|
||||
/**
|
||||
快速给View添加4边框
|
||||
width:边框宽度
|
||||
borderColor:边框颜色
|
||||
*/
|
||||
- (void)addBorderWithWidth:(CGFloat)width borderColor:(UIColor *)borderColor;
|
||||
/**
|
||||
快速给View添加圆角
|
||||
参数:圆角半径
|
||||
*/
|
||||
- (void)addRoundedCornersWithRadius:(CGFloat)radius;
|
||||
/**
|
||||
快速给View添加圆角
|
||||
radius:圆角半径
|
||||
corners:且那几个角
|
||||
类型共有以下几种:
|
||||
typedef NS_OPTIONS(NSUInteger, UIRectCorner) {
|
||||
UIRectCornerTopLeft,
|
||||
UIRectCornerTopRight ,
|
||||
UIRectCornerBottomLeft,
|
||||
UIRectCornerBottomRight,
|
||||
UIRectCornerAllCorners
|
||||
};
|
||||
使用案例:[self.mainView addRoundedCornersWithRadius:10 byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight]; // 切除了左下 右下
|
||||
*/
|
||||
- (void)addRoundedCornersWithRadius:(CGFloat)radius byRoundingCorners:(UIRectCorner)corners;
|
||||
|
||||
/************** 按自身Bounds计算 *************/
|
||||
|
||||
- (void)setTopToBottomGradientBackgroundWithColors:(NSArray<UIColor *> *_Nullable)colors;
|
||||
|
||||
- (void)setLeftToRightGradientBackgroundWithColors:(NSArray<UIColor *> *_Nullable)colors;
|
||||
|
||||
- (void)setGradientBackgroundWithColors:(NSArray<UIColor *> *_Nullable)colors startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint;
|
||||
|
||||
- (void)setLeftToRightGradientBackgroundWithColors:(NSArray<UIColor *> *_Nullable)colors roundedCorners:(CGFloat)radius;
|
||||
|
||||
- (void)setAroundRoundedCorners:(CGFloat)radius;
|
||||
|
||||
- (void)setTopRoundedCorners:(CGFloat)radius;
|
||||
|
||||
- (void)setBottomRoundedCorners:(CGFloat)radius;
|
||||
|
||||
- (void)setLeftRoundedCorners:(CGFloat)radius;
|
||||
|
||||
/************* 按Frame计算 *************/
|
||||
|
||||
/** 设置渐变色 */
|
||||
- (void)setViewBackgroundColorWithColorArray:(NSArray *)colorArray scaleArray:(NSArray * __nullable)scaleArray direction:(SRGradientDirection)direction;
|
||||
|
||||
/** 仅设置由上至下的渐变色 */
|
||||
- (void)setTopToBottomGradientBackgroundWithColors:(NSArray<UIColor *> *_Nullable)colors frame:(CGRect)frame;
|
||||
|
||||
/** 仅设置由左至右的渐变色 */
|
||||
- (void)setLeftToRightGradientBackgroundWithColors:(NSArray<UIColor *> *_Nullable)colors frame:(CGRect)frame;
|
||||
|
||||
/** 仅设置自定义起始和结束位置的渐变色 */
|
||||
- (void)setGradientBackgroundWithColors:(NSArray<UIColor *> *_Nullable)colors startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint frame:(CGRect)frame;
|
||||
|
||||
/** 设置由左至右的圆角渐变色 */
|
||||
- (void)setLeftToRightGradientBackgroundWithColors:(NSArray<UIColor *> *_Nullable)colors roundedCorners:(CGFloat)radius frame:(CGRect)frame;
|
||||
|
||||
/** 仅设置裁剪 */
|
||||
- (void)setAroundRoundedCorners:(CGFloat)radius frame:(CGRect)frame;
|
||||
|
||||
/** 仅设置顶部角裁剪 */
|
||||
- (void)setTopRoundedCorners:(CGFloat)radius frame:(CGRect)frame;
|
||||
|
||||
/** 仅设置底部角裁剪 */
|
||||
- (void)setBottomRoundedCorners:(CGFloat)radius frame:(CGRect)frame;
|
||||
|
||||
/** 仅设置左侧角裁剪 */
|
||||
- (void)setLeftRoundedCorners:(CGFloat)radius frame:(CGRect)frame;
|
||||
|
||||
/**
|
||||
给UIView添加阴影
|
||||
@param shadowColor 阴影颜色
|
||||
@param shadowOpacity 阴影透明度 默认0
|
||||
@param shadowRadius 阴影半径 也就是阴影放射程度 默认3
|
||||
@param shadowPathType 阴影方向
|
||||
@param shadowPathWidth 阴影放射g宽度
|
||||
*/
|
||||
- (void)setViewShadowPathWithColor:(UIColor *)shadowColor shadowOpacity:(CGFloat)shadowOpacity shadowRadius:(CGFloat)shadowRadius shadowPathType:(ShadowPathType)shadowPathType shadowPathWidth:(CGFloat)shadowPathWidth;
|
||||
|
||||
- (void)addTapBlock:(void(^)(id obj))tapAction;
|
||||
|
||||
- (UIViewController *)viewController;
|
||||
|
||||
- (UINavigationController *)navigationController;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
508
QXLive/Tools/Category/UIView+QX.m
Normal file
508
QXLive/Tools/Category/UIView+QX.m
Normal file
@@ -0,0 +1,508 @@
|
||||
//
|
||||
// UIView+QX.m
|
||||
// QXLive
|
||||
//
|
||||
// Created by 启星 on 2025/4/27.
|
||||
//
|
||||
|
||||
#import "UIView+QX.h"
|
||||
static const void* tagValue = &tagValue;
|
||||
@implementation UIView (QX)
|
||||
- (void)setX:(CGFloat)x {
|
||||
CGRect frame = self.frame;
|
||||
frame.origin.x = x;
|
||||
self.frame = frame;
|
||||
}
|
||||
|
||||
- (void)setY:(CGFloat)y {
|
||||
CGRect frame = self.frame;
|
||||
frame.origin.y = y;
|
||||
self.frame = frame;
|
||||
}
|
||||
|
||||
- (CGFloat)x {
|
||||
return self.frame.origin.x;
|
||||
}
|
||||
|
||||
- (CGFloat)y {
|
||||
return self.frame.origin.y;
|
||||
}
|
||||
|
||||
- (void)setCenterX:(CGFloat)centerX {
|
||||
|
||||
CGPoint center = self.center;
|
||||
center.x = centerX;
|
||||
self.center = center;
|
||||
|
||||
}
|
||||
|
||||
- (CGFloat)centerX {
|
||||
return self.center.x;
|
||||
}
|
||||
|
||||
- (void)setCenterY:(CGFloat)centerY{
|
||||
CGPoint center = self.center;
|
||||
center.y = centerY;
|
||||
self.center = center;
|
||||
}
|
||||
|
||||
- (CGFloat)centerY {
|
||||
return self.center.y;
|
||||
}
|
||||
|
||||
- (void)setWidth:(CGFloat)width {
|
||||
CGRect frame = self.frame;
|
||||
frame.size.width = width;
|
||||
self.frame = frame;
|
||||
}
|
||||
|
||||
- (void)setHeight:(CGFloat)height {
|
||||
CGRect frame = self.frame;
|
||||
frame.size.height = height;
|
||||
self.frame = frame;
|
||||
}
|
||||
|
||||
- (CGFloat)height {
|
||||
return self.frame.size.height;
|
||||
}
|
||||
|
||||
- (CGFloat)width {
|
||||
return self.frame.size.width;
|
||||
}
|
||||
|
||||
- (void)setSize:(CGSize)size {
|
||||
CGRect frame = self.frame;
|
||||
frame.size = size;
|
||||
self.frame = frame;
|
||||
}
|
||||
|
||||
- (CGSize)size {
|
||||
return self.frame.size;
|
||||
}
|
||||
|
||||
- (void)setOrigin:(CGPoint)origin {
|
||||
CGRect frame = self.frame;
|
||||
frame.origin = origin;
|
||||
self.frame = frame;
|
||||
}
|
||||
|
||||
- (CGPoint)origin {
|
||||
return self.frame.origin;
|
||||
}
|
||||
- (CGFloat)top {
|
||||
return self.frame.origin.y;
|
||||
}
|
||||
|
||||
- (void)setTop:(CGFloat)top {
|
||||
CGRect frame = self.frame;
|
||||
frame.origin.y = top;
|
||||
self.frame = frame;
|
||||
}
|
||||
|
||||
- (CGFloat)left {
|
||||
return self.frame.origin.x;
|
||||
}
|
||||
|
||||
- (void)setLeft:(CGFloat)left {
|
||||
CGRect frame = self.frame;
|
||||
frame.origin.x = left;
|
||||
self.frame = frame;
|
||||
}
|
||||
|
||||
|
||||
- (CGFloat)bottom {
|
||||
return self.frame.size.height + self.frame.origin.y;
|
||||
}
|
||||
|
||||
- (void)setBottom:(CGFloat)bottom {
|
||||
CGRect frame = self.frame;
|
||||
frame.origin.y = bottom - frame.size.height;
|
||||
self.frame = frame;
|
||||
}
|
||||
|
||||
- (CGFloat)right {
|
||||
return self.frame.size.width + self.frame.origin.x;
|
||||
}
|
||||
|
||||
- (void)setRight:(CGFloat)right {
|
||||
CGRect frame = self.frame;
|
||||
frame.origin.x = right - frame.size.width;
|
||||
self.frame = frame;
|
||||
}
|
||||
#pragma mark - 快速添加阴影
|
||||
- (void)addProjectionWithShadowOpacity:(CGFloat)shadowOpacity {
|
||||
self.layer.shadowColor = [UIColor blackColor].CGColor;//shadowColor阴影颜色
|
||||
self.layer.shadowOffset = CGSizeMake(0,0);//shadowOffset阴影偏移,x向右偏移2,y向下偏移6,默认(0, -3),这个跟shadowRadius配合使用
|
||||
self.layer.shadowOpacity = shadowOpacity;//阴影透明度,默认0
|
||||
self.layer.shadowRadius = 3;//阴影半径,默认3
|
||||
}
|
||||
- (void)addShadowWithColor:(UIColor*)color radius:(CGFloat)radius{
|
||||
CALayer *subLayer = [CALayer layer];
|
||||
subLayer.frame = self.frame;
|
||||
subLayer.cornerRadius = radius;
|
||||
subLayer.masksToBounds = NO;
|
||||
subLayer.backgroundColor = color.CGColor;
|
||||
subLayer.shadowColor = color.CGColor;//shadowColor阴影颜色
|
||||
subLayer.shadowOffset = CGSizeMake(0,2);
|
||||
subLayer.shadowOpacity = 0.5;//阴影透明度,默认0
|
||||
subLayer.shadowRadius = radius;//阴影半径,默认3
|
||||
[self.layer insertSublayer:subLayer below:self.layer];
|
||||
}
|
||||
- (void)addShadowWithColor:(UIColor*)color radius:(CGFloat)radius frame:(CGRect)frame{
|
||||
CALayer *subLayer = [CALayer layer];
|
||||
subLayer.frame = frame;
|
||||
subLayer.cornerRadius = radius;
|
||||
subLayer.masksToBounds = YES;
|
||||
subLayer.backgroundColor = color.CGColor;
|
||||
subLayer.shadowColor = color.CGColor;//shadowColor阴影颜色
|
||||
subLayer.shadowOffset = CGSizeMake(0,-3);
|
||||
subLayer.shadowOpacity = 0.5;//阴影透明度,默认0
|
||||
subLayer.shadowRadius = radius;//阴影半径,默认3
|
||||
[self.layer insertSublayer:subLayer below:self.layer];
|
||||
}
|
||||
- (void)addBorderWithWidth:(CGFloat)width {
|
||||
self.layer.borderWidth = width;
|
||||
self.layer.borderColor = [UIColor blackColor].CGColor;
|
||||
}
|
||||
- (void)addBorderWithWidth:(CGFloat)width borderColor:(UIColor *)borderColor {
|
||||
self.layer.borderWidth = width;
|
||||
self.layer.borderColor = borderColor.CGColor;
|
||||
}
|
||||
- (void)addRoundedCornersWithRadius:(CGFloat)radius {
|
||||
self.layer.cornerRadius = radius;
|
||||
self.layer.masksToBounds = YES;
|
||||
}
|
||||
- (void)addRoundedCornersWithRadius:(CGFloat)radius byRoundingCorners:(UIRectCorner)corners{
|
||||
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(radius, radius)];
|
||||
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
|
||||
maskLayer.frame = self.bounds;
|
||||
maskLayer.path = maskPath.CGPath;
|
||||
self.layer.mask = maskLayer;
|
||||
}
|
||||
|
||||
- (void)setTopToBottomGradientBackgroundWithColors:(NSArray<UIColor *> *)colors {
|
||||
|
||||
[self setGradientBackgroundWithColors:colors startPoint:CGPointMake(0.5, 0) endPoint:CGPointMake(0.5, 1)];
|
||||
}
|
||||
|
||||
- (void)setLeftToRightGradientBackgroundWithColors:(NSArray<UIColor *> *)colors {
|
||||
|
||||
[self setGradientBackgroundWithColors:colors startPoint:CGPointMake(0, 0.5) endPoint:CGPointMake(1, 0.5)];
|
||||
}
|
||||
|
||||
- (void)setGradientBackgroundWithColors:(NSArray<UIColor *> *)colors startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint {
|
||||
|
||||
NSMutableArray *colorsM = [NSMutableArray array];
|
||||
for (UIColor *color in colors) {
|
||||
[colorsM addObject:(__bridge id)color.CGColor];
|
||||
}
|
||||
|
||||
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
|
||||
gradientLayer.colors = colorsM;
|
||||
gradientLayer.locations = @[@0, @1];
|
||||
gradientLayer.startPoint = startPoint;
|
||||
gradientLayer.endPoint = endPoint;
|
||||
gradientLayer.frame = self.bounds;
|
||||
// [self.layer addSublayer:gradientLayer];
|
||||
|
||||
//layout中重复添加CAGradientLayer,需要清空多余的渐变层
|
||||
NSArray<CALayer *> *subLayers = self.layer.sublayers;
|
||||
NSArray<CALayer *> *removedLayers = [subLayers filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
|
||||
return [evaluatedObject isKindOfClass:[CAGradientLayer class]];
|
||||
}]];
|
||||
[removedLayers enumerateObjectsUsingBlock:^(CALayer * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
[obj removeFromSuperlayer];
|
||||
}];
|
||||
|
||||
[self.layer insertSublayer:gradientLayer atIndex:0];
|
||||
}
|
||||
|
||||
- (void)setLeftToRightGradientBackgroundWithColors:(NSArray<UIColor *> *)colors roundedCorners:(CGFloat)radius {
|
||||
|
||||
NSMutableArray *colorsM = [NSMutableArray array];
|
||||
for (UIColor *color in colors) {
|
||||
[colorsM addObject:(__bridge id)color.CGColor];
|
||||
}
|
||||
|
||||
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
|
||||
gradientLayer.colors = colorsM;
|
||||
gradientLayer.locations = @[@0, @1];
|
||||
gradientLayer.startPoint = CGPointMake(0, 0.5);
|
||||
gradientLayer.endPoint = CGPointMake(1, 0.5);
|
||||
gradientLayer.frame = self.bounds;
|
||||
gradientLayer.cornerRadius = radius;
|
||||
gradientLayer.masksToBounds = YES;
|
||||
|
||||
//layout中重复添加CAGradientLayer,需要清空多余的渐变层
|
||||
NSArray<CALayer *> *subLayers = self.layer.sublayers;
|
||||
NSArray<CALayer *> *removedLayers = [subLayers filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
|
||||
return [evaluatedObject isKindOfClass:[CAGradientLayer class]];
|
||||
}]];
|
||||
[removedLayers enumerateObjectsUsingBlock:^(CALayer * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
[obj removeFromSuperlayer];
|
||||
}];
|
||||
|
||||
[self.layer insertSublayer:gradientLayer atIndex:0];
|
||||
}
|
||||
|
||||
- (void)setAroundRoundedCorners:(CGFloat)radius {
|
||||
|
||||
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(radius, radius)];
|
||||
|
||||
CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init];
|
||||
maskLayer.frame = self.bounds;
|
||||
maskLayer.path = maskPath.CGPath;
|
||||
self.layer.mask = maskLayer;
|
||||
}
|
||||
|
||||
- (void)setTopRoundedCorners:(CGFloat)radius {
|
||||
|
||||
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(radius, radius)];
|
||||
|
||||
CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init];
|
||||
maskLayer.frame = self.bounds;
|
||||
maskLayer.path = maskPath.CGPath;
|
||||
self.layer.mask = maskLayer;
|
||||
}
|
||||
|
||||
- (void)setBottomRoundedCorners:(CGFloat)radius {
|
||||
|
||||
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight cornerRadii:CGSizeMake(radius, radius)];
|
||||
|
||||
CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init];
|
||||
maskLayer.frame = self.bounds;
|
||||
maskLayer.path = maskPath.CGPath;
|
||||
self.layer.mask = maskLayer;
|
||||
}
|
||||
|
||||
- (void)setLeftRoundedCorners:(CGFloat)radius {
|
||||
|
||||
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerBottomLeft cornerRadii:CGSizeMake(radius, radius)];
|
||||
|
||||
CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init];
|
||||
maskLayer.frame = self.bounds;
|
||||
maskLayer.path = maskPath.CGPath;
|
||||
self.layer.mask = maskLayer;
|
||||
}
|
||||
|
||||
#pragma mark - 按Frame计算
|
||||
|
||||
- (void)setTopToBottomGradientBackgroundWithColors:(NSArray<UIColor *> *)colors frame:(CGRect)frame {
|
||||
|
||||
[self setGradientBackgroundWithColors:colors startPoint:CGPointMake(0.5, 0) endPoint:CGPointMake(0.5, 1) frame:frame];
|
||||
}
|
||||
|
||||
- (void)setLeftToRightGradientBackgroundWithColors:(NSArray<UIColor *> *)colors frame:(CGRect)frame {
|
||||
|
||||
[self setGradientBackgroundWithColors:colors startPoint:CGPointMake(0, 0.5) endPoint:CGPointMake(1, 0.5) frame:frame];
|
||||
}
|
||||
|
||||
- (void)setGradientBackgroundWithColors:(NSArray<UIColor *> *)colors startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint frame:(CGRect)frame {
|
||||
|
||||
NSMutableArray *colorsM = [NSMutableArray array];
|
||||
for (UIColor *color in colors) {
|
||||
[colorsM addObject:(__bridge id)color.CGColor];
|
||||
}
|
||||
|
||||
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
|
||||
gradientLayer.colors = colorsM;
|
||||
gradientLayer.locations = @[@0, @1];
|
||||
gradientLayer.startPoint = startPoint;
|
||||
gradientLayer.endPoint = endPoint;
|
||||
gradientLayer.frame = frame;
|
||||
// [self.layer addSublayer:gradientLayer];
|
||||
|
||||
//layout中重复添加CAGradientLayer,需要清空多余的渐变层
|
||||
NSArray<CALayer *> *subLayers = self.layer.sublayers;
|
||||
NSArray<CALayer *> *removedLayers = [subLayers filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
|
||||
return [evaluatedObject isKindOfClass:[CAGradientLayer class]];
|
||||
}]];
|
||||
[removedLayers enumerateObjectsUsingBlock:^(CALayer * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
[obj removeFromSuperlayer];
|
||||
}];
|
||||
|
||||
[self.layer insertSublayer:gradientLayer atIndex:0];
|
||||
}
|
||||
|
||||
- (void)setLeftToRightGradientBackgroundWithColors:(NSArray<UIColor *> *)colors roundedCorners:(CGFloat)radius frame:(CGRect)frame {
|
||||
|
||||
NSMutableArray *colorsM = [NSMutableArray array];
|
||||
for (UIColor *color in colors) {
|
||||
[colorsM addObject:(__bridge id)color.CGColor];
|
||||
}
|
||||
|
||||
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
|
||||
gradientLayer.colors = colorsM;
|
||||
gradientLayer.locations = @[@0, @1];
|
||||
gradientLayer.startPoint = CGPointMake(0, 0.5);
|
||||
gradientLayer.endPoint = CGPointMake(1, 0.5);
|
||||
gradientLayer.frame = frame;
|
||||
gradientLayer.cornerRadius = radius;
|
||||
gradientLayer.masksToBounds = YES;
|
||||
|
||||
//layout中重复添加CAGradientLayer,需要清空多余的渐变层
|
||||
NSArray<CALayer *> *subLayers = self.layer.sublayers;
|
||||
NSArray<CALayer *> *removedLayers = [subLayers filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
|
||||
return [evaluatedObject isKindOfClass:[CAGradientLayer class]];
|
||||
}]];
|
||||
[removedLayers enumerateObjectsUsingBlock:^(CALayer * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
[obj removeFromSuperlayer];
|
||||
}];
|
||||
|
||||
[self.layer insertSublayer:gradientLayer atIndex:0];
|
||||
}
|
||||
|
||||
- (void)setAroundRoundedCorners:(CGFloat)radius frame:(CGRect)frame {
|
||||
|
||||
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:frame byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(radius, radius)];
|
||||
|
||||
CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init];
|
||||
maskLayer.frame = frame;
|
||||
maskLayer.path = maskPath.CGPath;
|
||||
self.layer.mask = maskLayer;
|
||||
}
|
||||
|
||||
- (void)setTopRoundedCorners:(CGFloat)radius frame:(CGRect)frame {
|
||||
|
||||
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:frame byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(radius, radius)];
|
||||
|
||||
CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init];
|
||||
maskLayer.frame = frame;
|
||||
maskLayer.path = maskPath.CGPath;
|
||||
self.layer.mask = maskLayer;
|
||||
}
|
||||
|
||||
- (void)setBottomRoundedCorners:(CGFloat)radius frame:(CGRect)frame {
|
||||
|
||||
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:frame byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight cornerRadii:CGSizeMake(radius, radius)];
|
||||
|
||||
CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init];
|
||||
maskLayer.frame = frame;
|
||||
maskLayer.path = maskPath.CGPath;
|
||||
self.layer.mask = maskLayer;
|
||||
}
|
||||
|
||||
- (void)setLeftRoundedCorners:(CGFloat)radius frame:(CGRect)frame {
|
||||
|
||||
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:frame byRoundingCorners:UIRectCornerTopLeft | UIRectCornerBottomLeft cornerRadii:CGSizeMake(radius, radius)];
|
||||
|
||||
CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init];
|
||||
maskLayer.frame = frame;
|
||||
maskLayer.path = maskPath.CGPath;
|
||||
self.layer.mask = maskLayer;
|
||||
}
|
||||
|
||||
- (void)setViewShadowPathWithColor:(UIColor *)shadowColor shadowOpacity:(CGFloat)shadowOpacity shadowRadius:(CGFloat)shadowRadius shadowPathType:(ShadowPathType)shadowPathType shadowPathWidth:(CGFloat)shadowPathWidth {
|
||||
|
||||
self.layer.masksToBounds = NO;//必须要等于NO否则会把阴影切割隐藏掉
|
||||
self.layer.shadowColor = shadowColor.CGColor;// 阴影颜色
|
||||
self.layer.shadowOpacity = shadowOpacity;// 阴影透明度,默认0
|
||||
self.layer.shadowOffset = CGSizeZero;//shadowOffset阴影偏移,默认(0, -3),这个跟shadowRadius配合使用
|
||||
self.layer.shadowRadius = shadowRadius;//阴影半径,默认3
|
||||
CGRect shadowRect = CGRectZero;
|
||||
CGFloat originX,originY,sizeWith,sizeHeight;
|
||||
originX = 0;
|
||||
originY = 0;
|
||||
sizeWith = self.bounds.size.width;
|
||||
sizeHeight = self.bounds.size.height;
|
||||
|
||||
if (shadowPathType == ShadowPathTop) {
|
||||
shadowRect = CGRectMake(originX, originY-shadowPathWidth/2, sizeWith, shadowPathWidth);
|
||||
}else if (shadowPathType == ShadowPathBottom){
|
||||
shadowRect = CGRectMake(originY, sizeHeight-shadowPathWidth/2, sizeWith, shadowPathWidth);
|
||||
}else if (shadowPathType == ShadowPathLeft){
|
||||
shadowRect = CGRectMake(originX-shadowPathWidth/2, originY, shadowPathWidth, sizeHeight);
|
||||
}else if (shadowPathType == ShadowPathRight){
|
||||
shadowRect = CGRectMake(sizeWith-shadowPathWidth/2, originY, shadowPathWidth, sizeHeight);
|
||||
}else if (shadowPathType == ShadowPathCommon){
|
||||
shadowRect = CGRectMake(originX-shadowPathWidth/2, 2, sizeWith+shadowPathWidth, sizeHeight+shadowPathWidth/2);
|
||||
}else if (shadowPathType == ShadowPathAround){
|
||||
shadowRect = CGRectMake(originX-shadowPathWidth/2, originY-shadowPathWidth/2, sizeWith+shadowPathWidth, sizeHeight+shadowPathWidth);
|
||||
}
|
||||
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRect:shadowRect];
|
||||
self.layer.shadowPath = bezierPath.CGPath;//阴影路径
|
||||
}
|
||||
|
||||
|
||||
- (void)setViewBackgroundColorWithColorArray:(NSArray *)colorArray scaleArray:(NSArray * __nullable)scaleArray direction:(SRGradientDirection)direction {
|
||||
/*
|
||||
layoutIfNeeded不一定会调用layoutSubviews方法。
|
||||
setNeedsLayout一定会调用layoutSubviews方法(有延迟,在下一轮runloop结束前)。
|
||||
如果想在当前runloop中立即刷新,调用顺序应该是:
|
||||
[self setNeedsLayout];
|
||||
[self layoutIfNeeded];
|
||||
*/
|
||||
[self setNeedsLayout];
|
||||
[self layoutIfNeeded];
|
||||
|
||||
CAGradientLayer *gradinentlayer = [CAGradientLayer layer];
|
||||
if (direction == SRGradientDirectionLeftToRight) {
|
||||
gradinentlayer.startPoint = CGPointMake(0, 0);
|
||||
gradinentlayer.endPoint = CGPointMake(1.0, 0);
|
||||
}else {
|
||||
gradinentlayer.startPoint = CGPointMake(0, 0);
|
||||
gradinentlayer.endPoint = CGPointMake(0, 1.0);
|
||||
}
|
||||
|
||||
NSMutableArray *CGColorArray = [NSMutableArray new];
|
||||
for (UIColor *color in colorArray) {
|
||||
[CGColorArray addObject:(__bridge id)color.CGColor];
|
||||
}
|
||||
if (!scaleArray) {
|
||||
|
||||
}else {
|
||||
gradinentlayer.locations = scaleArray;
|
||||
}
|
||||
gradinentlayer.colors = CGColorArray;
|
||||
gradinentlayer.frame = self.bounds;
|
||||
[self.layer addSublayer:gradinentlayer];
|
||||
|
||||
}
|
||||
- (void)tap{
|
||||
if (self.tapAction) {
|
||||
self.tapAction(self);
|
||||
}
|
||||
}
|
||||
- (void)addTapBlock:(void(^)(id obj))tapAction{
|
||||
self.tapAction = tapAction;
|
||||
if (![self gestureRecognizers]) {
|
||||
self.userInteractionEnabled = YES;
|
||||
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap)];
|
||||
[self addGestureRecognizer:tap];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)setTapAction:(void (^)(id))tapAction {
|
||||
objc_setAssociatedObject(self, tagValue, tapAction, OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||
}
|
||||
-(void (^)(id))tapAction {
|
||||
return objc_getAssociatedObject(self, tagValue);
|
||||
}
|
||||
|
||||
- (UIViewController *)viewController {
|
||||
|
||||
id nextResponder = [self nextResponder];
|
||||
while (nextResponder != nil) {
|
||||
if ([nextResponder isKindOfClass:[UIViewController class]]) {
|
||||
UIViewController *vc = (UIViewController *)nextResponder;
|
||||
return vc;
|
||||
}
|
||||
nextResponder = [nextResponder nextResponder];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (UINavigationController *)navigationController {
|
||||
|
||||
id nextResponder = [self nextResponder];
|
||||
while (nextResponder != nil) {
|
||||
if ([nextResponder isKindOfClass:[UINavigationController class]]) {
|
||||
UINavigationController *vc = (UINavigationController *)nextResponder;
|
||||
return vc;
|
||||
}
|
||||
nextResponder = [nextResponder nextResponder];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user