小说绘上架版本

This commit is contained in:
xtfei2011
2021-02-07 11:24:08 +08:00
commit ee5c1c8b12
1762 changed files with 115892 additions and 0 deletions
@@ -0,0 +1,25 @@
//
// TFColorHelper.h
// WXReader
//
// Created by 谢腾飞 on 2020/11/23.
// Copyright © 2020 xtfei_2011@126.com. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface TFColorHelper : NSObject
+ (UIColor *)getImageColorWithImage:(UIImage *)image atPixel:(CGPoint)point;
+ (UIColor *)getImageTopColorWithImage:(UIImage *)image;
+ (CGFloat)getColorWithContentOffsetY:(CGFloat)contentOffsetY;
+ (CGFloat)getAlphaWithContentOffsetY:(CGFloat)contentOffsetY;
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,95 @@
//
// TFColorHelper.m
// WXReader
//
// Created by 谢腾飞 on 2020/11/23.
// Copyright © 2020 xtfei_2011@126.com. All rights reserved.
//
#import "TFColorHelper.h"
@implementation TFColorHelper
+ (UIColor *)getImageTopColorWithImage:(UIImage *)image
{
return [[self class] getImageColorWithImage:image atPixel:CGPointMake(image.size.width / 2, 3)];
}
// 获取图片某一点的颜色
+ (UIColor *)getImageColorWithImage:(UIImage *)image atPixel:(CGPoint)point
{
if (!CGRectContainsPoint(CGRectMake(0.0f, 0.0f, image.size.width, image.size.height), point)) {
return nil;
}
NSInteger pointX = trunc(point.x);
NSInteger pointY = trunc(point.y);
CGImageRef cgImage = image.CGImage;
NSUInteger width = image.size.width;
NSUInteger height = image.size.height;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
int bytesPerPixel = 4;
int bytesPerRow = bytesPerPixel * 1;
NSUInteger bitsPerComponent = 8;
unsigned char pixelData[4] = {0, 0, 0, 0};
CGContextRef context = CGBitmapContextCreate(pixelData, 1, 1, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextSetBlendMode(context, kCGBlendModeCopy);
CGContextTranslateCTM(context, -pointX, pointY - (CGFloat)height);
CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, (CGFloat)width, (CGFloat)height), cgImage);
CGContextRelease(context);
CGFloat red = (CGFloat)pixelData[0] / 255.0f;
CGFloat green = (CGFloat)pixelData[1] / 255.0f;
CGFloat blue = (CGFloat)pixelData[2] / 255.0f;
CGFloat alpha = (CGFloat)pixelData[3] / 255.0f;
return [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
}
+ (CGFloat)getColorWithContentOffsetY:(CGFloat)contentOffsetY
{
CGFloat alpha = contentOffsetY;
CGFloat rbgColor = 0;
if (alpha > 100) {
alpha = 100;
} else if (alpha < 0) {
alpha = 0;
}
rbgColor = (255 - alpha * 2.55);
if (contentOffsetY >= 0 && contentOffsetY <= 100) {
return rbgColor;
} else if (contentOffsetY > 100) {
return 0;
} else if (contentOffsetY < 0) {
return 255;
} else {
return 0;
}
}
+ (CGFloat)getAlphaWithContentOffsetY:(CGFloat)contentOffsetY
{
CGFloat alpha = contentOffsetY;
if (alpha > 100) {
alpha = 100;
} else if (alpha < 0) {
alpha = 0;
}
if (contentOffsetY >= 0 && contentOffsetY <= 100) {
return alpha / 100;
} else if (contentOffsetY > 100) {
return 1;
} else if (contentOffsetY < 0) {
return 0;
} else {
return 1;
}
}
@end
@@ -0,0 +1,103 @@
//
// TFUtilsHelper.h
// WXReader
//
// Created by 谢腾飞 on 2020/11/21.
// Copyright © 2020 xtfei_2011@126.com. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "TFBasicViewController.h"
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSUInteger, TFSiteState) {
TFSiteStateBook = 1, // 小说
TFSiteStateComic = 2, // 漫画
TFSiteStateAudio = 3 // 有声
};
@interface TFUtilsHelper : NSObject
/**
设备信息
*/
+ (NSString *)getUDID;
+ (NSString *)getSystemVersion;
+ (NSString *)getCurrentDeviceModel;
// 获取文件大小
+ (long long)getFileSize:(NSString *)filePath;
// 获取在minNum ~ maxNum 之间的随机数
+ (NSUInteger)getArcRandomNumWithMinNum:(NSUInteger)minNum maxNum:(NSUInteger)maxNum;
+ (SEL _Nullable)createSetterWithPropertyName:(NSString *)name;
+ (void)synchronizationRack;
+ (void)synchronizationRackProductionWithProduction_id:(NSInteger)production_id productionType:(TFProductionType)productionType complete:(void(^ _Nullable)(BOOL status))complete;
// 审核日期
+ (BOOL)isInSafetyPeriod;
// 获取站点
+ (NSArray *)getSiteState;
// 是否使用Ai读书功能
+ (BOOL)getAiReadSwitchState;
+ (NSString *)convertFileSize:(long long)size;
+ (NSString *)getRemainingMemorySpace;
// 与当前的时间间隔
+ (NSInteger)getCurrentMinutesIntervalWithTimeStamp:(NSString *)timeStamp;
// 秒数转换成分钟
+ (NSString *)getMinuteTimeTransformationWithTotalTimeLenght:(NSInteger)totalTimeLength;
// 秒数转换成小时
+ (NSString *)getHourTimeTransformationWithTotalTimeLenght:(NSInteger)totalTimeLength;
// 获取时间戳
+ (NSString *)getTimeStamp;
+ (NSString *)currentDateString;
+ (NSString *)currentDateStringWithFormat:(NSString *)formatterStr;
/// 将指定时间戳转成“刚刚、昨天类似字样”
+ (NSString *)dateStringWithTimestamp:(NSString *)timestamp;
// 字符串格式化
+ (NSString *)formatStringWithObject:(id)object;
+ (NSString *)formatStringWithInteger:(NSUInteger)interger;
+ (NSString *)formatStringWithFloat:(float)floatValue;
+ (NSUInteger)formatIntegerValueWithString:(NSString *)kstring;
+ (NSString *)stringToMD5:(NSString *)inputStr;
// json格式化
+ (NSString *)jsonStringWithDictionary:(NSDictionary *)dictionary;
+ (NSString *)jsonStringWithObject:(id)object;
+ (NSString *)jsonStringWithArray:(NSArray *)array;
+ (NSString *)jsonStringWithString:(NSString *)string;
+ (NSDictionary *)dictionaryWithJsonString:(NSString *)jsonString;
/// 将Model转换为字典
+ (NSDictionary *)dicFromObject:(NSObject *)object;
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,595 @@
//
// TFUtilsHelper.m
// WXReader
//
// Created by 谢腾飞 on 2020/11/21.
// Copyright © 2020 xtfei_2011@126.com. All rights reserved.
//
#import "TFUtilsHelper.h"
#import "UUID.h"
#import <sys/utsname.h>
#import "CommonCrypto/CommonDigest.h"
#import "TFCollectionManager.h"
@implementation TFUtilsHelper
#pragma mark - 设备信息
+ (NSString *)getUDID
{
return [UUID getUUID];
}
+ (NSString *)getSystemVersion
{
return [[UIDevice currentDevice] systemVersion];
}
+ (NSString *)getCurrentDeviceModel
{
struct utsname systemInfo;
uname(&systemInfo);
return [NSString stringWithCString:systemInfo.machine encoding:NSASCIIStringEncoding];
}
+ (long long)getFileSize:(NSString *)filePath
{
long long ret = 0;
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
NSNumber *fileSizeNumber = [fileAttributes objectForKey:NSFileSize];
ret = [fileSizeNumber longLongValue];
return ret;
}
#pragma mark - 工具类
+ (SEL)createSetterWithPropertyName:(NSString *)name
{
if (!name || name.length == 0) return nil;
NSString *firstStirng = [name substringToIndex:1];
NSString *lastString = [name substringFromIndex:1];
name = [firstStirng.capitalizedString stringByAppendingString:lastString];
name = [NSString stringWithFormat:@"set%@:", name];
return NSSelectorFromString(name);
}
+ (void)synchronizationRack
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 同步小说
[self synchronizationRackProductionWithProduction_id:0 productionType:TFProductionTypeNovel complete:nil];
// 同步漫画
[self synchronizationRackProductionWithProduction_id:0 productionType:TFProductionTypeComic complete:nil];
// 同步有声
[self synchronizationRackProductionWithProduction_id:0 productionType:TFProductionTypeAudio complete:nil];
});
}
+ (void)synchronizationRackProductionWithProduction_id:(NSInteger)production_id productionType:(TFProductionType)productionType complete:(void(^ _Nullable)(BOOL status))complete
{
if (!TFUserInfoManager.isLogin) {
return;
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString *url = @"";
NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
switch (productionType) {
case TFProductionTypeAi:
case TFProductionTypeNovel:
url = Book_Add_Collect;
[parameters setObject:@"book_id" forKey:@"key"];
break;
case TFProductionTypeComic:
url = Comic_Collect_Add;
[parameters setObject:@"comic_id" forKey:@"key"];
break;
case TFProductionTypeAudio:
url = Audio_Collection_Add;
[parameters setObject:@"audio_id" forKey:@"key"];
break;
default:
break;
}
// 添加作品
if (production_id > 0) {
[parameters setObject:[TFUtilsHelper formatStringWithInteger:production_id] forKey:[parameters objectForKey:@"key"]];
// 同步作品
} else {
NSArray <TFProductionModel *> *t_arr = [[TFCollectionManager shareManagerWithProductionType:(productionType == TFProductionTypeAi ? TFProductionTypeNovel:productionType)] getAllCollection];
NSMutableArray *productionArray = [NSMutableArray array];
for (TFProductionModel *t_productionModel in t_arr) {
[productionArray addObject:[TFUtilsHelper formatStringWithInteger:t_productionModel.production_id]];
}
[parameters setObject:[productionArray componentsJoinedByString:@","] forKey:[parameters objectForKey:@"key"]];
[parameters setObject:@"1" forKey:@"auto_add"];
}
[TFNetworkTools POST:url parameters:parameters model:nil success:^(BOOL isSuccess, id _Nullable t_model, TFNetworkRequestModel * _Nonnull requestModel) {
!complete ?: complete(isSuccess);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
!complete ?: complete(NO);
}];
});
}
+ (BOOL)isInSafetyPeriod
{
#if TF_Enable_Magic
if ([TFSystemInfoManager.magicStatus isEqualToString:@"0"]) {
return NO;
} else if ([TFSystemInfoManager.magicStatus isEqualToString:@"1"]) {
return YES;
}
NSDateFormatter *date = [[NSDateFormatter alloc] init];
[date setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
// 后延天数
int delayDays = 15;
// 提交审核日期
NSDate *sd = [date dateFromString:Submission_Date];
// 预计审核成功日期
NSDate *ead = [[NSDate date] initWithTimeInterval:24 * 3600 * delayDays sinceDate:sd];
// 预计日期 - 当前日期
NSTimeInterval si = [ead timeIntervalSince1970] * 1;
NSTimeInterval ei = [[NSDate dateWithTimeIntervalSinceNow:0] timeIntervalSince1970];
NSTimeInterval value = si - ei;
// 天
int day = (int)value / (24 * 3600);
if (day > 0) { // 在审核期
return YES;
} else {// 非审核期
return NO;
}
#else
return NO;
#endif
}
static NSArray *siteStateArray;
+ (NSArray *)getSiteState
{
if (siteStateArray) {
return siteStateArray;
}
siteStateArray = @[
#if TF_Enable_Book
[NSNumber numberWithInt:TFSiteStateBook],
#endif
#if TF_Enable_Comic
[NSNumber numberWithInt:TFSiteStateComic],
#endif
#if TF_Enable_Audio
[NSNumber numberWithInt:TFSiteStateAudio]
#endif
];
id state = [[NSUserDefaults standardUserDefaults] objectForKey:TF_SITE_STATE];
if (!state) {
return siteStateArray;
}
// 兼容老版站点选择
if ([state isKindOfClass:[NSString class]]) {
if ([state integerValue] != 0) {
switch ([state integerValue]) {
case 1:
siteStateArray = @[[NSNumber numberWithInt:TFSiteStateBook]];
break;
case 2:
siteStateArray = @[[NSNumber numberWithInt:TFSiteStateComic]];
break;
case 3:
siteStateArray = @[[NSNumber numberWithInt:TFSiteStateBook], [NSNumber numberWithInt:TFSiteStateComic]];
break;
case 4:
siteStateArray = @[[NSNumber numberWithInt:TFSiteStateComic], [NSNumber numberWithInt:TFSiteStateBook]];
break;
default:
break;
}
}
}
// 新版站点选择
if ([state isKindOfClass:[NSArray class]]) {
NSMutableArray *t_siteArray = [NSMutableArray array];
NSArray *t_arr = (NSArray *)state;
for (NSString *siteString in t_arr) {
if ([[TFUtilsHelper formatStringWithObject:siteString] isEqualToString:@"1"]) {
[t_siteArray addObject:[NSNumber numberWithInt:TFSiteStateBook]];
}
if ([[TFUtilsHelper formatStringWithObject:siteString] isEqualToString:@"2"]) {
[t_siteArray addObject:[NSNumber numberWithInt:TFSiteStateComic]];
}
if ([[TFUtilsHelper formatStringWithObject:siteString] isEqualToString:@"3"]) {
[t_siteArray addObject:[NSNumber numberWithInt:TFSiteStateAudio]];
}
}
if (t_siteArray.count > 0) {
siteStateArray = t_siteArray;
}
}
return siteStateArray;
}
+ (BOOL)getAiReadSwitchState
{
#if TF_Enable_Ai
// 非简体中文、繁体中文不启用AI听书功能
if (TFLanguageManager.localizedLanguage != TFLanguageTypeSimplifiedChinese &&
TFLanguageManager.localizedLanguage != TFLanguageTypeTraditionalChinese) {
return NO;
}
if ([[NSUserDefaults standardUserDefaults] objectForKey:TF_Ai_Switch]) {
return [[[NSUserDefaults standardUserDefaults] objectForKey:TF_Ai_Switch] boolValue];
}
return YES;
#else
return NO;
#endif
}
+ (NSUInteger)getArcRandomNumWithMinNum:(NSUInteger)minNum maxNum:(NSUInteger)maxNum
{
return arc4random() % ((maxNum + 1) - minNum) + minNum;
}
// 与当前的时间间隔
+ (NSInteger)getCurrentMinutesIntervalWithTimeStamp:(NSString *)timeStamp
{
// 1.确定时间
NSString *startTime = timeStamp;
NSString *endTime = [self currentDateString];
if (timeStamp) {
NSDateFormatter *date = [[NSDateFormatter alloc] init];
[date setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSDate *startdate = [date dateFromString:startTime];
NSDate *enddate = [date dateFromString:endTime];
// 时间转时间戳的方法:
NSTimeInterval aTime = [enddate timeIntervalSinceDate:startdate];
return aTime / 60;
} else {
return -1;
}
}
// 秒数转换成小时
+ (NSString *)getHourTimeTransformationWithTotalTimeLenght:(NSInteger)totalTimeLength
{
NSInteger seconds = totalTimeLength;
return [NSString stringWithFormat:@"%@:%@:%@",[NSString stringWithFormat:@"%02zd",(NSInteger)(seconds / 3600)], [NSString stringWithFormat:@"%02zd",(NSInteger)((seconds % 3600) / 60)], [NSString stringWithFormat:@"%02zd",(NSInteger)(seconds % 60)]];
}
// 秒数转换成分钟
+ (NSString *)getMinuteTimeTransformationWithTotalTimeLenght:(NSInteger)totalTimeLength
{
NSInteger seconds = totalTimeLength;
return [NSString stringWithFormat:@"%@:%@", [NSString stringWithFormat:@"%02zd", (NSInteger)((seconds % 3600) / 60)], [NSString stringWithFormat:@"%02zd", (NSInteger)(seconds % 60)]];
}
+ (NSString *)getTimeStamp
{
NSDate *dat = [NSDate dateWithTimeIntervalSinceNow:0];
NSTimeInterval a = [dat timeIntervalSince1970];
NSString *timeString = [NSString stringWithFormat:@"%0.f", a];// 转为字符型
return timeString;
}
+ (NSString *)formatStringWithObject:(id)object
{
if ([object isKindOfClass:[NSString class]]) {
return object;
} else if (object) {
return [NSString stringWithFormat:@"%@", object];
} else {
return @"";
}
}
+ (NSString *)formatStringWithInteger:(NSUInteger)interger
{
return [NSString stringWithFormat:@"%"MZNSI, interger];
}
+ (NSString *)formatStringWithFloat:(float)floatValue
{
return [NSString stringWithFormat:@"%f", floatValue];
}
+ (NSUInteger)formatIntegerValueWithString:(NSString *)kstring
{
return [[NSString stringWithFormat:@"%@",kstring] integerValue];
}
+ (NSString *)stringToMD5:(NSString *)inputStr
{
const char *cStr = [inputStr UTF8String];
unsigned char result[CC_MD5_DIGEST_LENGTH];
CC_MD5(cStr,(CC_LONG)strlen(cStr), result);
NSString *resultStr = [NSString stringWithFormat:@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11],
result[12], result[13], result[14], result[15]
];
return [resultStr lowercaseString];
}
+ (NSDictionary *)dictionaryWithJsonString:(NSString *)jsonString
{
if (jsonString == nil) {
return nil;
}
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSError *err;
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
options:NSJSONReadingMutableContainers
error:&err];
if (err) {
return nil;
}
return dic;
}
+ (NSString *)jsonStringWithDictionary:(NSDictionary *)dictionary
{
if (!dictionary) {
return @"";
}
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonString;
if (!jsonData) {
} else {
jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
NSMutableString *mutStr = [NSMutableString stringWithString:jsonString];
NSRange range = {0,jsonString.length};
//去掉字符串中的空格
[mutStr replaceOccurrencesOfString:@" " withString:@"" options:NSLiteralSearch range:range];
NSRange range2 = {0,mutStr.length};
//去掉字符串中的换行符
[mutStr replaceOccurrencesOfString:@"\n" withString:@"" options:NSLiteralSearch range:range2];
return mutStr;
}
+ (NSString *)convertFileSize:(int64_t)size
{
if (size < 1024) { // B
return [NSString stringWithFormat:@"%lldB", size];
} else if (size >= 1024 && size < 1024 * 1024) { // KB
return [NSString stringWithFormat:@"%.2fKB", (double)size / 1024];
} else if(size >= 1024 * 1024 && size < 1024 * 1024 * 1024) { // MB
return [NSString stringWithFormat:@"%.2fMB", (double)size / (1024 * 1024)];
} else { // GB
return [NSString stringWithFormat:@"%.2fGB", (double)size / (1024 * 1024 * 1024)];
}
}
+ (NSString *)getRemainingMemorySpace
{
// 剩余大小
float freesize = 0.0;
NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] error:nil];
if (dictionary) {
NSNumber *_free = [dictionary objectForKey:NSFileSystemFreeSize];
freesize = [_free unsignedLongLongValue] * 1.0;
}
return [self convertFileSize:freesize];
}
+ (NSString *)jsonStringWithObject:(id)object
{
NSString *value = nil;
if (!object) {
return value;
}
if ([object isKindOfClass:[NSString class]]) {
value = [TFUtilsHelper jsonStringWithString:object];
}else if([object isKindOfClass:[NSDictionary class]]) {
value = [TFUtilsHelper jsonStringWithDictionary:object];
}else if([object isKindOfClass:[NSArray class]]) {
value = [TFUtilsHelper jsonStringWithArray:object];
}
return value;
}
+ (NSString *)jsonStringWithArray:(NSArray *)array
{
NSMutableString *reString = [NSMutableString string];
[reString appendString:@"["];
NSMutableArray *values = [NSMutableArray array];
for (id valueObj in array) {
NSString *value = [TFUtilsHelper jsonStringWithObject:valueObj];
if (value) {
[values addObject:[NSString stringWithFormat:@"%@",value]];
}
}
[reString appendFormat:@"%@",[values componentsJoinedByString:@","]];
[reString appendString:@"]"];
return reString;
}
+ (NSString *)jsonStringWithString:(NSString *)string
{
return [NSString stringWithFormat:@"\"%@\"",[[string stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"] stringByReplacingOccurrencesOfString:@"\""withString:@"\\\""]];
}
+ (NSString *)currentDateString
{
return [self currentDateStringWithFormat:@"yyyy-MM-dd HH:mm:ss"];
}
+ (NSString *)currentDateStringWithFormat:(NSString *)formatterStr
{
// 获取系统当前时间
NSDate *currentDate = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = formatterStr;
NSString *currentDateStr = [formatter stringFromDate:currentDate];
return currentDateStr;
}
+ (NSString *)dateStringWithTimestamp:(NSString *)timestamp
{
NSInteger currentTimestamp = [[self getTimeStamp] integerValue];
if ([self isSameDay:[timestamp integerValue] Time2:currentTimestamp]) {
// 小于60秒
if (currentTimestamp - [timestamp integerValue] < 60) {
return TFLocalizedString(@"刚刚");
}
// 小于60分钟
if (currentTimestamp - [timestamp integerValue] < 3600) {
NSInteger temp = (currentTimestamp - [timestamp integerValue]) / 60;
return [NSString stringWithFormat:@"%zd%@", temp, TFLocalizedString(@"分钟前")];
}
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"hh:mm"];
NSDate *date = [NSDate dateWithTimeIntervalSince1970:[timestamp integerValue]];
NSString *string = [dateFormat stringFromDate:date];
return [NSString stringWithFormat:@"%@ %@", TFLocalizedString(@"今天"), string];
} else {
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"yyyy-MM-dd hh:mm"];
NSDate *date = [NSDate dateWithTimeIntervalSince1970:[timestamp integerValue]];
NSString *string = [dateFormat stringFromDate:date];
return string;
}
}
// 判断2个时间戳是不是同一天
+ (BOOL)isSameDay:(NSInteger)iTime1 Time2:(NSInteger)iTime2
{
//传入时间毫秒数
NSDate *pDate1 = [NSDate dateWithTimeIntervalSince1970:iTime1];
NSDate *pDate2 = [NSDate dateWithTimeIntervalSince1970:iTime2];
NSCalendar* calendar = [NSCalendar currentCalendar];
unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
NSDateComponents* comp1 = [calendar components:unitFlags fromDate:pDate1];
NSDateComponents* comp2 = [calendar components:unitFlags fromDate:pDate2];
return [comp1 day] == [comp2 day] &&
[comp1 month] == [comp2 month] &&
[comp1 year] == [comp2 year];
}
+ (NSDictionary *)dicFromObject:(NSObject *)object
{
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
unsigned int count;
objc_property_t *propertyList = class_copyPropertyList([object class], &count);
for (int i = 0; i < count; i++) {
objc_property_t property = propertyList[i];
const char *cName = property_getName(property);
NSString *name = [NSString stringWithUTF8String:cName];
NSObject *value = [object valueForKey:name];//valueForKey返回的数字和字符串都是对象
if ([value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]]) {
//string , bool, int ,NSinteger
[dic setObject:value forKey:name];
} else if ([value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSDictionary class]]) {
//字典或字典
[dic setObject:[self arrayOrDicWithObject:(NSArray*)value] forKey:name];
} else if (value == nil) {
//null
//[dic setObject:[NSNull null] forKey:name];//这行可以注释掉?????
} else {
//model
[dic setObject:[self dicFromObject:value] forKey:name];
}
}
return [dic copy];
}
/// 将可能存在model数组转化为普通数组
+ (id)arrayOrDicWithObject:(id)origin
{
if ([origin isKindOfClass:[NSArray class]]) {
//数组
NSMutableArray *array = [NSMutableArray array];
for (NSObject *object in origin) {
if ([object isKindOfClass:[NSString class]] || [object isKindOfClass:[NSNumber class]]) {
//string , bool, int ,NSinteger
[array addObject:object];
} else if ([object isKindOfClass:[NSArray class]] || [object isKindOfClass:[NSDictionary class]]) {
//数组或字典
[array addObject:[self arrayOrDicWithObject:(NSArray *)object]];
} else {
//model
[array addObject:[self dicFromObject:object]];
}
}
return [array copy];
} else if ([origin isKindOfClass:[NSDictionary class]]) {
//字典
NSDictionary *originDic = (NSDictionary *)origin;
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
for (NSString *key in originDic.allKeys) {
id object = [originDic objectForKey:key];
if ([object isKindOfClass:[NSString class]] || [object isKindOfClass:[NSNumber class]]) {
//string , bool, int ,NSinteger
[dic setObject:object forKey:key];
} else if ([object isKindOfClass:[NSArray class]] || [object isKindOfClass:[NSDictionary class]]) {
//数组或字典
[dic setObject:[self arrayOrDicWithObject:object] forKey:key];
} else {
//model
[dic setObject:[self dicFromObject:object] forKey:key];
}
}
return [dic copy];
}
return [NSNull null];
}
@end
@@ -0,0 +1,87 @@
//
// TFViewHelper.h
// WXReader
//
// Created by 谢腾飞 on 2020/12/1.
// Copyright © 2020 xtfei_2011@126.com. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface TFViewHelper : NSObject
/**
* 上传图片处理
*/
+ (UIImage *)scaleImage:(UIImage *)image toScale:(float)scaleSize;
+ (NSString *)getBase64StringWithImageData:(NSData *)imageData;
+ (UIImage *)fixOrientation:(UIImage *)aImage;
+ (NSString *)imageExtensionWithFormatString:(NSString *)formatString;
+ (NSString *)audioExtensionWithFormatString:(NSString *)formatString;
+ (NSMutableAttributedString *)getSubContentWithOriginalContent:(NSMutableAttributedString *)originalContent labelWidth:(CGFloat)labelWidth labelMaxLine:(NSInteger)labelMaxLine;
+ (CGFloat)boundsWithFont:(UIFont *)font attributedText:(NSAttributedString *)attributedText needWidth:(CGFloat)needWidth lineSpacing:(CGFloat)lineSpacing;
/**
* 自适应frame
*/
// width
+ (CGFloat)getDynamicWidthWithLabel:(UILabel *)label;
+ (CGFloat)getDynamicWidthWithLabel:(UILabel *)label maxWidth:(CGFloat)maxWidth;
+ (CGFloat)getDynamicWidthWithLabelFont:(UIFont *)labelFont labelHeight:(CGFloat)labelHeight labelText:(NSString *)labelText;
+ (CGFloat)getDynamicWidthWithLabelFont:(UIFont *)labelFont labelHeight:(CGFloat)labelHeight labelText:(NSString *)labelText maxWidth:(CGFloat)maxWidth;
// height
+ (CGFloat)getDynamicHeightWithLabel:(UILabel *)label;
+ (CGFloat)getDynamicHeightWithLabel:(UILabel *)label maxHeight:(CGFloat)maxHeight;
+ (CGFloat)getDynamicHeightWithLabelFont:(UIFont *)labelFont labelWidth:(CGFloat)labelWidth labelText:(NSString *)labelText;
+ (CGFloat)getDynamicHeightWithLabelFont:(UIFont *)labelFont labelWidth:(CGFloat)labelWidth labelText:(NSString *)labelText maxHeight:(CGFloat)maxHeight;
#pragma mark - 特殊字体
// 添加删除线
+ (NSMutableAttributedString *)addPartionLineWithString:(NSString *)string range:(NSRange)range;
// 添加下划线
+ (NSMutableAttributedString *)addUnderLineWithString:(NSString *)string range:(NSRange)range;
// 添加字体变大
+ (NSMutableAttributedString *)resetFontWithFont:(UIFont *)font string:(NSString *)string range:(NSRange)range;
// 添加字体变色
+ (NSMutableAttributedString *)resetColorWithColor:(UIColor *)color string:(NSString *)string range:(NSRange)range;
// 字体加粗
+ (NSMutableAttributedString *)resetBoldFontWithString:(NSString *)string range:(NSRange)range;
/*
window
*/
+ (UIViewController *)getWindowRootController;
+ (UIViewController *)getCurrentViewController;
+ (UINavigationController * _Nullable)getCurrentNavigationController;
/*
view
*/
+ (void)setStateBarLightStyle;
+ (void)setStateBarDefaultStyle;
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,442 @@
//
// TFViewHelper.m
// WXReader
//
// Created by 谢腾飞 on 2020/12/1.
// Copyright © 2020 xtfei_2011@126.com. All rights reserved.
//
#import "TFViewHelper.h"
@implementation TFViewHelper
#pragma mark - 上传图片处理
+ (UIImage *)scaleImage:(UIImage *)image toScale:(float)scaleSize
{
UIGraphicsBeginImageContext(CGSizeMake(SCREEN_WIDTH, PUB_TABBAR_HEIGHT));
[image drawInRect:CGRectMake(0, 0, SCREEN_WIDTH, PUB_TABBAR_HEIGHT)];
UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return scaledImage;
}
+ (NSString *)getBase64StringWithImageData:(NSData *)imageData
{
return [self image2DataURL:[self imageWithImage:[self fixOrientation:[UIImage imageWithData:imageData]]]];
}
+ (UIImage *)fixOrientation:(UIImage *)aImage
{
if (aImage.imageOrientation == UIImageOrientationUp) return aImage;
CGAffineTransform transform = CGAffineTransformIdentity;
switch (aImage.imageOrientation) {
case UIImageOrientationDown:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);
transform = CGAffineTransformRotate(transform, M_PI);
break;
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
transform = CGAffineTransformRotate(transform, M_PI_2);
break;
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);
transform = CGAffineTransformRotate(transform, -M_PI_2);
break;
default:
break;
}
switch (aImage.imageOrientation) {
case UIImageOrientationUpMirrored:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
case UIImageOrientationLeftMirrored:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
default:
break;
}
CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height, CGImageGetBitsPerComponent(aImage.CGImage), 0, CGImageGetColorSpace(aImage.CGImage), CGImageGetBitmapInfo(aImage.CGImage));
CGContextConcatCTM(ctx, transform);
switch (aImage.imageOrientation) {
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage);
break;
default:
CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);
break;
}
CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
UIImage *img = [UIImage imageWithCGImage:cgimg];
CGContextRelease(ctx);
CGImageRelease(cgimg);
return img;
}
+ (UIImage *)imageWithImage:(UIImage *)image
{
UIGraphicsBeginImageContext(CGSizeMake(image.size.width, image.size.height));
[image drawInRect:CGRectMake(0,0,image.size.width,image.size.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
+ (NSString *)image2DataURL: (UIImage *) image
{
NSData *imageData = nil;
NSString *mimeType = nil;
imageData = UIImageJPEGRepresentation(image, 0.7f);
mimeType = @"image/jpeg";
return [NSString stringWithFormat:@"data:%@;base64,%@", mimeType, [imageData base64EncodedStringWithOptions: 0]];
}
+ (NSMutableAttributedString *)getSubContentWithOriginalContent:(NSMutableAttributedString *)originalContent labelWidth:(CGFloat)labelWidth labelMaxLine:(NSInteger)labelMaxLine
{
if (originalContent.length == 0 || labelWidth == 0 || labelMaxLine == 0) {
return nil;
}
// 计算总字符长度
CGFloat totalStringLength = 0;
for (int i = 0; i < [originalContent length]; i ++) {
// 找出每个字符
NSAttributedString *characterString = [originalContent attributedSubstringFromRange:NSMakeRange(i, 1)];
// 处理换行符
if ([characterString.string isEqualToString:@"\n"]) {
// 换行符再当前行的位置(类似于取余)
CGFloat currentDistanceToTop = totalStringLength - (int)(totalStringLength / labelWidth) * labelWidth;
// 换行符到末尾的距离
CGFloat distanceToEnd = labelWidth - currentDistanceToTop;
totalStringLength = totalStringLength + distanceToEnd;
} else {
// 计算字符宽度
CGFloat characterWidth = [characterString boundingRectWithSize:CGSizeMake(MAXFLOAT, 0.0) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingTruncatesLastVisibleLine context:nil].size.width;
totalStringLength = totalStringLength + characterWidth;
}
}
// 计算总字符有几行
NSInteger characterTotalLine = (int)(totalStringLength / labelWidth);
// 计算总字符最后一行宽度
CGFloat endLineWidth = totalStringLength / labelWidth - characterTotalLine;
// 是否需要截取
BOOL needSeparated = NO;
// 最后一行宽度大于限宽一半
if (endLineWidth > 0.5) {
needSeparated = YES;
}
// 总字符行数大于限制行数
if (characterTotalLine > labelMaxLine) {
needSeparated = YES;
characterTotalLine = labelMaxLine;
}
// 进行截取
if (needSeparated) {
CGFloat finalCharacterLength = 0;
for (int i = 0; i < [originalContent length]; i ++) {
NSAttributedString *characterString = [originalContent attributedSubstringFromRange:NSMakeRange(i, 1)];
if ([characterString.string isEqualToString:@"\n"]) {
// 换行符再当前行的位置(类似于取余)
CGFloat currentDistanceToTop = finalCharacterLength - (int)(finalCharacterLength / labelWidth) * labelWidth;
// 换行符到末尾的距离
CGFloat distanceToEnd = labelWidth - currentDistanceToTop;
finalCharacterLength = finalCharacterLength + distanceToEnd;
} else {
// 计算字符宽度
CGFloat characterWidth = [characterString boundingRectWithSize:CGSizeMake(MAXFLOAT, 0.0) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingTruncatesLastVisibleLine context:nil].size.width;
finalCharacterLength = finalCharacterLength + characterWidth;
}
//此处截取maxLength,根据需求设置
if (finalCharacterLength >= labelWidth * (characterTotalLine + 0.5)) {
NSMutableAttributedString *resultString = [[NSMutableAttributedString alloc] initWithAttributedString:[originalContent attributedSubstringFromRange:NSMakeRange(0, i)]];
[resultString appendAttributedString:[[NSAttributedString alloc] initWithString:@"..."]];
return resultString;
}
}
}
// 换行符再当前行的位置(类似于取余)
CGFloat currentDistanceToTop = totalStringLength - (int)(totalStringLength / labelWidth) * labelWidth;
// 如果当前行总字符长度不足一字符长度,则处理当前行的上一行内容
if (currentDistanceToTop < 15) {
if (characterTotalLine == 1) {
[originalContent replaceCharactersInRange:NSMakeRange(originalContent.length / 2, originalContent.length - NSMakeRange(0, originalContent.length / 2).length) withString:@"..."];
} else {
return [self getSubContentWithOriginalContent:originalContent labelWidth:labelWidth labelMaxLine:labelMaxLine - 1];
}
}
return originalContent;
}
+ (CGFloat)boundsWithFont:(UIFont *)font attributedText:(NSAttributedString *)attributedText needWidth:(CGFloat)needWidth lineSpacing:(CGFloat)lineSpacing
{
NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithAttributedString:attributedText];
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
style.lineSpacing = lineSpacing;
[attributeString addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0, attributedText.length)];
[attributeString addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, attributedText.length)];
NSStringDrawingOptions options = NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingTruncatesLastVisibleLine;
CGRect rect = [attributeString boundingRectWithSize:CGSizeMake(needWidth, CGFLOAT_MAX) options:options context:nil];
return rect.size.height;
}
+ (NSString *)imageExtensionWithFormatString:(NSString *)formatString
{
if ([formatString isEqualToString:@"image/jpeg"]) {
return @"jpeg";
}
if ([formatString isEqualToString:@"image/png"]) {
return @"png";
}
if ([formatString isEqualToString:@"image/gif"]) {
return @"gif";
}
if ([formatString isEqualToString:@"image/tiff"]) {
return @"tiff";
}
if ([formatString isEqualToString:@"image/webp"]) {
return @"webp";
}
return @"";
}
+ (NSString *)audioExtensionWithFormatString:(NSString *)formatString
{
if ([formatString isEqualToString:@"audio/mpeg"] || [formatString isEqualToString:@"audio/x-mpeg-3"] || [formatString isEqualToString:@"audio/mpeg3"]) {
return @"mp3";
}
if ([formatString isEqualToString:@"audio/wav"]) {
return @"wav";
}
if ([formatString isEqualToString:@"audio/x-ma-wma"]) {
return @"wma";
}
return @"";
}
#pragma mark - 自适应frame
// width
+ (CGFloat)getDynamicWidthWithLabel:(UILabel *)label
{
return [self getDynamicWidthWithLabelFont:label.font labelHeight:label.bounds.size.height labelText:label.text maxWidth:MAXFLOAT];
}
+ (CGFloat)getDynamicWidthWithLabel:(UILabel *)label maxWidth:(CGFloat)maxWidth
{
return [self getDynamicWidthWithLabelFont:label.font labelHeight:label.bounds.size.height labelText:label.text maxWidth:maxWidth];
}
+ (CGFloat)getDynamicWidthWithLabelFont:(UIFont *)labelFont labelHeight:(CGFloat)labelHeight labelText:(NSString *)labelText
{
return [self getDynamicWidthWithLabelFont:labelFont labelHeight:labelHeight labelText:labelText maxWidth:MAXFLOAT];
}
+ (CGFloat)getDynamicWidthWithLabelFont:(UIFont *)labelFont labelHeight:(CGFloat)labelHeight labelText:(NSString *)labelText maxWidth:(CGFloat)maxWidth
{
CGSize retSize = [self getDynamicSizeWithLabelFont:labelFont labelText:labelText rectWidth:maxWidth rectHeight:labelHeight];
if (retSize.width + kMargin > maxWidth) {
return maxWidth;
}
return retSize.width + 5;
}
// height
+ (CGFloat)getDynamicHeightWithLabel:(UILabel *)label
{
return [self getDynamicHeightWithLabelFont:label.font labelWidth:label.bounds.size.width labelText:label.text maxHeight:MAXFLOAT];
}
+ (CGFloat)getDynamicHeightWithLabel:(UILabel *)label maxHeight:(CGFloat)maxHeight
{
return [self getDynamicHeightWithLabelFont:label.font labelWidth:label.bounds.size.width labelText:label.text maxHeight:maxHeight];
}
+ (CGFloat)getDynamicHeightWithLabelFont:(UIFont *)labelFont labelWidth:(CGFloat)labelWidth labelText:(NSString *)labelText
{
return [self getDynamicHeightWithLabelFont:labelFont labelWidth:labelWidth labelText:labelText maxHeight:MAXFLOAT];
}
+ (CGFloat)getDynamicHeightWithLabelFont:(UIFont *)labelFont labelWidth:(CGFloat)labelWidth labelText:(NSString *)labelText maxHeight:(CGFloat)maxHeight
{
CGSize retSize = [self getDynamicSizeWithLabelFont:labelFont labelText:labelText rectWidth:labelWidth rectHeight:maxHeight];
if (retSize.height + kMargin > maxHeight) {
return maxHeight;
}
return retSize.height + kMargin;
}
+ (CGSize)getDynamicSizeWithLabelFont:(UIFont *)labelFont labelText:(NSString *)labelText rectWidth:(CGFloat)rectWidth rectHeight:(CGFloat)rectHeight
{
NSDictionary *attribute = @{NSFontAttributeName:labelFont};
CGSize retSize = [labelText boundingRectWithSize:CGSizeMake(rectWidth, rectHeight) options:NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:attribute context:nil].size;
return retSize;
}
#pragma mark - window
+ (UIViewController *)getWindowRootController
{
UIViewController *rootController = kMainWindow.rootViewController;
while (rootController.presentedViewController) {
rootController = rootController.presentedViewController;
}
return rootController;
}
+ (UIViewController *)getCurrentViewController
{
UIViewController * __block result = nil;
kCodeSync({
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
if (window.windowLevel != UIWindowLevelNormal) {
NSArray *windows = [[UIApplication sharedApplication] windows];
for(UIWindow *tmpWin in windows) {
if (tmpWin.windowLevel == UIWindowLevelNormal) {
window = tmpWin;
break;
}
}
}
result = window.rootViewController;
while (result.presentedViewController) {
result = result.presentedViewController;
}
if ([result isKindOfClass:[UITabBarController class]]) {
result = [(UITabBarController *)result selectedViewController];
}
if ([result isKindOfClass:[UINavigationController class]]) {
result = [(UINavigationController *)result visibleViewController];
}
});
return result;
}
+ (UINavigationController *)getCurrentNavigationController
{
UIWindow *window = __IPHONE_13_0 ? [UIApplication sharedApplication].windows.firstObject : [UIApplication sharedApplication].keyWindow;
id rootViewController = window.rootViewController;
if ([rootViewController isKindOfClass:UINavigationController.class]) {
return (UINavigationController *)rootViewController;
} else if ([rootViewController isKindOfClass:UITabBarController.class]) {
UITabBarController *tabBarController = rootViewController;
if (![tabBarController.selectedViewController isKindOfClass:UINavigationController.class]) return nil;
return tabBarController.selectedViewController;
}
return nil;
}
+ (void)setStateBarLightStyle
{
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
}
+ (void)setStateBarDefaultStyle
{
if (@available(iOS 13.0, *)) {
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDarkContent;
} else {
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault;
}
}
#pragma mark - 特殊字体
// 删除线
+ (NSMutableAttributedString *)addPartionLineWithString:(NSString *)string range:(NSRange)range
{
NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:string];
[attributedStr addAttribute:NSStrikethroughStyleAttributeName value:@(NSUnderlineStyleSingle) range:range];
return attributedStr;
}
// 下划线
+ (NSMutableAttributedString *)addUnderLineWithString:(NSString *)string range:(NSRange)range
{
NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:string];
[attributedStr addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:range];
return attributedStr;
}
// 字体变大
+ (NSMutableAttributedString *)resetFontWithFont:(UIFont *)font string:(NSString *)string range:(NSRange)range
{
NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:string];
[attributedStr addAttribute:NSFontAttributeName value:font range:range];
return attributedStr;
}
// 字体变色
+ (NSMutableAttributedString *)resetColorWithColor:(UIColor *)color string:(NSString *)string range:(NSRange)range
{
NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:string];
[attributedStr addAttribute:NSForegroundColorAttributeName value:color range:range];
return attributedStr;
}
// 字体加粗
+ (NSMutableAttributedString *)resetBoldFontWithString:(NSString *)string range:(NSRange)range
{
NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:string];
[attributedStr addAttribute:NSExpansionAttributeName value:[NSNumber numberWithInt:1] range:range];
return attributedStr;
}
@end