小说绘上架版本
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user