├── Sagit ├── STModel │ ├── Common │ │ ├── STLocationModel.m │ │ ├── STLocationModel.h │ │ ├── STHttpModel.h │ │ ├── STLayoutTracer.h │ │ ├── STHttpModel.m │ │ ├── STEnum.h │ │ └── STLayoutTracer.m │ ├── STModelBase.h │ └── STModelBase.m ├── STBase │ ├── STNavController.h │ ├── STTabController.h │ ├── STView.h │ ├── STNavController.m │ ├── STView.m │ ├── STController.h │ └── STTabController.m ├── STTool │ ├── Tool │ │ ├── CropImage │ │ │ ├── CropImageView.h │ │ │ ├── CropPanGestureRecognizer.h │ │ │ ├── CropClipAreaLayer.h │ │ │ ├── CropPanGestureRecognizer.m │ │ │ └── CropClipAreaLayer.m │ │ ├── Reachability.h │ │ ├── LocationConverter.h │ │ └── LocationConverter.m │ ├── Common │ │ ├── STCache.h │ │ ├── STLocation.h │ │ ├── STFile.h │ │ ├── STHttp.h │ │ ├── STMsgBox.h │ │ ├── STCache.m │ │ └── STFile.m │ ├── STSagit.h │ └── STSagit.m ├── Category │ ├── Object │ │ ├── STNumber.h │ │ ├── STNumber.m │ │ ├── STArray.h │ │ ├── STColor.h │ │ ├── STUserDefaults.h │ │ ├── STFont.h │ │ ├── STStack.h │ │ ├── STQueue.h │ │ ├── STNSMutableDictionary.h │ │ ├── STStack.m │ │ ├── STQueue.m │ │ ├── STDictionary.h │ │ ├── STNSMapTable.h │ │ ├── STUserDefaults.m │ │ ├── STArray.m │ │ ├── STFont.m │ │ ├── STDate.h │ │ ├── STString.h │ │ ├── STColor.m │ │ ├── STNSMapTable.m │ │ ├── STNSMutableDictionary.m │ │ ├── STDictionary.m │ │ ├── STDate.m │ │ └── STString.m │ ├── UI │ │ ├── STUIWindow.h │ │ ├── STUILabel.h │ │ ├── STUIViewAs.h │ │ ├── STUIImage.h │ │ ├── STUICollectionView.h │ │ ├── STUISwitch.h │ │ ├── STUICollectionViewCell.h │ │ ├── STUIPageControl.h │ │ ├── STUIControl.h │ │ ├── STUINavigationBar.h │ │ ├── STUICollectionView.m │ │ ├── STUITextField.h │ │ ├── STUITextView.h │ │ ├── STUISwitch.m │ │ ├── STUIButton.h │ │ ├── STUITableViewCellAction.h │ │ ├── STUITableViewCell.h │ │ ├── STUIScrollView.h │ │ ├── STUITableViewCellAction.m │ │ ├── STUIViewValue.h │ │ ├── STUIViewAs.m │ │ ├── STUICollectionViewCell.m │ │ ├── STUINavigationBar.m │ │ ├── STUIView.h │ │ ├── STUITableView.h │ │ ├── STUIImageView.h │ │ ├── STUIControl.m │ │ ├── STUIPageControl.m │ │ ├── STUIViewAutoLayout.h │ │ ├── STUILabel.m │ │ ├── STUIViewAddUI.h │ │ ├── STUIImage.m │ │ ├── STUIWindow.m │ │ ├── STUITextField.m │ │ ├── STUIButton.m │ │ ├── STUITableView.m │ │ ├── STUIViewEvent.h │ │ └── STUITextView.m │ ├── STCategory.h │ └── Controller │ │ └── STUIViewController.h ├── Define │ ├── STDefineFunc.h │ ├── STDefine.h │ └── STDefine.m └── Sagit.h └── .gitignore /Sagit/STModel/Common/STLocationModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // STCityModel.m 3 | // 4 | // Created by 陈裕强 on 2020/8/21. 5 | // 6 | 7 | #import "STLocationModel.h" 8 | 9 | @implementation STLocationModel 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /Sagit/STBase/STNavController.h: -------------------------------------------------------------------------------- 1 | // 2 | // STNavController.h 3 | // 4 | // Created by 陈裕强 on 2020/9/12. 5 | // 6 | 7 | #import 8 | 9 | 10 | 11 | @interface STNavController : UINavigationController 12 | 13 | @end 14 | 15 | -------------------------------------------------------------------------------- /Sagit/STTool/Tool/CropImage/CropImageView.h: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | #import "STView.h" 4 | @interface CropImageView : STView 5 | -(CropImageView*)setPara:(UIImage*)image scaleSize:(CGSize)scaleSize editScaleSize:(BOOL)editScaleSize; 6 | - (UIImage*)cropImage; 7 | @end 8 | -------------------------------------------------------------------------------- /Sagit/Category/Object/STNumber.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // Copyright © 2017-2027年. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface NSNumber(ST) 11 | -(NSString*)toString; 12 | @end 13 | 14 | -------------------------------------------------------------------------------- /Sagit/STTool/Tool/CropImage/CropPanGestureRecognizer.h: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | 4 | @interface CropPanGestureRecognizer : UIPanGestureRecognizer 5 | 6 | @property(assign, nonatomic) CGPoint beginPoint; 7 | @property(assign, nonatomic) CGPoint movePoint; 8 | 9 | -(instancetype)initWithTarget:(id)target action:(SEL)action inview:(UIView*)view; 10 | 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Sagit/Category/Object/STNumber.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // Copyright © 2017-2027年. All rights reserved. 6 | // 7 | 8 | #import "STNumber.h" 9 | 10 | @implementation NSNumber(ST) 11 | -(NSString*)toString 12 | { 13 | return [self stringValue]; 14 | } 15 | @end 16 | 17 | -------------------------------------------------------------------------------- /Sagit/Category/Object/STArray.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // Copyright © 2017-2027年. All rights reserved. 6 | // 7 | 8 | #import "STController.h" 9 | 10 | @interface NSArray(ST) 11 | -(NSMutableArray*)toNSMutableArray; 12 | -(NSString*)toJson; 13 | @end 14 | 15 | @interface NSMutableArray(ST) 16 | -(NSString*)toJson; 17 | @end 18 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUIWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // STUIWindow.h 3 | // IT恋 4 | // 5 | // Created by 陈裕强 on 2018/1/24. 6 | // Copyright © 2018年 . All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIWindow (ST) 12 | -(instancetype)initWithBackgoundColor:(id)colorOrHex; 13 | //当前编辑的文本框 14 | @property (nonatomic,retain) UIView *editingTextUI; 15 | @property (nonatomic,assign) CGFloat keyboardHeight; 16 | +(id)mainWindow; 17 | @end 18 | 19 | -------------------------------------------------------------------------------- /Sagit/Category/Object/STColor.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // Copyright © 2017-2027年. All rights reserved. 6 | // 7 | 8 | #import 9 | #import 10 | 11 | @interface UIColor(ST) 12 | + (UIColor *)hex:(NSString *)hexColor; 13 | +(UIColor *)toColor:(id)hexOrColor; 14 | -(UIColor*)alpha:(CGFloat)value; 15 | @end 16 | -------------------------------------------------------------------------------- /Sagit/Category/Object/STUserDefaults.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // Copyright © 2017-2027年. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | 11 | @interface NSUserDefaults(ST) 12 | -(void)set:(NSString*)key value:(NSString*)value; 13 | -(NSString*)get:(NSString*)key; 14 | -(BOOL)has:(NSString*)key; 15 | -(void)remove:(NSString *)key; 16 | @end 17 | -------------------------------------------------------------------------------- /Sagit/STModel/Common/STLocationModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // STCityModel.h 3 | // 4 | // Created by 陈裕强 on 2020/8/21. 5 | // 6 | 7 | #import 8 | #import "STModelBase.h" 9 | @interface STLocationModel : STModelBase 10 | //!城市 11 | @property (nonatomic,copy) NSString *City; 12 | //!完整地址 13 | @property (nonatomic,copy) NSString *GPSAddress; 14 | //!经度 15 | @property (nonatomic,copy) NSString *Longitude; 16 | //!纬度 17 | @property (nonatomic,copy) NSString *Latitude; 18 | 19 | @end 20 | 21 | -------------------------------------------------------------------------------- /Sagit/STBase/STTabController.h: -------------------------------------------------------------------------------- 1 | // 2 | // STTabController.h 3 | // 4 | // Created by 陈裕强 on 2017/12/24. 5 | // Copyright © 2017年. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface STTabController : UITabBarController 11 | //!事件在UI初始化之前执行 12 | -(void)onInit; 13 | //!UI初始化 14 | -(void)initUI; 15 | //!事件在UI初始化之后执行 16 | -(void)initData; 17 | 18 | #pragma mark 系统的2个事件方法 19 | //呈现UI之前【执行N次】 20 | -(void)beforeViewAppear; 21 | //UI消失之前【执行N次】 22 | -(void)beforeViewDisappear; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Sagit/Category/Object/STFont.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // Copyright © 2017-2027年. All rights reserved. 6 | // 7 | 8 | #import 9 | #import 10 | 11 | 12 | @interface UIFont(ST) 13 | //小数位.0代表加粗。 14 | +(UIFont *)toFont:(CGFloat)px; 15 | +(UIFont *)toFont:(NSInteger)px name:(NSString*)name; 16 | +(UIFont *)toFont:(NSInteger)px bold:(BOOL)bold; 17 | @end 18 | 19 | 20 | -------------------------------------------------------------------------------- /Sagit/STTool/Tool/CropImage/CropClipAreaLayer.h: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | 4 | @interface CropClipAreaLayer : CAShapeLayer 5 | 6 | @property(assign, nonatomic) NSInteger cropAreaLeft; 7 | @property(assign, nonatomic) NSInteger cropAreaTop; 8 | @property(assign, nonatomic) NSInteger cropAreaRight; 9 | @property(assign, nonatomic) NSInteger cropAreaBottom; 10 | 11 | - (void)setCropAreaLeft:(NSInteger)cropAreaLeft CropAreaTop:(NSInteger)cropAreaTop CropAreaRight:(NSInteger)cropAreaRight CropAreaBottom:(NSInteger)cropAreaBottom; 12 | 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Sagit/Category/Object/STStack.h: -------------------------------------------------------------------------------- 1 | // 2 | // 自定义栈:先进后出。 3 | // 4 | // 开源:https://github.com/cyq1162/Sagit 5 | // 作者:陈裕强 create on 2017/12/12. 6 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 7 | // Copyright © 2017-2027年. All rights reserved. 8 | // 9 | 10 | #import 11 | 12 | @interface STStack:NSObject 13 | -(instancetype)init; 14 | @property (readonly) NSUInteger count; 15 | //!移除并返回位于 STStack 顶处的对象。 16 | -(ObjectType)pop; 17 | //!返回位于 STStack 顶处的对象但不将其移除。 18 | -(ObjectType)peek; 19 | //!将对象添加到 STStack 的顶处 20 | - (void)push:(ObjectType)anObject; 21 | 22 | @end 23 | 24 | -------------------------------------------------------------------------------- /Sagit/Category/Object/STQueue.h: -------------------------------------------------------------------------------- 1 | // 2 | // 自定义队列:先进先出。 3 | // 4 | // 开源:https://github.com/cyq1162/Sagit 5 | // 作者:陈裕强 create on 2017/12/12. 6 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 7 | // Copyright © 2017-2027年. All rights reserved. 8 | // 9 | 10 | #import 11 | 12 | @interface STQueue :NSObject 13 | -(instancetype)init; 14 | @property (readonly) NSUInteger count; 15 | //!移除并返回位于 STQueue 开始处的对象。 16 | -(ObjectType)dequeue; 17 | //!返回位于 STQueue 开始处的对象但不将其移除。 18 | -(ObjectType)peek; 19 | //!将对象添加到 STQueue 的结尾处 20 | - (void)enqueue:(ObjectType)anObject; 21 | @end 22 | 23 | -------------------------------------------------------------------------------- /Sagit/STBase/STView.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "STController.h" 11 | 12 | @interface STView : UIView 13 | //!所对应的Controller (弱引用,不然就双向引用内存不保) 14 | @property (nonatomic,weak) STController *Controller; 15 | 16 | //!初始化 17 | -(instancetype)initWithController:(STController*)controller; 18 | 19 | #pragma mark 通用的两个事件方法:initUI、initData #pragma mark (还有一个位于基类的:reloadData) 20 | //!UI初始化 21 | -(void)initUI; 22 | //!事件在UI初始化之后执行 23 | -(void)initData; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Sagit/STTool/Common/STCache.h: -------------------------------------------------------------------------------- 1 | // 2 | // STCache.h 3 | // IT恋 4 | // 5 | // Created by 陈裕强 on 2018/1/10. 6 | // Copyright © 2018年 . All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface STCache : NSObject 12 | 13 | +(instancetype)share; 14 | @property (readonly,nonatomic,retain)NSMutableDictionary*cacheObj; 15 | //!获取缓存: 16 | -(id)get:(NSString*)key; 17 | //!是否存在指定的缓存。 18 | -(BOOL)has:(NSString*)key; 19 | //!设置缓存。 20 | -(void)set:(NSString*)key value:(id)value; 21 | //!设置缓存:可以设置过期的时间。 22 | -(void)set:(NSString*)key value:(id)value second:(NSInteger)timeOutSecond; 23 | //!移除指定缓存 24 | -(void)remove:(NSString*)key; 25 | //!清除所有缓存 26 | -(void)clear; 27 | @end 28 | -------------------------------------------------------------------------------- /Sagit/Category/Object/STNSMutableDictionary.h: -------------------------------------------------------------------------------- 1 | // 2 | // STNSMutableDictionary.h 3 | // 4 | // Created by 陈裕强 on 2020/8/18. 5 | // 6 | 7 | #import 8 | 9 | @interface NSMutableDictionary(ST) 10 | +(instancetype)share; 11 | //!把格式化的JSON格式的字符串转换成字典 12 | +(id)initWithJsonOrEntity:(id)jsonOrEntity; 13 | -(id)get:(NSString*)key; 14 | //!取值并忽略大小写。 15 | -(id)getWithIgnoreCase:(NSString*)key; 16 | -(BOOL)has:(NSString*)key; 17 | -(void)set:(NSString*)key value:(id)value; 18 | //-(void)set:(NSString*)key valueWeak:(id)value; 19 | -(void)remove:(NSString*)key; 20 | -(NSString*)toJson; 21 | //!转成实体类(Model) 22 | +(void)dictionaryToEntity:(NSDictionary*)dic to:(id)entity; 23 | @end 24 | 25 | 26 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUILabel.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface UILabel(ST) 13 | 14 | #pragma mark 扩展系统事件 15 | -(UILabel*)longPressCopy:(BOOL)yesNo; 16 | //!复制文本 17 | -(UILabel*)copy; 18 | 19 | #pragma mark 扩展系统属性 20 | -(UILabel*)text:(NSString*)text; 21 | -(UILabel*)textColor:(id)colorOrHex; 22 | -(UILabel*)textAlignment:(NSTextAlignment)align; 23 | -(UILabel*)font:(CGFloat)px; 24 | -(UILabel*)numberOfLines:(NSInteger)value; 25 | -(UILabel*)adjustsFontSizeToFitWidth:(BOOL)yesNo; 26 | @end 27 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUIViewAs.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "STUIView.h" 11 | @interface UIView(STUIViewAs) 12 | -(UISwitch*)asSwitch; 13 | -(UIStepper*)asStepper; 14 | -(UIProgressView*)asProgressView; 15 | -(UILabel*)asLabel; 16 | -(UIImageView*)asImageView; 17 | -(UITextField*)asTextField; 18 | -(UITextView*)asTextView; 19 | -(UIButton*)asButton; 20 | -(UIScrollView*)asScrollView; 21 | -(UITableView*)asTableView; 22 | -(UICollectionView*)asCollectionView; 23 | -(UIPickerView*)asPickerView; 24 | -(STView*)asSTView; 25 | -(UIView*)asBaseView; 26 | -(UIImage*)asImage; 27 | @end 28 | -------------------------------------------------------------------------------- /Sagit/STModel/STModelBase.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | #import 9 | 10 | @interface STModelBase:NSObject 11 | //@用于方便子类扩展属性用。 12 | @property(nonatomic,strong) NSMutableDictionary* stKeyValue; 13 | -(id)init; 14 | -(id)initWithObject:(id)msg; 15 | -(id)initWithDictionary:(NSDictionary*)dic; 16 | -(NSDictionary*)toDictionary; 17 | 18 | //!指定的属性名称是否忽略。 19 | -(BOOL)isIgnore:(NSString*)name; 20 | //!是否忽略大小写。 21 | -(BOOL)isIgnoreCase; 22 | //转JSON。 23 | -(NSString*)toJson; 24 | //!NSArray 转 NSArray 25 | +(NSArray* )toArrayEntityFrom:(NSArray*)array; 26 | @end 27 | 28 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUIImage.h: -------------------------------------------------------------------------------- 1 | // 2 | // STUIImage.h 3 | // 4 | // Created by 陈裕强 on 2020/8/19. 5 | // 6 | 7 | #import 8 | #import 9 | #import 10 | @interface UIImage(ST) 11 | //!为每个UI都扩展有一个name 12 | @property (nonatomic,copy) NSString* name; 13 | typedef void (^OnAfterImageSave)(NSError *err); 14 | @property (nonatomic,copy) OnAfterImageSave afterImageSaveBlock; 15 | //!获取图片压缩后的字节数据,当前图片不受变化 16 | -(NSData*)compress:(NSInteger)maxKb; 17 | -(void)save:(OnAfterImageSave)afterSave; 18 | //!在UIImage周围添加透明空间 19 | -(UIImage*)drawIn:(CGSize)size point:(CGPoint)point; 20 | 21 | //!检测最大宽高的等比缩放 22 | -(UIImage *)reSize:(CGSize)maxSize; 23 | -(UIImage *)reSize:(CGSize)maxSize point:(CGPoint)point; 24 | -(NSData*)data; 25 | 26 | +(UIImage*)toImage:(id)imgOrName; 27 | 28 | @end 29 | 30 | -------------------------------------------------------------------------------- /Sagit/STModel/Common/STHttpModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import "STModelBase.h" 10 | 11 | @interface STHttpModel : STModelBase 12 | @property (nonatomic, assign) BOOL success; 13 | @property (nonatomic, retain) id msg; 14 | @property (nonatomic, assign) NSInteger code; 15 | //!将msg转成dictionary返回 16 | @property (retain, nonatomic,readonly) NSDictionary* msgDic; 17 | //!将msg转成Array返回 18 | @property (retain, nonatomic,readonly) NSArray* msgArray; 19 | //!将msg转成string返回 20 | @property (copy, nonatomic,readonly) NSString* msgString; 21 | //!获取请求返回的原始输出 22 | @property (copy, nonatomic,readonly) NSString* responseText; 23 | @end 24 | 25 | 26 | -------------------------------------------------------------------------------- /Sagit/STTool/Common/STLocation.h: -------------------------------------------------------------------------------- 1 | // 2 | // STLocation.h 3 | // 4 | // Created by 陈裕强 on 2020/8/21. 5 | // 6 | 7 | 8 | #import 9 | #import 10 | #import "STLocationModel.h" 11 | #import "LocationConverter.h" 12 | 13 | @interface STLocation : NSObject 14 | typedef void (^OnLocationEnd)(STLocationModel *model); 15 | @property (nonatomic,retain) STLocationModel *cityModel; 16 | + (instancetype)share; 17 | -(void)runOnce; 18 | -(void)start:(OnLocationEnd)locationEnd; 19 | //!是否可用GPS 20 | -(BOOL)isEnabled; 21 | 22 | //!获取坐标间的距离(单位米) 23 | -(double)distince:(double) lat1 lng1:(double) lng1 lat2:(double) lat2 lng2:(double) lng2; 24 | #pragma mark 跳转 25 | //!跳转到系统设置界面 26 | -(void)redirectToSetting; 27 | //!跳转到第3方地图 28 | -(void)redirectToMap; 29 | -(void)redirectToMap:(STLocationModel*)mode; 30 | @end 31 | -------------------------------------------------------------------------------- /Sagit/Category/Object/STStack.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // Copyright © 2017-2027年. All rights reserved. 6 | // 7 | #import "STStack.h" 8 | @interface STStack() 9 | @property (nonatomic,strong) NSMutableArray *array; 10 | 11 | @end 12 | @implementation STStack 13 | -(instancetype)init 14 | { 15 | _array=[NSMutableArray new]; 16 | return self; 17 | } 18 | -(NSUInteger)count 19 | { 20 | return self.array.count; 21 | } 22 | -(void)push:(id)anObject 23 | { 24 | [self.array addObject:anObject]; 25 | } 26 | -(id)pop 27 | { 28 | id obj=[self.array lastObject]; 29 | [self.array removeObject:obj]; 30 | return obj; 31 | } 32 | -(id)peek 33 | { 34 | id obj=[self.array lastObject]; 35 | return obj; 36 | } 37 | @end 38 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUICollectionView.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import "STController.h" 10 | 11 | @interface UICollectionView(ST) 12 | #pragma mark 核心扩展 13 | typedef void(^OnAddCollectionCell)(UICollectionViewCell *cell,NSIndexPath *indexPath); 14 | typedef BOOL(^OnDelCollectionCell)(UICollectionViewCell *cell,NSIndexPath *indexPath); 15 | //!用于为Table追加每一行的Cell 16 | @property (nonatomic,copy) OnAddCollectionCell addCell; 17 | //!用于为Table移除行的Cell 18 | @property (nonatomic,copy) OnDelCollectionCell delCell; 19 | //!获取Table的数据源 20 | @property (nonatomic,strong) NSMutableArray *source; 21 | //!设置Table的数据源 22 | -(UITableView*)source:(NSMutableArray *)dataSource; 23 | @end 24 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUISwitch.h: -------------------------------------------------------------------------------- 1 | // 2 | // STUISwitch.h 3 | // IT恋 4 | // 5 | // Created by 陈裕强 on 2018/1/1. 6 | // Copyright © 2018年 . All rights reserved. 7 | // 8 | 9 | #import "STController.h" 10 | 11 | @interface UISwitch(ST) 12 | 13 | #pragma mark 事件 14 | typedef void(^onSwitch)(UISwitch *view); 15 | //!绑定事件 event:指定事件名称,也可以是控制器名称,也可以指向其它UI的事件,如:Age.click (Age是其它UI的name) 16 | //-(UIView*)addSwitch:(NSString*)event; 17 | //!绑定事件 并指定target 18 | //-(UIView*)addSwitch:(NSString *)event target:(UIViewController*)target; 19 | //!绑定事件 用代码块的形式 20 | -(UIView*)onSwitch:(onSwitch)block; 21 | 22 | #pragma mark 属性扩展 23 | -(UISwitch*)on:(BOOL)yesNo; 24 | -(UISwitch*)tintColor:(id)colorOrHex; 25 | -(UISwitch*)onTintColor:(id)colorOrHex; 26 | -(UISwitch*)enabled:(BOOL)yesNo; 27 | -(UISwitch*)onImage:(id)imgOrName; 28 | -(UISwitch*)offImage:(id)imgOrName; 29 | @end 30 | -------------------------------------------------------------------------------- /Sagit/Category/Object/STQueue.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // Copyright © 2017-2027年. All rights reserved. 6 | // 7 | 8 | #import "STQueue.h" 9 | @interface STQueue() 10 | @property (nonatomic,strong) NSMutableArray *array; 11 | 12 | @end 13 | @implementation STQueue 14 | -(instancetype)init 15 | { 16 | _array=[NSMutableArray new]; 17 | return self; 18 | } 19 | -(NSUInteger)count 20 | { 21 | return self.array.count; 22 | } 23 | -(void)enqueue:(id)anObject 24 | { 25 | [self.array addObject:anObject]; 26 | } 27 | -(id)dequeue 28 | { 29 | id obj=[self.array firstObject]; 30 | [self.array removeObject:obj]; 31 | return obj; 32 | } 33 | -(id)peek 34 | { 35 | id obj=[self.array firstObject]; 36 | return obj; 37 | } 38 | @end 39 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUICollectionViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import "STController.h" 10 | 11 | @interface UICollectionViewCell(ST) 12 | //!获取Cell的数据源 13 | @property (nonatomic,strong) NSMutableDictionary *source; 14 | //!设置Cell的数据源 15 | -(UICollectionViewCell *)source:(NSMutableDictionary *)dataSource; 16 | //!创建或复用Cell 17 | + (instancetype)reuseCell:(UICollectionView *)tableView index:(NSIndexPath *)index; 18 | //!获取当前所在的table 19 | -(UICollectionView*)table; 20 | 21 | //!获取是否允许删除属性 22 | //-(BOOL)allowDelete; 23 | //!设置是否允许删除 24 | //-(UITableView*)allowDelete:(BOOL)yesNo; 25 | //!数据源中的第一个字段,系统自动设置 26 | -(NSString*)firstValue; 27 | -(UICollectionViewCell*)firstValue:(NSString*)value; 28 | @end 29 | -------------------------------------------------------------------------------- /Sagit/Category/Object/STDictionary.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // Copyright © 2017-2027年. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface NSDictionary(ST) 11 | @property (nonatomic,retain)NSDictionary* caseDic; 12 | //!把格式化的JSON格式的字符串转换成字典 13 | +(id)initWithJsonOrEntity:(id)jsonOrEntity; 14 | 15 | -(NSMutableDictionary*)toNSMutableDictionary; 16 | -(id)get:(NSString*)key; 17 | //!取值并忽略大小写。 18 | -(id)getWithIgnoreCase:(NSString*)key; 19 | -(id)firstObject; 20 | -(BOOL)has:(NSString*)key; 21 | -(NSString*)toJson; 22 | //!转成实体类(Model) 23 | +(void)dictionaryToEntity:(NSDictionary*)dic to:(id)entity; 24 | 25 | @end 26 | 27 | 28 | @interface NSJSONSerialization(ST) 29 | +(NSString*)dicToJson:(NSDictionary*)dic; 30 | +(NSString*)arrayToJson:(NSArray*)array; 31 | @end 32 | 33 | 34 | -------------------------------------------------------------------------------- /Sagit/Category/Object/STNSMapTable.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // Copyright © 2017-2027年. All rights reserved. 6 | // 7 | 8 | #import 9 | #pragma mark NSMapTable(ST) 10 | @interface NSMapTable(ST) 11 | -(id)get:(NSString*)key; 12 | -(BOOL)has:(NSString*)key; 13 | -(void)set:(NSString*)key value:(id)value; 14 | -(void)remove:(NSString*)key; 15 | @end 16 | 17 | #pragma mark STMapTable 18 | @interface STMapTable : NSObject 19 | @property (nonatomic,retain)NSMutableArray *keys; 20 | @property (nonatomic,retain) NSMapTable *mapTable; 21 | -(instancetype)init; 22 | 23 | -(id)get:(NSString*)key; 24 | //!取值并忽略大小写。 25 | -(id)getWithIgnoreCase:(NSString*)key; 26 | -(BOOL)has:(NSString*)key; 27 | -(void)set:(NSString*)key value:(id)value; 28 | -(void)remove:(NSString*)key; 29 | @end 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Sagit/Category/Object/STUserDefaults.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import "STUserDefaults.h" 10 | 11 | 12 | @implementation NSUserDefaults(ST) 13 | 14 | -(NSString *)get:(NSString *)key 15 | { 16 | //NSUserDefaults *data=[NSUserDefaults standardUserDefaults]; 17 | return [self valueForKey:key]; 18 | } 19 | 20 | -(void)set:(NSString *)key value:(NSString *)value 21 | { 22 | //NSUserDefaults *data=[NSUserDefaults standardUserDefaults]; 23 | return [self setValue:value forKey:key]; 24 | } 25 | -(BOOL)has:(NSString *)key 26 | { 27 | return [self get:key]!=nil; 28 | 29 | } 30 | -(void)remove:(NSString *)key 31 | { 32 | //NSUserDefaults *data=[NSUserDefaults standardUserDefaults]; 33 | return [self removeObjectForKey:key]; 34 | } 35 | @end 36 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUIPageControl.h: -------------------------------------------------------------------------------- 1 | // 2 | // STUIPageControl.h 3 | // IT恋 4 | // 5 | // Created by 陈裕强 on 2018/2/1. 6 | // Copyright © 2018年 . All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIPageControl(ST) 12 | @property (readonly,nonatomic,weak)UIScrollView* scrollView; 13 | -(UIPageControl*)numberOfPages:(NSInteger)num; 14 | -(UIPageControl*)currentPage:(NSInteger)pagerIndex; 15 | -(UIPageControl*)pageColor:(id)colorOrHex; 16 | -(UIPageControl*)currentColor:(id)colorOrHex; 17 | #pragma mark 定时切换 18 | typedef void (^OnPageTimer)(NSTimer* timer); 19 | @property (readonly,nonatomic,assign)BOOL isTimering; 20 | 21 | -(UIPageControl*)startTimer:(NSInteger)second onTimer:(OnPageTimer)onTimer; 22 | -(UIPageControl*)stopTimer; 23 | 24 | #pragma mark 值改变事件 25 | @property (nonatomic,assign)BOOL allowClickPager; 26 | typedef void (^OnPagerChange)(UIPageControl* pager); 27 | @property (nonatomic,copy)OnPagerChange onPagerChange; 28 | @end 29 | -------------------------------------------------------------------------------- /Sagit/STModel/Common/STLayoutTracer.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "STEnum.h" 12 | 13 | @interface STLayoutTracer : NSObject 14 | @property (nonatomic, weak) UIView* view; 15 | @property (nonatomic,assign) XYLocation location; 16 | @property (nonatomic,assign) XYFlag xyFlag; 17 | @property (nonatomic,assign) CGFloat v1; 18 | @property (nonatomic,assign) CGFloat v2; 19 | @property (nonatomic,assign) CGFloat v3; 20 | @property (nonatomic,assign) CGFloat v4; 21 | 22 | #pragma mark 属性方法 23 | -(BOOL) hasRelateLeft; 24 | -(CGFloat)relateLeftPx; 25 | -(BOOL) hasRelateTop; 26 | -(CGFloat)relateTopPx; 27 | -(BOOL) hasRelateRight; 28 | -(CGFloat)relateRightPx; 29 | -(BOOL) hasRelateBottom; 30 | -(CGFloat)relateBottomPx; 31 | @end 32 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUIControl.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIControl (ST) 12 | 13 | #pragma mark 系统事件 14 | typedef void(^OnAction)(id control); 15 | ////!执行点击事件 16 | //-(UIControl*)action; 17 | ////!绑定事件 event:指定事件名称,也可以是控制器名称,也可以指向其它UI的事件,如:Age.click (Age是其它UI的name) 18 | //-(UIControl*)addAction:(NSString*)event; 19 | ////!绑定事件 并指定target 20 | //-(UIControl*)addAction:(NSString *)event target:(UIViewController*)target; 21 | ////!绑定事件 用代码块的形式 22 | //-(UIControl*)onAction:(onAction)block event:(UIControlEvents)event; 23 | //!移除绑定点击事件 24 | -(UIControl*)removeAction:(UIControlEvents)event; 25 | -(UIControl*)onAction:(UIControlEvents)event on:(OnAction)block; 26 | #pragma mark 系统属性 27 | -(UIControl*)enabled:(BOOL)yesNo; 28 | -(UIControl *)selected:(BOOL)yesNo; 29 | -(UIControl *)highlighted:(BOOL)yesNo; 30 | @end 31 | -------------------------------------------------------------------------------- /Sagit/Category/Object/STArray.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // Copyright © 2017-2027年. All rights reserved. 6 | // 7 | 8 | #import "STArray.h" 9 | 10 | @implementation NSArray(ST) 11 | 12 | -(NSMutableArray*)toNSMutableArray 13 | { 14 | NSMutableArray *array=[NSMutableArray new]; 15 | for (NSInteger i=0; i 10 | //说明对于 [UINavigationBar appearcence] 出来的是协议,不是实例 11 | //网上的Demo多数是:UINavigationBar *bar=[UINavigationBar appearcence]; 12 | //这种拿到的bar是协议不是实例,如果调用了扩展方法,就会Crash。 13 | 14 | @interface UINavigationBarSetting:NSObject 15 | #pragma mark 扩展系统属性 16 | //字体颜色 17 | -(UINavigationBarSetting*)tintColor:(id)colorOrHex; 18 | //背景色 19 | -(UINavigationBarSetting*)barTintColor:(id)colorOrHex; 20 | -(UINavigationBarSetting*)backgroundImage:(id)img; 21 | -(UINavigationBarSetting*)backgroundImage:(id)img stretch:(BOOL)stretch; 22 | -(UINavigationBarSetting*)shadowImage:(id)img; 23 | -(UINavigationBarSetting*)titleTextAttributes:(NSDictionary *)dic; 24 | -(UINavigationBarSetting*)translucent:(BOOL)yesNo; 25 | @end 26 | 27 | @interface UINavigationBar (ST) 28 | +(UINavigationBarSetting*)globalSetting; 29 | @end 30 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUICollectionView.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import "STUICollectionView.h" 10 | #import "STUIView.h" 11 | @implementation UICollectionView(ST) 12 | 13 | #pragma mark 核心扩展 14 | -(NSMutableArray *)source 15 | { 16 | return [self key:@"source"]; 17 | } 18 | -(void)setSource:(NSMutableArray *)source 19 | { 20 | [self source:source]; 21 | } 22 | -(UICollectionView *)source:(NSMutableArray *)dataSource 23 | { 24 | [self key:@"source" value:dataSource]; 25 | return self; 26 | } 27 | -(OnAddCollectionCell)addCell 28 | { 29 | return [self key:@"addCell"]; 30 | } 31 | -(void)setAddCell:(OnAddCollectionCell)addCell 32 | { 33 | [self key:@"addCell" value:addCell]; 34 | } 35 | -(OnDelCollectionCell)delCell 36 | { 37 | return [self key:@"delCell"]; 38 | } 39 | -(void)setDelCell:(OnDelCollectionCell)delCell 40 | { 41 | [self key:@"delCell" value:delCell]; 42 | } 43 | @end 44 | -------------------------------------------------------------------------------- /Sagit/STTool/Tool/CropImage/CropPanGestureRecognizer.m: -------------------------------------------------------------------------------- 1 | 2 | #import "CropPanGestureRecognizer.h" 3 | #import 4 | 5 | @interface CropPanGestureRecognizer() 6 | 7 | @property(strong, nonatomic) UIView *targetView; 8 | 9 | @end 10 | 11 | @implementation CropPanGestureRecognizer 12 | 13 | -(instancetype)initWithTarget:(id)target action:(SEL)action inview:(UIView*)view{ 14 | 15 | self = [super initWithTarget:target action:action]; 16 | if(self) { 17 | self.targetView = view; 18 | } 19 | return self; 20 | } 21 | 22 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event{ 23 | 24 | [super touchesBegan:touches withEvent:event]; 25 | UITouch *touch = [touches anyObject]; 26 | self.beginPoint = [touch locationInView:self.targetView]; 27 | } 28 | 29 | - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 30 | { 31 | [super touchesMoved:touches withEvent:event]; 32 | UITouch *touch = [touches anyObject]; 33 | self.movePoint = [touch locationInView:self.targetView]; 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUITextField.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface UITextField(ST) 13 | typedef void (^OnTextFieldEdit)(UITextField*textField,BOOL isEnd); 14 | @property (nonatomic,copy) OnTextFieldEdit onEdit; 15 | #pragma mark 自定义追加属系统 16 | //!文本指定的最大长度(超过这个长度则无法再输入内容) 17 | -(NSInteger)maxLength; 18 | //!对文本指定最大长度(超过这个长度则无法再输入内容) 19 | - (UITextField*)maxLength:(NSInteger)length; 20 | 21 | 22 | #pragma mark 扩展系统属性 23 | -(UITextField*)keyboardType:(UIKeyboardType)value; 24 | -(UITextField*)secureTextEntry:(BOOL)value; 25 | -(UITextField*)text:(NSString*)text; 26 | -(UITextField*)font:(CGFloat)px; 27 | -(UITextField*)textColor:(id)colorOrHex; 28 | -(UITextField*)textAlignment:(NSTextAlignment)value; 29 | -(UITextField*)placeholder:(NSString*)text; 30 | -(UITextField*)borderStyle:(UITextBorderStyle)style; 31 | -(UITextField*)enabled:(BOOL)yesNo; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Sagit/STModel/Common/STHttpModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import "STHttpModel.h" 10 | 11 | @implementation STHttpModel 12 | 13 | -(BOOL)isIgnore:(NSString *)name 14 | { 15 | if([name eq:@"msgArray"] || [name eq:@"msgDic"] ||[name eq:@"msgString"]) 16 | { 17 | return YES; 18 | } 19 | return [super isIgnore:name]; 20 | } 21 | 22 | -(NSArray*)msgArray 23 | { 24 | if(self.msg && [self.msg isKindOfClass:[NSArray class]]) 25 | { 26 | return (NSArray*)self.msg; 27 | } 28 | return nil; 29 | } 30 | -(NSDictionary *)msgDic 31 | { 32 | if(self.msg && [self.msg isKindOfClass:[NSDictionary class]]) 33 | { 34 | return (NSDictionary*)self.msg; 35 | } 36 | return nil; 37 | } 38 | -(NSString *)msgString 39 | { 40 | if(self.msg && [self.msg isKindOfClass:[NSString class]]) 41 | { 42 | return (NSString*)self.msg; 43 | } 44 | return nil; 45 | } 46 | @end 47 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUITextView.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | 13 | @interface UITextView(ST) 14 | typedef void (^OnTextViewEdit)(UITextView*textView,BOOL isEnd); 15 | @property (nonatomic,copy) OnTextViewEdit onEdit; 16 | #pragma mark 自定义追加属系统 17 | //!文字框最多能输入的长度 18 | -(NSInteger)maxLength; 19 | - (UITextView*)maxLength:(NSInteger)length; 20 | 21 | //!文字框最大的行数(px) 22 | - (NSInteger)maxRow; 23 | - (UITextView*)maxRow:(NSInteger)num; 24 | 25 | #pragma mark 扩展系统属性 26 | -(UITextView*)keyboardType:(UIKeyboardType)value; 27 | -(UITextView*)secureTextEntry:(BOOL)value; 28 | -(UITextView*)text:(NSString*)text; 29 | -(UITextView*)font:(CGFloat)px; 30 | -(UITextView*)textColor:(id)colorOrHex; 31 | -(UITextView*)textAlignment:(NSTextAlignment)value; 32 | //!自定义扩展 33 | -(UITextView*)placeholder; 34 | -(UITextView*)placeholder:(NSString*)text; 35 | -(UITextView*)editable:(BOOL)yesNo; 36 | @end 37 | 38 | 39 | -------------------------------------------------------------------------------- /Sagit/STTool/STSagit.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | 7 | #import 8 | //#import 9 | #import "STDefine.h" 10 | #import "STFile.h" 11 | #import "STHttp.h" 12 | #import "STCache.h" 13 | #import "STMsgBox.h" 14 | #import "STLocation.h" 15 | 16 | //!所有单例的入口,可以扩展此类,来增加不同的方法,达到如:Sagit.Global之类的用法。 17 | @interface Sagit : NSObject 18 | //!单例,目前没啥用。 19 | //+ (instancetype)share; 20 | //@property(nonatomic,weak)UIView* Layout; 21 | //!全局定义 22 | +(STDefine*)Define; 23 | //!默认对应于NSCache沙盒目录(用于存档数据到plist文件中) 24 | +(STFile*)File; 25 | //!用于存档到内存的全局唯一字典。 26 | +(STCache*)Cache; 27 | //!用于发起网络请求的单例类,,在STController中时用self.http调用 28 | +(STHttp*)Http; 29 | //!用于弹窗消息的单例类,在STController中时用self.msgBox调用 30 | +(STMsgBox*)MsgBox; 31 | //!用于GPS坐标定位 32 | +(STLocation*)Location; 33 | #pragma mark 扩展一些全局的方法 34 | typedef void (^DelayExecuteBlock)(); 35 | //延时N秒后执行 36 | +(void)delayExecute:(double)second onMainThread:(BOOL)onMainThread block:(DelayExecuteBlock)block; 37 | //回主线程处理代码 38 | +(void)runOnMainThread:(DelayExecuteBlock)block; 39 | @end 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUISwitch.m: -------------------------------------------------------------------------------- 1 | // 2 | // STUISwitch.m 3 | // IT恋 4 | // 5 | // Created by 陈裕强 on 2018/1/1. 6 | // Copyright © 2018年 . All rights reserved. 7 | // 8 | 9 | #import "STUISwitch.h" 10 | #import "STUIView.h" 11 | #import "STUIControl.h" 12 | #import "STCategory.h" 13 | @implementation UISwitch(ST) 14 | -(UISwitch*)on:(BOOL)yesNo 15 | { 16 | [self setOn:yesNo]; 17 | return self; 18 | } 19 | -(UISwitch*)tintColor:(id)colorOrHex 20 | { 21 | self.tintColor=[UIColor toColor:colorOrHex]; 22 | return self; 23 | } 24 | -(UISwitch*)onTintColor:(id)colorOrHex 25 | { 26 | self.onTintColor=[UIColor toColor:colorOrHex]; 27 | return self; 28 | } 29 | -(UISwitch*)enabled:(BOOL)yesNo 30 | { 31 | [self setEnabled:yesNo]; 32 | return self; 33 | } 34 | -(UISwitch*)onImage:(id)imgOrName 35 | { 36 | [self setOnImage:[UIImage toImage:imgOrName]]; 37 | return self; 38 | } 39 | -(UISwitch*)offImage:(id)imgOrName 40 | { 41 | [self setOffImage:[UIImage toImage:imgOrName]]; 42 | return self; 43 | } 44 | 45 | #pragma mark 事件 46 | -(UIView *)onSwitch:(onSwitch)block 47 | { 48 | [self onAction:UIControlEventValueChanged on:block]; 49 | return self; 50 | } 51 | @end 52 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUIButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //typedef void(^onAction)(UIButton *button); 12 | @interface UIButton (ST) 13 | 14 | #pragma mark 扩展系统属性 15 | -(UIButton*)backgroundImage:(id)img; 16 | -(UIButton*)backgroundImage:(id)img forState:(UIControlState)state; 17 | -(UIButton*)image:(id)img; 18 | -(UIButton*)image:(id)img forState:(UIControlState)state; 19 | -(UIButton*)title:(NSString*)title; 20 | -(UIButton*)title:(NSString*)title forState:(UIControlState)state; 21 | -(UIButton*)titleColor:(id)colorOrHex; 22 | -(UIButton*)titleColor:(id)colorOrHex forState:(UIControlState)state; 23 | -(UIButton*)titleFont:(CGFloat)px; 24 | -(UIButton*)adjustsImageWhenHighlighted:(BOOL)yesNo; 25 | //!当button在动态设置文字或图片之后,宽度自适应 26 | -(UIButton*)stWidthToFit; 27 | //!显示Ns的倒计时状态(秒),时间到了,默认恢复初始文字 28 | -(UIButton*)showTime:(NSInteger)second; 29 | //!显示Ns的倒计时状态(秒) resetStateOnEnd Yes(时间到了,恢复初始文字) NO (时间到了,不恢复初始文字) 30 | -(UIButton *)showTime:(NSInteger)second resetStateOnEnd:(BOOL)resetStateOnEnd; 31 | @end 32 | -------------------------------------------------------------------------------- /Sagit/Define/STDefineFunc.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | 7 | #ifndef STDefineFunc_h 8 | #define STDefineFunc_h 9 | 10 | #pragma mark 函数定义:(可使用、而不可更改) 11 | 12 | //将字符从大写转化成小写 13 | #define STCharLower(c) ((c >= 'A' && c <= 'Z') ? (c | 0x20) : c) 14 | //将字符从小写转化成大写 15 | #define STCharUpper(c) ((c >= 'a' && c <= 'z') ? (c & ~0x20) : c) 16 | //数字转字符串 17 | #define STNumString(value) [@(value) stringValue] 18 | #define STString(format,...) [NSString stringWithFormat:format,##__VA_ARGS__] 19 | //系统的版本号 20 | #define STOSVersion [[[UIDevice currentDevice] systemVersion] doubleValue] 21 | //!为Controller定义的 22 | #define STNew(className) ((UIViewController*)STNewClass([className appendIfNotEndWith:@"Controller"])) 23 | //!为所有的class定义的 24 | #define STNewClass(className) [NSClassFromString(className) new] 25 | //block块中用的引用 26 | #define STWeakSelf __weak typeof(self) selfWeak = self;__weak typeof(selfWeak) this = selfWeak; 27 | #define STWeakObj(o) __weak typeof(o) o##Weak = o; 28 | #define STStrongObj(o) __strong typeof(o) o = o##Weak; 29 | //日志输出。 30 | #define STLog(frame) NSLog(@"frame : %@",NSStringFromCGRect(frame)); 31 | #endif /* Constants_h */ 32 | -------------------------------------------------------------------------------- /Sagit/Category/Object/STFont.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // Copyright © 2017-2027年. All rights reserved. 6 | // 7 | 8 | #import "STFont.h" 9 | #import "STDefineUI.h" 10 | #import "STSagit.h" 11 | @implementation UIFont(ST) 12 | 13 | +(UIFont *)toFont:(CGFloat)px 14 | { 15 | NSNumber *pxNum=@(px); 16 | NSString*value=[@(px) stringValue]; 17 | if([value containsString:@".0"]) 18 | { 19 | //有小数点。 20 | return [UIFont boldSystemFontOfSize:pxNum.integerValue*Xpt]; 21 | } 22 | else if(px>300) 23 | { 24 | px=[[value substringWithRange:NSMakeRange(0, 2)] integerValue]; 25 | NSInteger type=[[value substringFromIndex:2] integerValue];//type 26 | if(type==0) 27 | { 28 | return [UIFont boldSystemFontOfSize:px*Xpt]; 29 | } 30 | } 31 | return [UIFont systemFontOfSize:px*Xpt]; 32 | } 33 | +(UIFont *)toFont:(NSInteger)px name:(NSString*)name 34 | { 35 | return [UIFont fontWithName:name size:px*Xpt]; 36 | } 37 | +(UIFont *)toFont:(NSInteger)px bold:(BOOL)bold 38 | { 39 | return bold?[UIFont boldSystemFontOfSize:px*Xpt]:[UIFont systemFontOfSize:px*Xpt]; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /Sagit/Define/STDefine.h: -------------------------------------------------------------------------------- 1 | // 2 | // STDefine.h 3 | // 4 | // Created by 陈裕强 on 2020/9/11. 5 | // 6 | 7 | #import 8 | #import 9 | 10 | @interface STDefine : NSObject 11 | + (instancetype)share; 12 | #pragma mark 框架版本 13 | /// 版本号 14 | @property (nonatomic,copy) NSString *Version; 15 | /// 版本发布时间 16 | @property (nonatomic,copy) NSString *VersionNum; 17 | 18 | #pragma mark UI编码规范【重要】 19 | ///【可更改】选择编码标准:1倍(375*667)、2倍(750*1334)【默认值】、3倍(1125*2001) 20 | @property (nonatomic,assign) NSInteger StandardScale; 21 | 22 | #pragma mark 状态栏、导航栏、Tab栏 默认显示定义 【可选】 23 | /// 状态栏 的默认显示 YES 24 | @property (nonatomic,assign) BOOL DefaultShowStatus; 25 | /// 有NavController 的默认显示 YES 26 | @property (nonatomic,assign) BOOL DefaultShowNav; 27 | /// 有TabController 的默认显示 YES 28 | @property (nonatomic,assign) BOOL DefaultShowTab; 29 | 30 | #pragma mark 导航栏 【可选】 31 | /// 可设定名称 【默认返回文字】 32 | @property (nonatomic,copy) NSString *DefaultNavLeftTitle; 33 | /// 可设定图标 【默认返回图标】 34 | @property (nonatomic,copy) NSString *DefaultNavLeftImage; 35 | #pragma mark 手机屏幕默认的显示方向(默认:竖立) 【可选】 36 | /// 可设定手机屏幕默认的显示方向 37 | @property (nonatomic,assign) UIInterfaceOrientation DefaultOrientation; 38 | /// 可设定手机屏幕默认支持的显示方向 39 | @property (nonatomic,assign) UIInterfaceOrientationMask DefaultOrientationMask; 40 | @end 41 | 42 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUITableViewCellAction.h: -------------------------------------------------------------------------------- 1 | // 2 | // STUITableViewCellMenu.h 3 | // 4 | // Created by 陈裕强 on 2020/9/16. 5 | // 6 | 7 | #import 8 | 9 | @interface STCellAction : NSObject 10 | typedef void(^OnCellAction)(UITableViewCell *cell, NSIndexPath * indexPath); 11 | typedef void(^OnCustomView)(UIView *actionView, NSIndexPath * indexPath); 12 | //!事件【点击事件】 13 | @property (nonatomic,copy) OnCellAction onAction; 14 | //!事件【自定义ActionView事件】 15 | @property (nonatomic,copy) OnCustomView onCustomView; 16 | //!标题【非自定义ActionView事件时】 17 | @property (nonatomic,retain) NSString* title; 18 | //!背景色【非自定义ActionView事件时】 19 | @property (nonatomic,retain) UIColor* bgColor; 20 | //!释放。 21 | -(void)dispose; 22 | @end 23 | 24 | @interface STUITableViewCellAction : NSObject 25 | 26 | -(instancetype)initWithCell:(UITableViewCell*) cell; 27 | //!action 集合。 28 | @property (nonatomic,retain) NSMutableArray *items; 29 | //!获取当前所在的cell,(weak,不能造成双strong引用) 30 | @property (nonatomic,weak) UITableViewCell *cell; 31 | //添加 action 【非自定义ActionView】 32 | -(void)addAction:(NSString*)title bgColor:(UIColor*)bgColor onAction:(OnCellAction)onAction; 33 | //添加 action 【自定义ActionView】 34 | -(void)addAction:(OnCustomView)onCustomView onAction:(OnCellAction)onAction; 35 | //!释放。 36 | -(void)dispose; 37 | @end 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Sagit/Sagit.h: -------------------------------------------------------------------------------- 1 | // 名称:Sagit.framework Sagittarius(射手座单词简写) 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | #import 7 | //! Project version number for Sagit. 8 | FOUNDATION_EXPORT double SagitVersionNumber; 9 | 10 | //! Project version string for Sagit. 11 | FOUNDATION_EXPORT const unsigned char SagitVersionString[]; 12 | 13 | // In this header, you should import all the public headers of your framework using statements like #import 14 | 15 | #ifndef STFramework_h 16 | #define STFramework_h 17 | 18 | #import "STSagit.h" 19 | 20 | //STDefine 21 | #import "STDefine.h" 22 | #import "STDefineFunc.h" 23 | #import "STDefineUI.h" 24 | 25 | //STModel 26 | #import "STEnum.h" 27 | #import "STHttpModel.h" 28 | #import "STModelBase.h" 29 | #import "STLayoutTracer.h" 30 | #import "STLocationModel.h" 31 | 32 | //STCategory 33 | #import "STCategory.h" 34 | 35 | //STTool 36 | #import "STMsgBox.h" 37 | #import "STHttp.h" 38 | #import "STFile.h" 39 | #import "STCache.h" 40 | #import "STLocation.h" 41 | #import "CropImageView.h" 42 | 43 | //STBase 44 | #import "STController.h" 45 | #import "STTabController.h" 46 | #import "STNavController.h" 47 | #import "STView.h" 48 | 49 | #endif /* STFramework_h */ 50 | -------------------------------------------------------------------------------- /Sagit/Category/Object/STDate.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // Copyright © 2017-2027年. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface NSDate(ST) 11 | //!自己处理的格式化,只处理年月日时分秒毫秒 12 | -(NSString*)toString:(NSString*)formatter; 13 | //!自己处理的格式化,只处理年月日时分秒毫秒 14 | -(NSString*)toString; 15 | //!系统的格式化(包括星期等信息) 16 | -(NSString*)formatter:(NSString*)formatter; 17 | //!返回类型可以取更多日期属性 18 | -(NSDateComponents *)component; 19 | //!获取北京的当前时间。 20 | +(NSDate *)beiJinDate; 21 | //!字符串转日期 22 | +(NSDate *)parse:(NSString*)datetime; 23 | @property(readonly) NSInteger year; 24 | @property(readonly) NSInteger month; 25 | @property(readonly) NSInteger day; 26 | @property(readonly) NSInteger hour; 27 | @property(readonly) NSInteger minute; 28 | @property(readonly) NSInteger second; 29 | @property(readonly) NSInteger nanosecond; 30 | 31 | -(NSDate*)addSecond:(NSInteger)second; 32 | -(NSDate*)addMinute:(NSInteger)minute; 33 | -(NSDate*)addHour:(NSInteger)hour; 34 | -(NSDate*)addDay:(NSInteger)day; 35 | -(NSDate*)addMonth:(NSInteger)month; 36 | -(NSDate*)addYear:(NSInteger)year; 37 | 38 | @end 39 | @interface NSDateComponents(ST) 40 | -(NSString*)toString:(NSString*)formatter; 41 | -(NSString*)toString; 42 | @end 43 | 44 | -------------------------------------------------------------------------------- /Sagit/Category/STCategory.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | 7 | //Object 8 | #import "STString.h" 9 | #import "STArray.h" 10 | #import "STDictionary.h" 11 | #import "STNSMutableDictionary.h" 12 | #import "STNSMapTable.h" 13 | #import "STDate.h" 14 | #import "STNumber.h" 15 | #import "STUserDefaults.h" 16 | #import "STColor.h" 17 | #import "STFont.h" 18 | #import "STQueue.h" 19 | #import "STStack.h" 20 | //UI 21 | #import "STUIView.h" 22 | #import "STUIViewValue.h" 23 | #import "STUIViewAs.h" 24 | #import "STUIViewEvent.h" 25 | #import "STUIViewAutoLayout.h" 26 | #import "STUIViewAddUI.h" 27 | 28 | #import "STUITextView.h" 29 | #import "STUITextField.h" 30 | #import "STUIButton.h" 31 | #import "STUILabel.h" 32 | #import "STUINavigationBar.h" 33 | #import "STUITableView.h" 34 | #import "STUITableViewCell.h" 35 | #import "STUITableViewCellAction.h" 36 | #import "STUICollectionView.h" 37 | #import "STUICollectionViewCell.h" 38 | #import "STUIImage.h" 39 | #import "STUIImageView.h" 40 | #import "STUIControl.h" 41 | #import "STUISwitch.h" 42 | #import "STUIWindow.h" 43 | #import "STUIPageControl.h" 44 | #import "STUIScrollView.h" 45 | //New UI 46 | // 47 | //#import "STTable.h" 48 | //#import "STTableCell.h" 49 | 50 | //Controller 51 | #import "STUIViewController.h" 52 | 53 | 54 | -------------------------------------------------------------------------------- /Sagit/STTool/Common/STFile.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | #import 9 | #import 10 | 11 | //!用于存档数据到plist文件中,默认存档沙盒的Library/Cache目录(iTunes不会备份此目录,此目录下文件不会在应用退出删除。一般存放体积比较大,不是特别重要的资源,比如缓存数据。缓存数据在设备低存储空间时可能会被删除。) 12 | @interface STFile : NSObject 13 | 14 | //!对应沙盒的Home目录(主目录) 15 | @property (nonatomic,retain) STFile* Home; 16 | //!对应沙盒的Document目录:用于存储用户数据,该目录下的所有文件会进行iCloud或iTunes备份 17 | @property (nonatomic,retain) STFile* Document; 18 | //!对应沙盒的Libaray目录(该路径下的文件夹,除Caches以外,都会被iTunes备份。) 19 | @property (nonatomic,retain) STFile* Libaray; 20 | //!对应沙盒的Tmp目录(目录用于存放临时文件,APP重新启动时会清除这个路径下的文件。该路径下的文件不会被iTunes备份。一般用来保存临时文件,比如:相机拍摄完成时的照片视频都会被暂时保存到这个路径。) 21 | @property (nonatomic,retain) STFile* Temp; 22 | //!存档系统配置信息,对应沙盒的Tmp目录 Library/Preferences(包含应用程序的偏好设置文件。NSUserDefaults就是默认存放在此文件夹下面。) 23 | @property (nonatomic,retain)NSUserDefaults* Setting; 24 | //!存档的文件名(plist)。 25 | @property (readonly,nonatomic,copy) NSString* fileName; 26 | 27 | 28 | + (instancetype)share; 29 | //!获取文件的大小(单位:MB) 30 | - (CGFloat)size; 31 | //!清除所有文件缓存 32 | - (void)clear:(void(^)(BOOL success))block; 33 | //!设置文件缓存 34 | - (void)set:(NSString*)key value:(id)value; 35 | //!获取文件缓存 36 | - (id)get:(NSString*)key; 37 | //!移除文件缓存 38 | - (void)remove:(NSString*)key; 39 | @end 40 | -------------------------------------------------------------------------------- /Sagit/STModel/Common/STEnum.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #ifndef STEnum_h 10 | #define STEnum_h 11 | #import 12 | 13 | typedef NS_ENUM(NSUInteger,RootViewControllerType) { 14 | RootViewDefaultType, 15 | RootViewNavigationType, 16 | RootViewTabBarType 17 | }; 18 | 19 | typedef NS_ENUM(NSUInteger,XYFlag) { 20 | XY=0, 21 | X=1, 22 | Y=2, 23 | }; 24 | 25 | //!布局时的相对位置(取值的依据为:Left:1 Top:2 Ritht:3 Bottom:4 可以根据值来检测所相对哪些位置) 26 | typedef NS_ENUM(NSUInteger,XYLocation) { 27 | Left = 1, 28 | LeftTop = 12, 29 | LeftTopRight = 123, 30 | LeftTopBottom = 124, 31 | LeftRight = 13, 32 | LeftBottom = 14, 33 | LeftBottomRight = 143, 34 | 35 | Top = 2, 36 | TopRight = 23, 37 | TopBottom = 24, 38 | TopRightBottom = 234, 39 | 40 | Right = 3, 41 | RightBottom = 34, 42 | 43 | Bottom = 4, 44 | //相对四边 45 | LeftTopRightBottom = 1234 46 | }; 47 | //!定义拖动的事件 48 | typedef NS_ENUM(NSUInteger,DragDirection) { 49 | DragToLeft=1, 50 | DragToRight=2, 51 | DragToLeftRight=DragToLeft|DragToRight, 52 | DragToUp=4, 53 | DragToDown=8, 54 | DragToUpDown=DragToUp|DragToDown, 55 | DragToAll=DragToLeft|DragToRight|DragToUp|DragToDown, 56 | }; 57 | #endif /* Header_h */ 58 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUITableViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "STUITableViewCellAction.h" 11 | 12 | @interface UITableViewCell(ST) 13 | //!获取当前所在的table,(weak,不能造成双strong引用) 14 | @property (readonly,nonatomic,weak) UITableView *table; 15 | //!获取Cell的数据源 16 | @property (nonatomic,strong) id source; 17 | 18 | //!Cell是否重用的Cell,如果是,就不要再添加子控制,避免重复添加。 19 | //@property (readonly,nonatomic,assign) BOOL isReused; 20 | //!设置Cell的数据源 21 | -(UITableViewCell *)source:(id)dataSource; 22 | //!创建或复用Cell 23 | + (instancetype)reuseCell:(UITableView *)tableView index:(NSIndexPath *)index; 24 | //!获取Cell所在的行数 25 | -(NSIndexPath*)indexPath; 26 | -(UITableViewCell*)indexPath:(NSIndexPath*)indexPath; 27 | //!获取是否允许编辑【删除】属性 28 | -(BOOL)allowEdit; 29 | //!设置是否允许编辑【删除】 30 | -(UITableViewCell*)allowEdit:(BOOL)yesNo; 31 | //!数据源中的第一个字段,系统自动设置 32 | -(NSString*)firstValue; 33 | -(UITableViewCell*)firstValue:(NSString*)value; 34 | //!当Cell的高度在绑定后,需要动态根据子内容高度变化,再次刷新高度时使用。 35 | -(UITableViewCell*)resetHeightCache; 36 | //!刷新表格高度 37 | -(void)refleshTableHeight; 38 | #pragma mark 扩展属性 39 | -(UITableViewCell*)accessoryType:(UITableViewCellAccessoryType)type; 40 | -(UITableViewCell*)selectionStyle:(UITableViewCellSelectionStyle)style; 41 | #pragma mark 扩展 42 | //!获取Cell的滑动菜单项。 43 | @property (nonatomic,strong) STUITableViewCellAction *action; 44 | @end 45 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUIScrollView.h: -------------------------------------------------------------------------------- 1 | // 2 | // STUIScrollView.h 3 | // IT恋 4 | // 5 | // Created by 陈裕强 on 2018/1/29. 6 | // Copyright © 2018年 . All rights reserved. 7 | // 8 | 9 | #import 10 | #import "STEnum.h" 11 | #import "STUIViewEvent.h" 12 | @interface UIScrollView (ST) 13 | //定义两个事件,上一页和下一页 14 | typedef void (^OnScrollPrePager)(UIScrollView *scrollView); 15 | //定义两个事件,上一页和下一页 16 | typedef void (^OnScrollNextPager)(UIScrollView *scrollView); 17 | //!上一页事件 18 | @property (nonatomic,copy)OnScrollPrePager onPrePager; 19 | //!下一页事件 20 | @property (nonatomic,copy)OnScrollNextPager onNextPager; 21 | //!当前页的索引 22 | @property (nonatomic,assign)NSInteger pagerIndex; 23 | //!分页的长度、或高度(px单位)。 24 | @property (nonatomic,assign) NSInteger pagerPx; 25 | //!开始滑动的坐标 26 | @property (nonatomic,assign)CGPoint startPoint; 27 | //!手放开时的坐标 28 | @property (nonatomic,assign)CGPoint endPoint; 29 | //!滑动的方向 30 | @property (nonatomic,assign)XYFlag direction; 31 | //!图片是否全屏 32 | @property (nonatomic,assign)BOOL isImageFull; 33 | 34 | //!绑定事件 用代码块的形式,为所有子View添加事件 35 | -(UIScrollView*)onSubviewClick:(OnViewClick)block; 36 | -(UIScrollView*)removeAt:(NSInteger) index; 37 | -(UIScrollView *)removeAt:(NSInteger)index moveXY:(BOOL)yesNO; 38 | #pragma mark 分页组件 39 | @property (readonly,nonatomic,retain)UIPageControl *pager; 40 | -(BOOL)showPager; 41 | -(UIScrollView*)showPager:(BOOL)yesNo; 42 | //!图片是否允许保存 43 | -(BOOL)isAllowSaveImage; 44 | -(UIScrollView*)isAllowSaveImage:(BOOL)yesNo; 45 | 46 | #pragma mark Add Images 47 | -(UIScrollView *)addImages:(id)imgOrNameOrArray,...NS_REQUIRES_NIL_TERMINATION; 48 | //扩展N页内容大小 49 | -(UIScrollView *)addPageSizeContent:(NSInteger)num; 50 | @end 51 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | # CocoaPods 32 | # 33 | # We recommend against adding the Pods directory to your .gitignore. However 34 | # you should judge for yourself, the pros and cons are mentioned at: 35 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 36 | # 37 | # Pods/ 38 | 39 | # Carthage 40 | # 41 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 42 | # Carthage/Checkouts 43 | 44 | Carthage/Build 45 | 46 | # fastlane 47 | # 48 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 49 | # screenshots whenever they are needed. 50 | # For more information about the recommended setup visit: 51 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 52 | 53 | fastlane/report.xml 54 | fastlane/Preview.html 55 | fastlane/screenshots 56 | fastlane/test_output 57 | 58 | # Code Injection 59 | # 60 | # After new code Injection tools there's a generated folder /iOSInjectionProject 61 | # https://github.com/johnno1962/injectionforxcode 62 | 63 | iOSInjectionProject/ 64 | -------------------------------------------------------------------------------- /Sagit/Category/Object/STString.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // Copyright © 2017-2027年. All rights reserved. 6 | // 7 | 8 | #import 9 | #import 10 | 11 | @interface NSString(ST) 12 | //+ (instancetype)format:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2); 13 | 14 | -(NSString*)reverse; 15 | -(BOOL)isInt; 16 | -(BOOL)isFloat; 17 | -(NSString*)append:(NSString*)string; 18 | //!检测是否已经是以后面的结尾,如果是,则不追加 19 | -(NSString *)appendIfNotEndWith:(NSString *)string; 20 | -(NSString*)replace:(NSString*)a with:(NSString*)b; 21 | -(NSString *)replace:(NSString *)a with:(NSString *)b ignoreCase:(BOOL)ignoreCase; 22 | -(NSArray*)split:(NSString*)separator; 23 | -(NSString*)toUpper; 24 | -(NSString*)toLower; 25 | -(BOOL)startWith:(NSString*)value; 26 | -(BOOL)endWith:(NSString*)value; 27 | -(BOOL)contains:(NSString*)value; 28 | -(BOOL)contains:(NSString*)value ignoreCase:(BOOL)ignoreCase; 29 | -(BOOL)isEmpty; 30 | -(BOOL)eq:(id)value; 31 | +(BOOL)isNilOrEmpty:(NSString*)value; 32 | +(NSString*)toString:(id)value; 33 | +(NSString *)newGuid; 34 | -(NSString*)trim; 35 | -(NSString*)trimStart:(NSString*)value; 36 | -(NSString*)trimEnd:(NSString*)value; 37 | //!去除两位小数点的尾数0,如:13.00=》13,134.30=》134.3 38 | -(NSString*)trimDecimalZero; 39 | -(NSInteger)indexOf:(NSString*)searchString; 40 | -(NSInteger)indexOf:(NSString*)searchString ignoreCase:(BOOL)ignoreCase; 41 | -(NSString*)firstCharUpper; 42 | -(NSString*)firstCharLower; 43 | -(NSString*)remove:(NSInteger)startIndex length:(NSInteger)length; 44 | -(CGSize)sizeWithFont:font maxSize:(CGSize)maxSize; 45 | @end 46 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUITableViewCellAction.m: -------------------------------------------------------------------------------- 1 | // 2 | // STUITableViewCellMenu.m 3 | // 4 | // Created by 陈裕强 on 2020/9/16. 5 | // 6 | 7 | #import "STUITableViewCellAction.h" 8 | @implementation STCellAction 9 | -(void)dispose 10 | { 11 | self.onAction = nil; 12 | self.onCustomView = nil; 13 | self.title=nil; 14 | self.bgColor=nil; 15 | } 16 | @end 17 | @implementation STUITableViewCellAction 18 | 19 | -(instancetype)initWithCell:(UITableViewCell*) cell 20 | { 21 | self=[self init]; 22 | if(cell!=nil) 23 | { 24 | self.cell=cell; 25 | } 26 | return self; 27 | } 28 | -(NSMutableArray*) items 29 | { 30 | 31 | if(_items==nil) 32 | { 33 | _items=[NSMutableArray new]; 34 | } 35 | return _items; 36 | 37 | } 38 | -(void)addAction:(NSString*)title bgColor:(UIColor*)bgColor onAction:(OnCellAction)onAction; 39 | { 40 | STCellAction *menu=[STCellAction new]; 41 | menu.title=title; 42 | menu.bgColor=bgColor; 43 | menu.onAction = onAction; 44 | [self.items addObject:menu]; 45 | } 46 | -(void)addAction:(OnCustomView)onCustomView onAction:(OnCellAction)onAction 47 | { 48 | STCellAction *menu=[STCellAction new]; 49 | menu.onCustomView = onCustomView; 50 | menu.onAction = onAction; 51 | [self.items addObject:menu]; 52 | } 53 | -(void)dispose 54 | { 55 | if(self.items.count>0) 56 | { 57 | for (STCellAction *action in self.items) { 58 | [action dispose]; 59 | } 60 | [self.items removeAllObjects]; 61 | } 62 | _items=nil; 63 | } 64 | -(void)dealloc 65 | { 66 | [self dispose]; 67 | NSLog(@"%@ ->STUITableViewCellAction relase", [self class]); 68 | } 69 | @end 70 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUIViewValue.h: -------------------------------------------------------------------------------- 1 | // 2 | // STUIViewValue.h 3 | // STITLink 4 | // 5 | // Created by 陈裕强 on 2020/8/27. 6 | // Copyright © 2020 随天科技. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface UIView (STUIViewValue) 13 | 14 | //!根据UI类型不同而返回不同的属性值 15 | -(NSString*)stValue; 16 | //!为UI赋属性值 17 | -(UIView*)stValue:(NSString*)value; 18 | //!默认为下拉选择等做简化(扩展属性) 19 | -(NSString*)selectText; 20 | -(UIView*)selectText:(NSString*)text; 21 | //!默认为下拉选择等做简化(扩展属性) 22 | -(NSString*)selectValue; 23 | -(UIView*)selectValue:(NSString*)value; 24 | 25 | 26 | #pragma mark 共用接口 27 | //!重新加载数据(一般由子类重写,由于方法统一,在不同控制器中都可以直接调用,而不用搞代理事件) 28 | -(void)reloadData; 29 | //!重新加载数据(一般由子类重写,只是多了个参数,方便根据参数重新加载不同的数据) 30 | -(void)reloadData:(NSString*)para; 31 | 32 | //!将指定的数据批量赋值到所有的UI中:data可以是字典、是json,是实体等 33 | -(void)setToAll:(id)data; 34 | //!将指定的数据批量赋值到所有的UI中:data可以是字典、是json,是实体等 toChild:是否检测子控件并对子控件也批量赋值,默认NO。 35 | -(void)setToAll:(id)data toChild:(BOOL)toChild; 36 | //!从UIList中遍历获取属性isFormUI的表单数据列表 37 | -(NSMutableDictionary*)formData; 38 | //!从UIList中遍历获取属性isFormUI的表单数据列表 superView :指定一个父,不指定则为根视图 39 | -(NSMutableDictionary*)formData:(id)superView; 40 | 41 | #pragma mark 设置数据校验 42 | //!【表单设置】用于校验输入的必填、格式。(点击事件时被检测触发) 43 | -(UIView*)require:(BOOL)yesNo; 44 | -(UIView*)require:(BOOL)yesNo regex:(NSString*)regex; 45 | -(UIView*)require:(BOOL)yesNo regex:(NSString*)regex tipName:(NSString*)tipName; 46 | //!用于校验的分组触发(表单、按钮可设置)。 47 | -(UIView*)requireGroup:(NSString*)name; 48 | 49 | #pragma mark 触发数据校验[按钮] 50 | //!【按钮设置】点击事件设置是否触发验证。 51 | -(UIView*)requireBeforeClick:(BOOL)yesNo; 52 | //!【按钮设置】若需要将提示语显示在指定人UILabel中。 53 | -(UIView*)requireTipLabel:(id)nameOrLabel; 54 | //!触发验证。(内部点击触发) 55 | -(BOOL)exeRequire; 56 | @end 57 | 58 | -------------------------------------------------------------------------------- /Sagit/STBase/STNavController.m: -------------------------------------------------------------------------------- 1 | // 2 | // STNavController.m 3 | // 4 | // Created by 陈裕强 on 2020/9/12. 5 | // 6 | 7 | #import "STNavController.h" 8 | #import "STUIViewController.h" 9 | @implementation STNavController 10 | 11 | #pragma mark ios 13.6 不能用扩展属性 处理的。 12 | 13 | //!屏幕旋转 14 | -(UIInterfaceOrientationMask)supportedInterfaceOrientations 15 | { 16 | return [self.topViewController supportedInterfaceOrientations]; 17 | } 18 | //设置样式 19 | - (UIStatusBarStyle)preferredStatusBarStyle { 20 | return [self.topViewController preferredStatusBarStyle]; 21 | } 22 | #pragma mark NavigationBar 的协议,这里触发 23 | //- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPushItem:(UINavigationItem *)item { 24 | // //只有一个控制器的时候禁止手势,防止卡死现象 25 | // if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) { 26 | // self.interactivePopGestureRecognizer.enabled = NO; 27 | // } 28 | // if (self.childViewControllers.count > 1) { 29 | // if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) { 30 | // self.interactivePopGestureRecognizer.enabled = YES; 31 | // } 32 | // } 33 | // return YES; 34 | //} 35 | - (void)navigationBar:(UINavigationBar *)navigationBar didPopItem:(UINavigationItem *)item 36 | { 37 | NSInteger count=self.viewControllers.count; 38 | if(count>0) 39 | { 40 | //找到关键,忽略全屏点击事件 41 | UIViewController *current=self.viewControllers[count-1]; 42 | [current reSetBarState:YES]; 43 | } 44 | // //只有一个控制器的时候禁止手势,防止卡死现象 45 | // if (self.childViewControllers.count == 1) { 46 | // if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) { 47 | // self.interactivePopGestureRecognizer.enabled = NO; 48 | // } 49 | // } 50 | } 51 | 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /Sagit/STModel/STModelBase.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import "STModelBase.h" 10 | #import "STCategory.h" 11 | 12 | @implementation STModelBase 13 | -(NSMutableDictionary *)stKeyValue 14 | { 15 | if(_stKeyValue==nil) 16 | { 17 | _stKeyValue=[NSMutableDictionary new]; 18 | } 19 | return _stKeyValue; 20 | } 21 | -(BOOL)isIgnoreCase 22 | { 23 | return YES; 24 | } 25 | -(BOOL)isIgnore:(NSString *)name 26 | { 27 | if([name isEqualToString:@"stKeyValue"]) 28 | { 29 | return YES; 30 | } 31 | return NO; 32 | } 33 | -(id)init 34 | { 35 | return self; 36 | } 37 | -(id)initWithObject:(id)msg 38 | { 39 | return [self initWithDictionary:(NSDictionary*)msg]; 40 | } 41 | -(id)initWithDictionary:(NSDictionary *)dic 42 | { 43 | self=[self init]; 44 | [NSDictionary dictionaryToEntity:dic to:self]; 45 | return self; 46 | } 47 | -(NSDictionary *)toDictionary{ 48 | NSDictionary *dic=[NSMutableDictionary initWithJsonOrEntity:self]; 49 | return dic; 50 | } 51 | -(NSString *)toJson 52 | { 53 | return [[self toDictionary] toJson]; 54 | } 55 | +(NSArray* )toArrayEntityFrom:(NSArray*)array 56 | { 57 | if(array==nil || array.count==0) 58 | { 59 | return nil; 60 | } 61 | NSMutableArray *returnArray=[NSMutableArray new]; 62 | //NSString *name=NSStringFromClass([self class]); 63 | for (int i=0; i 10 | #import 11 | #import 12 | 13 | 14 | typedef enum : NSInteger { 15 | NotReachable = 0, 16 | ReachableViaWiFi, 17 | ReachableViaWWAN 18 | } NetworkStatus; 19 | 20 | #pragma mark IPv6 Support 21 | //Reachability fully support IPv6. For full details, see ReadMe.md. 22 | 23 | 24 | extern NSString *kReachabilityChangedNotification; 25 | 26 | 27 | @interface Reachability : NSObject 28 | 29 | /*! 30 | * Use to check the reachability of a given host name. 31 | */ 32 | + (instancetype)reachabilityWithHostName:(NSString *)hostName; 33 | 34 | /*! 35 | * Use to check the reachability of a given IP address. 36 | */ 37 | + (instancetype)reachabilityWithAddress:(const struct sockaddr *)hostAddress; 38 | 39 | /*! 40 | * Checks whether the default route is available. Should be used by applications that do not connect to a particular host. 41 | */ 42 | + (instancetype)reachabilityForInternetConnection; 43 | 44 | 45 | #pragma mark reachabilityForLocalWiFi 46 | //reachabilityForLocalWiFi has been removed from the sample. See ReadMe.md for more information. 47 | //+ (instancetype)reachabilityForLocalWiFi; 48 | 49 | /*! 50 | * Start listening for reachability notifications on the current run loop. 51 | */ 52 | - (BOOL)startNotifier; 53 | - (void)stopNotifier; 54 | 55 | - (NetworkStatus)currentReachabilityStatus; 56 | 57 | /*! 58 | * WWAN may be available, but not active until a connection has been established. WiFi may require a connection for VPN on Demand. 59 | */ 60 | - (BOOL)connectionRequired; 61 | 62 | @end 63 | 64 | 65 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUIViewAs.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import "STUIViewAs.h" 10 | #import "STCategory.h" 11 | 12 | @implementation UIView(STUIViewAs) 13 | -(UISwitch*)asSwitch 14 | { 15 | return (UISwitch*)self; 16 | } 17 | -(UIStepper*)asStepper 18 | { 19 | return (UIStepper*)self; 20 | } 21 | -(UIProgressView*)asProgressView 22 | { 23 | return (UIProgressView*)self; 24 | } 25 | -(UILabel*)asLabel 26 | { 27 | return (UILabel*)self; 28 | } 29 | -(UIImageView*)asImageView 30 | { 31 | return (UIImageView*)self; 32 | } 33 | -(UITextField*)asTextField 34 | { 35 | return (UITextField*)self; 36 | } 37 | -(UITextView*)asTextView 38 | { 39 | return (UITextView*)self; 40 | } 41 | -(UIButton*)asButton 42 | { 43 | return (UIButton*)self; 44 | } 45 | -(UIScrollView*)asScrollView 46 | { 47 | return (UIScrollView*)self; 48 | } 49 | -(UITableView*)asTableView 50 | { 51 | return (UITableView*)self; 52 | } 53 | -(UICollectionView*)asCollectionView 54 | { 55 | return (UICollectionView*)self; 56 | } 57 | -(UIPickerView*)asPickerView 58 | { 59 | return (UICollectionView*)self; 60 | } 61 | -(STView *)asSTView 62 | { 63 | return (STView*)self; 64 | } 65 | -(UIView *)asBaseView 66 | { 67 | [self key:@"isBaseView" value:@"1"]; 68 | return self; 69 | } 70 | -(UIImage *)asImage 71 | { 72 | // 下面方法,第一个参数表示区域大小。第二个参数表示是否是非透明的。如果需要显示半透明效果,需要传NO,否则传YES。第三个参数就是屏幕密度了,关键就是第三个参数 [UIScreen mainScreen].scale。 73 | UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0.0); 74 | [self.layer renderInContext:UIGraphicsGetCurrentContext()]; 75 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 76 | UIGraphicsEndImageContext(); 77 | return image; 78 | } 79 | @end 80 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUICollectionViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import "STUICollectionViewCell.h" 10 | #import "STUIView.h" 11 | @implementation UICollectionViewCell(ST) 12 | 13 | +(instancetype)reuseCell:(UICollectionView *)tableView index:(NSIndexPath *)index 14 | { 15 | UICollectionViewCell *cell=[tableView dequeueReusableCellWithReuseIdentifier:@"UICollectionViewCell" forIndexPath:index]; 16 | if(cell==nil) 17 | { 18 | cell=[UICollectionViewCell new]; 19 | [cell key:@"table" valueWeak:tableView]; 20 | [cell key:@"stView" valueWeak:tableView.stView]; 21 | [cell key:@"baseView" valueWeak:tableView.baseView]; 22 | } 23 | return cell; 24 | } 25 | -(UICollectionView *)table 26 | { 27 | return [self key:@"table"]; 28 | } 29 | -(NSMutableDictionary *)source 30 | { 31 | return [self key:@"source"]; 32 | } 33 | -(void)setSource:(NSMutableDictionary *)source 34 | { 35 | [self source:source]; 36 | } 37 | -(UICollectionViewCell*)source:(NSMutableDictionary *)dataSource 38 | { 39 | [self key:@"source" value:dataSource]; 40 | return self; 41 | } 42 | //-(BOOL)allowDelete 43 | //{ 44 | // if([self key:@"allowDelete"]==nil) 45 | // { 46 | // return self.table.allowDelete; 47 | // } 48 | // return [[self key:@"allowDelete"] isEqualToString:@"1"]; 49 | //} 50 | //-(UITableView *)allowDelete:(BOOL)yesNo 51 | //{ 52 | // [self key:@"allowDelete" value:yesNo?@"1":@"0"]; 53 | // return self; 54 | //} 55 | -(NSString *)firstValue 56 | { 57 | return [self key:@"firstValue"]; 58 | } 59 | -(UICollectionViewCell *)firstValue:(NSString *)value 60 | { 61 | [self key:@"firstValue" value:value]; 62 | return self; 63 | } 64 | @end 65 | -------------------------------------------------------------------------------- /Sagit/STTool/Tool/LocationConverter.h: -------------------------------------------------------------------------------- 1 | // 2 | // LocationConverter.h 3 | // 4 | #import 5 | #import 6 | @interface LocationConverter : NSObject 7 | 8 | /** 9 | * @brief 世界标准地理坐标(WGS-84) 转换成 中国国测局地理坐标(GCJ-02)<火星坐标> 10 | * 11 | * ####只在中国大陆的范围的坐标有效,以外直接返回世界标准坐标 12 | * 13 | * @param location 世界标准地理坐标(WGS-84) 14 | * 15 | * @return 中国国测局地理坐标(GCJ-02)<火星坐标> 16 | */ 17 | + (CLLocationCoordinate2D)wgs84ToGcj02:(CLLocationCoordinate2D)location; 18 | 19 | 20 | /** 21 | * @brief 中国国测局地理坐标(GCJ-02) 转换成 世界标准地理坐标(WGS-84) 22 | * 23 | * ####此接口有1-2米左右的误差,需要精确定位情景慎用 24 | * 25 | * @param location 中国国测局地理坐标(GCJ-02) 26 | * 27 | * @return 世界标准地理坐标(WGS-84) 28 | */ 29 | + (CLLocationCoordinate2D)gcj02ToWgs84:(CLLocationCoordinate2D)location; 30 | 31 | 32 | /** 33 | * @brief 世界标准地理坐标(WGS-84) 转换成 百度地理坐标(BD-09) 34 | * 35 | * @param location 世界标准地理坐标(WGS-84) 36 | * 37 | * @return 百度地理坐标(BD-09) 38 | */ 39 | + (CLLocationCoordinate2D)wgs84ToBd09:(CLLocationCoordinate2D)location; 40 | 41 | 42 | /** 43 | * @brief 中国国测局地理坐标(GCJ-02)<火星坐标> 转换成 百度地理坐标(BD-09) 44 | * 45 | * @param location 中国国测局地理坐标(GCJ-02)<火星坐标> 46 | * 47 | * @return 百度地理坐标(BD-09) 48 | */ 49 | + (CLLocationCoordinate2D)gcj02ToBd09:(CLLocationCoordinate2D)location; 50 | 51 | 52 | /** 53 | * @brief 百度地理坐标(BD-09) 转换成 中国国测局地理坐标(GCJ-02)<火星坐标> 54 | * 55 | * @param location 百度地理坐标(BD-09) 56 | * 57 | * @return 中国国测局地理坐标(GCJ-02)<火星坐标> 58 | */ 59 | + (CLLocationCoordinate2D)bd09ToGcj02:(CLLocationCoordinate2D)location; 60 | 61 | 62 | /** 63 | * @brief 百度地理坐标(BD-09) 转换成 世界标准地理坐标(WGS-84) 64 | * 65 | * ####此接口有1-2米左右的误差,需要精确定位情景慎用 66 | * 67 | * @param location 百度地理坐标(BD-09) 68 | * 69 | * @return 世界标准地理坐标(WGS-84) 70 | */ 71 | + (CLLocationCoordinate2D)bd09ToWgs84:(CLLocationCoordinate2D)location; 72 | 73 | 74 | @end 75 | -------------------------------------------------------------------------------- /Sagit/STBase/STView.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | #import "STCategory.h" 9 | #import "STView.h" 10 | #import "STLayoutTracer.h" 11 | #import "STDefineUI.h" 12 | #import "STModelBase.h" 13 | //#import 14 | 15 | @implementation STView 16 | 17 | -(instancetype)init 18 | { 19 | self = [super init]; 20 | self.frame=STFullRect;//页面加载完后,IOS系统会根据导航状态栏等情况修改坐标和高度 21 | self.backgroundColor=ColorDevice;//卡的问题 22 | return self; 23 | } 24 | 25 | - (instancetype)initWithController:(STController*)controller 26 | { 27 | self=[self init]; 28 | if (controller) { 29 | self.Controller=controller; 30 | } 31 | return self; 32 | } 33 | 34 | 35 | //初始化[子类重写该方法] 36 | -(void)initUI 37 | { 38 | 39 | } 40 | -(void)initData 41 | { 42 | //触发子控件事件 43 | for (NSString *key in self.UIList.keys) 44 | { 45 | STView*view=[self.UIList get:key]; 46 | if([view isKindOfClass:[STView class]]) 47 | { 48 | [view initData]; 49 | } 50 | } 51 | } 52 | -(void)reloadData 53 | { 54 | //触发子控件事件 55 | for (NSString *key in self.UIList.keys) 56 | { 57 | STView*view=[self.UIList get:key]; 58 | if([view isKindOfClass:[STView class]]) 59 | { 60 | [view reloadData]; 61 | } 62 | } 63 | } 64 | 65 | 66 | ////延时加载 67 | //-(NSMutableDictionary*)UIList 68 | //{ 69 | // return [super.baseView key:@"UIList"]; 70 | //} 71 | //-(NSMutableArray*)UITextList 72 | //{ 73 | // if(_UITextList==nil) 74 | // { 75 | // _UITextList=[NSMutableArray new]; 76 | // } 77 | // return _UITextList; 78 | //} 79 | 80 | 81 | -(void)dealloc{ 82 | //[[NSNotificationCenter defaultCenter] removeObserver:self];//在视图控制器消除时,移除键盘事件的通知 83 | 84 | NSLog(@"STView relase -> %@",[self class]); 85 | } 86 | @end 87 | 88 | -------------------------------------------------------------------------------- /Sagit/STTool/STSagit.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | 7 | #import "Sagit.h" 8 | #import "STDefine.h" 9 | #import "STSagit.h" 10 | @implementation Sagit 11 | //+(instancetype)share 12 | //{ 13 | // static Sagit *_share = nil; 14 | // static dispatch_once_t onceToken; 15 | // dispatch_once(&onceToken, ^{ 16 | // _share = [Sagit new]; 17 | // }); 18 | // return _share; 19 | //} 20 | +(STDefine *)Define 21 | { 22 | return [STDefine share]; 23 | } 24 | +(STFile *)File 25 | { 26 | return [STFile share]; 27 | } 28 | +(STCache *)Cache 29 | { 30 | return [STCache share]; 31 | } 32 | +(STHttp *)Http 33 | { 34 | return [STHttp share]; 35 | } 36 | +(STMsgBox *)MsgBox 37 | { 38 | return [STMsgBox share]; 39 | } 40 | +(STLocation *)Location 41 | { 42 | return [STLocation share]; 43 | } 44 | #pragma mark 扩展一些全局的方法 45 | +(void)delayExecute:(double)second onMainThread:(BOOL)onMainThread block:(DelayExecuteBlock)block 46 | { 47 | if(!block){return;} 48 | 49 | dispatch_async(dispatch_get_global_queue(0, 0), ^{ 50 | if(second>0) 51 | { 52 | [NSThread sleepForTimeInterval:second]; 53 | } 54 | __block DelayExecuteBlock exeBlock=block; 55 | if(onMainThread && !NSThread.isMainThread) 56 | { 57 | dispatch_sync(dispatch_get_main_queue(), ^{ 58 | exeBlock(); 59 | exeBlock=nil; 60 | }); 61 | } 62 | else 63 | { 64 | exeBlock(); 65 | exeBlock=nil; 66 | } 67 | }); 68 | } 69 | +(void)runOnMainThread:(DelayExecuteBlock)block 70 | { 71 | if(!block){return;} 72 | __block DelayExecuteBlock exeBlock=block; 73 | if([NSThread isMainThread]){exeBlock();exeBlock=nil;return;} 74 | dispatch_sync(dispatch_get_main_queue(), ^{ 75 | exeBlock(); 76 | exeBlock=nil; 77 | }); 78 | } 79 | @end 80 | -------------------------------------------------------------------------------- /Sagit/Category/Object/STColor.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // Copyright © 2017-2027年. All rights reserved. 6 | // 7 | #import "STColor.h" 8 | 9 | @implementation UIColor (ST) 10 | 11 | + (UIColor *)hex:(NSString *)hexColor { 12 | NSString *cString = [[hexColor stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString]; 13 | 14 | // String should be 6 or 8 characters 15 | if ([cString length] < 6) { 16 | return [UIColor clearColor]; 17 | } 18 | 19 | // 判断前缀并剪切掉 20 | if ([cString hasPrefix:@"0X"]) 21 | cString = [cString substringFromIndex:2]; 22 | if ([cString hasPrefix:@"#"]) 23 | cString = [cString substringFromIndex:1]; 24 | if ([cString length] != 6) 25 | return [UIColor clearColor]; 26 | 27 | // 从六位数值中找到RGB对应的位数并转换 28 | NSRange range; 29 | range.location = 0; 30 | range.length = 2; 31 | 32 | //R、G、B 33 | NSString *rString = [cString substringWithRange:range]; 34 | 35 | range.location = 2; 36 | NSString *gString = [cString substringWithRange:range]; 37 | 38 | range.location = 4; 39 | NSString *bString = [cString substringWithRange:range]; 40 | 41 | // Scan values 42 | unsigned int r, g, b; 43 | [[NSScanner scannerWithString:rString] scanHexInt:&r]; 44 | [[NSScanner scannerWithString:gString] scanHexInt:&g]; 45 | [[NSScanner scannerWithString:bString] scanHexInt:&b]; 46 | 47 | return [UIColor colorWithRed:((float) r / 255.0f) green:((float) g / 255.0f) blue:((float) b / 255.0f) alpha:1.0f]; 48 | } 49 | +(UIColor *)toColor:(id)hexOrColor 50 | { 51 | if([hexOrColor isKindOfClass:([NSString class])]) 52 | { 53 | return [UIColor hex:hexOrColor]; 54 | } 55 | return hexOrColor; 56 | } 57 | -(UIColor*)alpha:(CGFloat)value 58 | { 59 | return [self colorWithAlphaComponent:value]; 60 | } 61 | @end 62 | -------------------------------------------------------------------------------- /Sagit/STModel/Common/STLayoutTracer.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import "STLayoutTracer.h" 10 | #import "STCategory.h" 11 | @implementation STLayoutTracer 12 | -(BOOL)hasRelateTop 13 | { 14 | NSString *relate=[@(self.location) stringValue]; 15 | return [relate contains:@"2"]; 16 | } 17 | -(BOOL)hasRelateLeft 18 | { 19 | NSString *relate=[@(self.location) stringValue]; 20 | return [relate contains:@"1"]; 21 | } 22 | -(BOOL)hasRelateRight 23 | { 24 | NSString *relate=[@(self.location) stringValue]; 25 | return [relate contains:@"3"]; 26 | } 27 | -(BOOL)hasRelateBottom 28 | { 29 | NSString *relate=[@(self.location) stringValue]; 30 | return [relate contains:@"4"]; 31 | } 32 | -(CGFloat)relateTopPx 33 | { 34 | return [self relatePx:Top]; 35 | } 36 | -(CGFloat)relateLeftPx 37 | { 38 | return [self relatePx:Left]; 39 | } 40 | -(CGFloat)relateRightPx 41 | { 42 | return [self relatePx:Right]; 43 | } 44 | -(CGFloat)relateBottomPx 45 | { 46 | return [self relatePx:Bottom]; 47 | } 48 | -(CGFloat)relatePx:(XYLocation)location 49 | { 50 | NSString *relate=[@(self.location) stringValue]; 51 | if(relate) 52 | { 53 | NSInteger index=-1; 54 | switch (location) { 55 | case Top: 56 | index=[relate indexOf:@"2"]; 57 | break; 58 | case Left: 59 | index=[relate indexOf:@"1"]; 60 | break; 61 | case Right: 62 | index=[relate indexOf:@"3"]; 63 | break; 64 | case Bottom: 65 | index=[relate indexOf:@"4"]; 66 | break; 67 | default: 68 | break; 69 | } 70 | if(index==0){return self.v1;} 71 | if(index==1){return self.v2;} 72 | if(index==2){return self.v3;} 73 | if(index==3){return self.v4;} 74 | } 75 | return 0; 76 | } 77 | @end 78 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUINavigationBar.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import "STUINavigationBar.h" 10 | #import "STDefineUI.h" 11 | #import "STUIView.h" 12 | #import "STCategory.h" 13 | @implementation UINavigationBar (ST) 14 | 15 | +(UINavigationBarSetting*)globalSetting 16 | { 17 | return [UINavigationBarSetting new]; 18 | } 19 | @end 20 | 21 | @implementation UINavigationBarSetting 22 | #pragma mark 扩展系统属性 23 | -(UINavigationBarSetting*)tintColor:(id)colorOrHex 24 | { 25 | [UINavigationBar appearance].tintColor=[UIColor toColor:(colorOrHex)]; 26 | return self; 27 | } 28 | -(UINavigationBarSetting*)barTintColor:(id)colorOrHex 29 | { 30 | [UINavigationBar appearance].barTintColor=[UIColor toColor:(colorOrHex)]; 31 | return self; 32 | } 33 | -(UINavigationBarSetting*)backgroundImage:(id)img 34 | { 35 | return [self backgroundImage:img stretch:NO]; 36 | } 37 | -(UINavigationBarSetting*)backgroundImage:(id)img stretch:(BOOL)stretch 38 | { 39 | UIImage *uiImg=nil; 40 | if(img==nil) 41 | { 42 | uiImg=[UIImage new]; 43 | } 44 | else 45 | { 46 | uiImg=[UIImage toImage:img]; 47 | } 48 | if(stretch) 49 | { 50 | uiImg=[uiImg resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0) resizingMode:UIImageResizingModeStretch]; 51 | } 52 | [[UINavigationBar appearance] setBackgroundImage:uiImg forBarMetrics:UIBarMetricsDefault]; 53 | return self; 54 | } 55 | -(UINavigationBarSetting*)shadowImage:(id)img 56 | { 57 | if(img==nil) 58 | { 59 | [[UINavigationBar appearance] setShadowImage: [[UIImage alloc] init]]; 60 | } 61 | else{[[UINavigationBar appearance] setShadowImage:[UIImage toImage:img]];} 62 | return self; 63 | } 64 | -(UINavigationBarSetting*)titleTextAttributes:(NSDictionary *)dic 65 | { 66 | [[UINavigationBar appearance] setTitleTextAttributes:dic]; 67 | return self; 68 | } 69 | -(UINavigationBarSetting*)translucent:(BOOL)yesNo 70 | { 71 | [UINavigationBar appearance].translucent=yesNo; 72 | return self; 73 | } 74 | @end 75 | -------------------------------------------------------------------------------- /Sagit/STTool/Common/STHttp.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "STHttpModel.h" 11 | #import "STMsgBox.h" 12 | 13 | typedef void(^OnSuccess)(STHttpModel *result); 14 | typedef void(^OnError)(NSString *errMsg); 15 | typedef void(^OnBefore)(NSMutableURLRequest *request); 16 | 17 | //!提供基础的网络请求(get、post、upload(图片上传)) 18 | @interface STHttp : NSObject 19 | //!消息弹窗。 20 | @property (nonatomic,strong) STMsgBox *msgBox; 21 | //!请求的默认编码:默认Utf8 22 | @property (nonatomic,assign) NSStringEncoding defautEncoding; 23 | 24 | - (instancetype)init:(STMsgBox*)msgBox; 25 | + (STHttp*)share; 26 | #pragma mark 调用方法 27 | - (void)get:(NSString *)url paras:(NSDictionary *)paras success:(OnSuccess)succese; 28 | - (void)get:(NSString *)url paras:(NSDictionary *)paras success:(OnSuccess)success error:(OnError)error; 29 | - (void)get:(NSString *)url paras:(NSDictionary *)paras before:(OnBefore)before success:(OnSuccess)success; 30 | - (void)get:(NSString *)url paras:(NSDictionary *)paras before:(OnBefore)before success:(OnSuccess)success error:(OnError)error; 31 | 32 | - (void)post:(NSString *)url paras:(NSDictionary *)paras success:(OnSuccess)success; 33 | - (void)post:(NSString *)url paras:(NSDictionary *)paras success:(OnSuccess)success error:(OnError)error; 34 | - (void)post:(NSString *)url paras:(NSDictionary *)paras before:(OnBefore)before success:(OnSuccess)success; 35 | - (void)post:(NSString *)url paras:(NSDictionary *)paras before:(OnBefore)before success:(OnSuccess)success error:(OnError)error; 36 | 37 | - (void)upload:(NSString *)url paras:(id)dicOrNSData success:(OnSuccess)success; 38 | - (void)upload:(NSString *)url paras:(id)dicOrNSData success:(OnSuccess)success error:(OnError)error; 39 | - (void)upload:(NSString *)url paras:(id)dicOrNSData before:(OnBefore)before success:(OnSuccess)success; 40 | - (void)upload:(NSString *)url paras:(id)dicOrNSData before:(OnBefore)before success:(OnSuccess)success error:(OnError)error; 41 | 42 | #pragma mark 全局可覆盖方法 43 | //可以扩展此方法,以便增加初始的请求头。 44 | -(BOOL)globalBeforeSuccess:(STHttpModel*)model; 45 | -(BOOL)globalBeforeError:(NSString*)errorMsg; 46 | //!全局追加默认请求头(覆盖方法) 47 | -(void)globalHeader:(NSMutableURLRequest*)request; 48 | //!全局修改默认请求URL(覆盖方法) 49 | -(NSString*)globalSetUrl:(NSString*)url; 50 | @end 51 | -------------------------------------------------------------------------------- /Sagit/STTool/Common/STMsgBox.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "STCategory.h" 12 | #import "STDefineUI.h" 13 | typedef void (^OnConfirmClick)(NSInteger btnIndex,UIAlertController* alertController); 14 | typedef BOOL (^OnInputClick)(NSInteger btnIndex,UIAlertController* alertController); 15 | typedef void (^OnMenuClick)(NSInteger btnIndex,UIAlertController* alertController); 16 | typedef BOOL (^OnBeforeDialogHide)(UIView* winView,UIView* clickView); 17 | typedef void (^OnBeforeShow)(UIAlertController* alertController); 18 | typedef void (^OnDialogShow)(UIView* winView); 19 | //!提供基础的消息弹窗 20 | @interface STMsgBox : NSObject 21 | + (STMsgBox*)share; 22 | //!dialog 状态。 23 | @property (nonatomic,assign) BOOL isDialoging; 24 | //!dialog 控制器(内部使用) 25 | @property (nonatomic,strong) STController *dialogController; 26 | //!alert 控制器(内部使用) 27 | @property (nonatomic,retain) STQueue *alertQueue; 28 | //!dialog 控制器(内部使用) 29 | @property (nonatomic,retain) STStack *dialogStack; 30 | #pragma AlertView 31 | //!提示消息 32 | -(void)prompt:(id)msg; 33 | -(void)prompt:(id)msg second:(NSInteger)second; 34 | //!弹出需要点击确定的消息框 35 | -(void)alert:(id)msg; 36 | -(void)alert:(id)msg title:(NSString*)title; 37 | -(void)alert:(id)msg title:(NSString *)title okText:(NSString*)okText; 38 | -(void)loading; 39 | -(void)loading:(id)text; 40 | -(void)hideLoading; 41 | //!弹出需要确认,并可执行事件的消息框。 42 | -(void)confirm:(id)msg title:(NSString*)title click:(OnConfirmClick)click; 43 | -(void)confirm:(id)msg title:(NSString *)title click:(OnConfirmClick)click okText:(NSString*)okText; 44 | -(void)confirm:(id)msg title:(NSString *)title click:(OnConfirmClick)click okText:(NSString*)okText cancelText:(NSString*)cancelText; 45 | //!弹出一个可以(自定义)输入内容的对话框 46 | -(void)input:(id)title before:(OnBeforeShow)beforeShow click:(OnInputClick)click okText:(NSString*)okText cancelText:(NSString*)cancelText; 47 | //!弹出底部菜单 48 | -(void)menu:(id)msg title:(NSString*)title click:(OnMenuClick)click names:(id)names,...NS_REQUIRES_NIL_TERMINATION; 49 | //!弹出底部菜单 50 | -(void)menu:(OnMenuClick)click names:(id)names,...NS_REQUIRES_NIL_TERMINATION; 51 | //!弹出自定义界面的对话框 52 | - (void)dialog:(OnDialogShow)dialog; 53 | - (void)dialog:(OnDialogShow)dialog beforeHide:(OnBeforeDialogHide) beforeHide; 54 | //!手动触发关闭所有对话框(包含嵌套) 55 | - (void)dialogClose; 56 | //!手动触发关闭指定对话框(嵌套时可能有多个) 57 | - (void)dialogClose:(UIView*)winView; 58 | @end 59 | -------------------------------------------------------------------------------- /Sagit/Category/Object/STNSMapTable.m: -------------------------------------------------------------------------------- 1 | // 2 | // STNSMapTable.m 3 | // 4 | // Created by 陈裕强 on 2020/8/18. 5 | // Copyright © 2020 . All rights reserved. 6 | // 7 | 8 | #import "STNSMapTable.h" 9 | #import "STCategory.h" 10 | #pragma mark NSMapTable(ST) 11 | @implementation NSMapTable(ST) 12 | 13 | -(id)get:(NSString*)key 14 | { 15 | return [self objectForKey:key]; 16 | } 17 | -(BOOL)has:(NSString*)key 18 | { 19 | return [self objectForKey:key]!=nil; 20 | } 21 | -(void)set:(NSString*)key value:(id)value 22 | { 23 | if(value!=nil) 24 | { 25 | [self setObject:value forKey:key]; 26 | } 27 | else 28 | { 29 | [self remove:key]; 30 | } 31 | } 32 | 33 | -(void)remove:(NSString*)key 34 | { 35 | NSArray *items=[key split:@","]; 36 | for (NSString* item in items) 37 | { 38 | [self removeObjectForKey:item]; 39 | } 40 | 41 | } 42 | @end 43 | 44 | 45 | #pragma mark STMapTable 46 | @implementation STMapTable 47 | 48 | -(instancetype)init 49 | { 50 | _keys=[NSMutableArray new]; 51 | _mapTable=[NSMapTable mapTableWithKeyOptions:NSPointerFunctionsStrongMemory valueOptions:NSPointerFunctionsStrongMemory]; 52 | return self; 53 | } 54 | - (NSMutableArray *)keys 55 | { 56 | return _keys; 57 | } 58 | -(NSMapTable *)mapTable 59 | { 60 | return _mapTable;; 61 | } 62 | -(id)get:(NSString*)key 63 | { 64 | return [self.mapTable objectForKey:key]; 65 | } 66 | -(id)getWithIgnoreCase:(NSString *)key 67 | { 68 | id v=[self get:key]; 69 | if(v!=nil) 70 | { 71 | return v; 72 | } 73 | NSString *lowerKey=[key toLower]; 74 | for (NSString* k in self.keys) { 75 | if([lowerKey isEqual:[k toLower]]) 76 | { 77 | return [self get:k]; 78 | } 79 | } 80 | return nil; 81 | } 82 | -(BOOL)has:(NSString*)key 83 | { 84 | return [self.mapTable objectForKey:key]!=nil; 85 | } 86 | -(void)set:(NSString*)key value:(id)value 87 | { 88 | if(value!=nil) 89 | { 90 | if(![self has:key]) 91 | { 92 | [self.keys addObject:key]; 93 | } 94 | [self.mapTable setObject:value forKey:key]; 95 | } 96 | else 97 | { 98 | [self remove:key]; 99 | } 100 | } 101 | 102 | -(void)remove:(NSString*)key 103 | { 104 | NSArray *items=[key split:@","]; 105 | for (NSString* item in items) 106 | { 107 | [self.mapTable removeObjectForKey:item]; 108 | [self.keys removeObject:item]; 109 | } 110 | 111 | } 112 | @end 113 | 114 | 115 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUIView.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | #import "STView.h" 13 | 14 | @class STController; 15 | @class STView; 16 | 17 | @interface UIView(ST) 18 | //!获取当前UI的STController,如果当前UI的控制器没有继承自STController,则返回nil 19 | -(STController*)stController; 20 | //!获取当前UI的STView,如果当前UI的根视图没有继承自STView,则返回nil 21 | -(STView*)stView; 22 | //!获取当前应用的状态栏 23 | -(UIView*)statusBar; 24 | //!获取当前UI的根控制器UIViewController 25 | //-(UIViewController*)baseController; 26 | //!获取当前UI的根视图,如果当前的UI没有根视图或根视图为UIWindow,则返回自身。 27 | -(UIView*)baseView; 28 | //! 29 | -(UIWindow*)keyWindow; 30 | //!检测当前UI是否STView 31 | -(BOOL)isSTView; 32 | //!检测当前UI的根视图是否继承自STView 33 | //-(BOOL)isOnSTView; 34 | //!为每个UI都扩展有一个name 35 | - (NSString*)name; 36 | //!为UI设置name 37 | - (UIView*)name:(NSString *)name; 38 | 39 | #pragma mark keyvalue 40 | //!一个强引用的字典属性,方便存档及数据传递 41 | -(NSMutableDictionary*)keyValue; 42 | //!扩展一个弱引用的字典属性,用于存档有可能造成双向循环的对象,避免死引用 43 | //-(NSMapTable*)keyValueWeak; 44 | //!从keyValue属性中获取字指定key的值 45 | -(id)key:(NSString*)key; 46 | //!为keyValue属性设置键与值 47 | -(UIView*)key:(NSString*)key value:(id)value; 48 | //当value不存在时,才允许赋值(保证该方法仅赋值一次) 49 | -(UIView*)key:(NSString *)key valueIfNil:(id)value; 50 | //!为keyValue属性设置键与值 其中value为弱引用 51 | -(UIView*)key:(NSString*)key valueWeak:(id)value; 52 | 53 | #pragma mark 扩展系统属性 54 | 55 | -(UIView*)hidden:(BOOL)yesNo; 56 | -(UIView*)backgroundColor:(id)colorOrHex; 57 | -(UIImage*)backgroundImage; 58 | -(UIView*)backgroundImage:(id)imgOrName; 59 | -(UIView*)clipsToBounds:(BOOL)value; 60 | -(UIView*)tag:(NSInteger)tag; 61 | -(UIView*)alpha:(CGFloat)value; 62 | //!将圆角半径设为宽度的一半 63 | -(UIView*)layerCornerRadiusToHalf; 64 | //!将圆角半径设为指定的值(px) 65 | -(UIView*)layerCornerRadius:(CGFloat)px; 66 | //!将圆角半径设为指定的值(px),byRoundingCorners:指定要圆角的边。多个用 | 符号。 67 | -(UIView*)layerCornerRadius:(CGFloat)px byRoundingCorners:(UIRectCorner)byRoundingCorners; 68 | -(UIView*)layerBorderWidth:(NSInteger)px; 69 | -(UIView*)layerBorderWidth:(NSInteger)px color:(id)colorOrHex; 70 | -(UIView*)layerBorderColor:(id)colorOrHex; 71 | -(UIView*)corner:(BOOL)yesNo; 72 | -(UIView*)contentMode:(UIViewContentMode)contentMode; 73 | -(UIView*)userInteractionEnabled:(BOOL)yesNO; 74 | //!克隆复制一份UIView 75 | -(UIView*)clone; 76 | #pragma mark 扩展系统方法 77 | -(UITextField*)bottomLine:(id)colorOrHex; 78 | -(UITextField*)bottomLine:(id)colorOrHex height:(NSInteger)px; 79 | //!框架自动释放资源(不需要人工调用) 80 | -(void)dispose; 81 | @end 82 | 83 | 84 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUITableView.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // Copyright © 2017-2027年. All rights reserved. 6 | // 7 | 8 | #import 9 | #import "STUITableViewCellAction.h" 10 | @interface UITableView(ST) 11 | 12 | #pragma mark 核心扩展 13 | typedef void(^OnAddTableCell)(UITableViewCell *cell,NSIndexPath *indexPath); 14 | typedef BOOL(^OnDelTableCell)(UITableViewCell *cell,NSIndexPath *indexPath); 15 | typedef void(^OnAddTableCellAction)(STUITableViewCellAction *cellAction, NSIndexPath *indexPath); 16 | typedef bool(^OnAddTableCellMove)(UITableView *tableView,NSIndexPath *sourceIndexPath,NSIndexPath *destinationIndexPath); 17 | typedef void(^OnAddTableSectionHeaderView)(UIView *sectionHeaderView,NSInteger section); 18 | typedef void(^OnAddTableSectionFooterView)(UIView *sectionFooterView,NSInteger section); 19 | typedef void(^OnAfterTableReloadData)(UITableView *tableView); 20 | //!用于为Table追加每一行的Cell 21 | @property (nonatomic,copy) OnAddTableCell addCell; 22 | //!用于为Table追加每一行的Cell的滑动菜单 23 | @property (nonatomic,copy) OnAddTableCellAction addCellAction; 24 | //!用于为Table追加每一行的拖动 25 | @property (nonatomic,copy) OnAddTableCellMove addCellMove; 26 | //!用于为Table追加每一组Section的标题View 27 | @property (nonatomic,copy) OnAddTableSectionHeaderView addSectionHeaderView; 28 | @property (nonatomic,copy) OnAddTableSectionFooterView addSectionFooterView; 29 | //!用于为Table移除行的Cell 30 | @property (nonatomic,copy) OnDelTableCell delCell; 31 | //!用于为Table reloadData 加载完数据后触发 32 | @property (nonatomic,copy) OnAfterTableReloadData afterReload; 33 | //!获取Table的数据源 34 | @property (nonatomic,strong) NSMutableArray *source; 35 | //!设置Table的数据源 36 | -(UITableView*)source:(NSMutableArray *)dataSource; 37 | //!存档所有Cell的高度(由系统控制)[存档格式为:section key,[row Array]] 38 | @property (readonly,nonatomic,retain) NSMutableDictionary *heightForCells; 39 | 40 | //!是否重用Cell(默认Yes) 41 | -(BOOL)reuseCell; 42 | -(BOOL)reuseCell:(BOOL)yesNo; 43 | //!是否自动控制Table的高度 44 | -(BOOL)autoHeight; 45 | //!设置是否自动控制Table的高度 46 | -(UITableView*)autoHeight:(BOOL)yesNo; 47 | //!获取默认的UITableViewCellStyle 48 | -(UITableViewCellStyle)cellStyle; 49 | //!设置默认的UITableViewCellStyle 50 | -(UITableView*)cellStyle:(UITableViewCellStyle)style; 51 | //!获取是否允许编辑【删除】属性 52 | -(BOOL)allowEdit; 53 | //!设置是否允许编辑【删除】 54 | -(UITableView*)allowEdit:(BOOL)yesNo; 55 | //!移除数据源和数据行(并重新计算且刷新高度) 56 | -(UITableView*)afterDelCell:(NSIndexPath*)indexPath; 57 | #pragma mark 扩展属性 58 | -(UITableView*)scrollEnabled:(BOOL)yesNo; 59 | //!分组数(默认1) 60 | -(UITableView*)sectionCount:(NSInteger)count; 61 | //!每个Section的num数:参数可以传递:@[@"1",@"2",@"2",@"1"] 或者:@"1,2,2,1" 62 | -(UITableView*)rowCountInSections:(id)nums; 63 | @end 64 | -------------------------------------------------------------------------------- /Sagit/STBase/STController.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | 7 | #import 8 | #import "STEnum.h" 9 | 10 | @class STView; 11 | @class STHttp; 12 | @class STMsgBox; 13 | 14 | @interface STController : UIViewController 15 | //!当前控制器的STView根视图 16 | @property (nonatomic,retain) STView* stView; 17 | //!用于发起http请求 18 | @property (nonatomic,retain) STHttp *http; 19 | //!用于弹窗提示消息 20 | @property (nonatomic,retain) STMsgBox *msgBox; 21 | 22 | #pragma mark 屏幕旋转 23 | //!屏幕旋转事件:【 return true 系统调用刷新布局([self.view refleshLayoutAfterRotate];);return false 用户自己手动控制】 @isEventRotate 是旋转屏幕、还是点击事件触发。 24 | typedef BOOL(^OnRotate)(NSNotification* notify,BOOL isEventRotate); 25 | //!屏幕旋转事件。 26 | @property (nonatomic,assign) OnRotate onDeviceRotate; 27 | //!设置当前视图支持的屏幕旋转方向 28 | -(void)setSupportedInterfaceOrientations:(UIInterfaceOrientationMask)orientation; 29 | ////!设置当前视图的屏幕显示方向(可设置默认的显示方向) 30 | //-(void)setInterfaceOrientation:(UIInterfaceOrientation)orientation; 31 | //!手动调用旋转屏幕。 32 | -(STController*)rotateOrientation:(UIInterfaceOrientation)direction; 33 | 34 | #pragma mark 通用的三个事件方法:onInit、initUI、initData(还有一个位于基类的:reloadData) 35 | //!事件在UI初始化之前执行【只执行1次】 36 | -(void)onInit; 37 | //!内部使用。 38 | -(void)initView; 39 | //!UI初始化【只执行1次】 40 | -(void)initUI; 41 | //!事件在UI初始化之后执行【只执行1次】 42 | -(void)initData; 43 | 44 | #pragma mark 系统的2个事件方法 45 | //呈现UI之前【执行N次】 46 | -(void)beforeViewAppear; 47 | //呈现UI之后【执行N次】 48 | -(void)afterViewAppear; 49 | //UI消失之前【执行N次】 50 | -(void)beforeViewDisappear; 51 | 52 | 53 | //!执行view的stValue属性 54 | -(NSString*)stValue:(NSString*)name; 55 | //!执行view的stValue属性 56 | -(void)stValue:(NSString*)name value:(NSString*)value; 57 | 58 | //!验证文本框的值是否填写或格式是否错误 根据ui的name进行处理 59 | -(BOOL)isMatch:(NSString*)tipMsg name:(NSString*)name; 60 | -(BOOL)isMatch:(NSString*)tipMsg name:(NSString*)name regex:(NSString*)pattern; 61 | -(BOOL)isMatch:(NSString*)tipMsg name:(NSString*)name regex:(NSString*)pattern require:(BOOL)yesNo; 62 | //!验证文本框的值是否填写或格式是否错误 根据已获取的value进行处理 63 | -(BOOL)isMatch:(NSString*)tipMsg value:(NSString*)value; 64 | -(BOOL)isMatch:(NSString*)tipMsg value:(NSString*)value regex:(NSString*)pattern; 65 | -(BOOL)isMatch:(NSString*)tipMsg value:(NSString*)value regex:(NSString*)pattern require:(BOOL)yesNo; 66 | //!根据指定的结果弹出消息。 67 | -(BOOL)isMatch:(NSString*)tipMsg isMatch:(BOOL)result; 68 | //!指向view的setToAll:将指定的数据批量赋值到所有的UI中:data可以是字典、是json,是实体等 69 | -(void)setToAll:(id)data; 70 | //!指向view的formData: 从UIList中遍历获取属性isFormUI的表单数据列表 71 | -(NSMutableDictionary*)formData; 72 | //!指向view的formData: 从UIList中遍历获取属性isFormUI的表单数据列表 superView :指定一个父,不指定则为根视图 73 | -(NSMutableDictionary*)formData:(id)superView; 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUIImageView.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIImageView(ST) 12 | 13 | typedef void (^OnImageCrop)(UIImage *image); 14 | typedef void (^OnPick)(NSData *data,UIImagePickerController *picker,NSDictionary *info); 15 | //typedef void (^AfterSetImageUrl)(UIImageView* img); 16 | //!长按时提示用户保存图片 17 | -(UIImageView*)longPressSave:(BOOL)yesNo; 18 | //!执行保存图片事件 19 | -(void)save; 20 | //!设置图片是否圆角 21 | -(UIImageView*)corner:(BOOL)yesNo; 22 | //!获取图片的地址 23 | -(NSString*)url; 24 | //!为图片设置一个网络地址 (默认超过256K时会进行压缩) 25 | -(UIImageView*)url:(NSString*)url; 26 | //!为图片设置一个网络地址 (默认超过256K时会进行压缩)afterSet为设置后的回调函数 27 | //-(UIImageView *)url:(NSString *)url after:(AfterSetImageUrl)block; 28 | //!为图片设置一个网络地址 (默认超过256K时会进行压缩)default:设置一张默认图片 29 | -(UIImageView *)url:(NSString *)url default:(id)imgOrName; 30 | //!为图片设置一个网络地址 maxKb 指定超过大小时压缩显示(设置为0不压缩) 31 | //-(UIImageView *)url:(NSString *)url maxKb:(NSInteger)compress; 32 | //!为图片设置一个网络地址 (默认超过256K时会进行压缩) maxKb 指定超过大小时压缩显示(设置为0不压缩) default:设置一张默认图片 33 | -(UIImageView *)url:(NSString *)url default:(id)imgOrName maxKb:(NSInteger)compress; 34 | //!为图片设置一个网络地址 (默认超过256K时会进行压缩) maxKb 指定超过大小时压缩显示(设置为0不压缩) default:设置一张默认图片 afterSet为设置后的回调函数 35 | //-(UIImageView *)url:(NSString *)url maxKb:(NSInteger)compress default:(id)imgOrName after:(AfterSetImageUrl)block; 36 | //!图片选择 edit:是否出现裁剪框 37 | -(UIImageView*)pick:(OnPick)pick edit:(BOOL)yesNo; 38 | //!图片选择 edit:是否出现裁剪框 maxKb:指定压缩的大小 39 | -(UIImageView*)pick:(OnPick)pick edit:(BOOL)yesNo maxKb:(NSInteger)maxKb; 40 | //!图片选择 edit:是否出现裁剪框 maxKb:指定压缩的大小, scaleSize 定义裁剪大小比例 41 | -(UIImageView*)pick:(OnPick)pick edit:(BOOL)yesNo maxKb:(NSInteger)maxKb scaleSize:(CGSize)scaleSize; 42 | //!图片选择 edit:是否出现裁剪框 maxKb:指定压缩的大小 scaleSize 定义裁剪大小比例 editScaleSize 编辑缩放大小 43 | -(UIImageView*)pick:(OnPick)pick edit:(BOOL)yesNo maxKb:(NSInteger)maxKb scaleSize:(CGSize)scaleSize editScaleSize:(BOOL)editScaleSize; 44 | //!将图片压缩到指定的宽高,当前图片受变化 45 | -(UIImageView*)reSize:(CGSize)maxSize; 46 | #pragma mark 扩展属性 47 | //!获取图片的名称 48 | -(NSString*)imageName; 49 | -(UIImageView*)image:(id)imgOrName; 50 | #pragma mark 浏览查看大图、(去掉第3方图片查看) 51 | //!双击切换放大查看 52 | -(void)zoom; 53 | -(UIImageView *)zoom:(BOOL)yesNo; 54 | //!点击发大查看 55 | -(void)show; 56 | -(UIImageView *)show:(BOOL)yesNo; 57 | +(void)show:(NSInteger)startIndex images:(id)imgOrNameOrArray,...NS_REQUIRES_NIL_TERMINATION; 58 | #pragma mark 本地验证码 59 | -(NSString*)VerifyCode; 60 | //!生成指定长度验证码(随机背景色)。 61 | -(UIImageView*)VerifyCode:(NSInteger)length; 62 | //!生成指定长度验证码(指定背景色,随机字体颜色)。 63 | -(UIImageView*)VerifyCode:(NSInteger)length fixBgColor:(id)fixBgColor; 64 | //!生成指定长度验证码(指定背景色,指定字体颜色)。 65 | -(UIImageView *)VerifyCode:(NSInteger)length fixBgColor:(id)fixBgColor fixFontColor:(id)fixFontColor; 66 | @end 67 | -------------------------------------------------------------------------------- /Sagit/STBase/STTabController.m: -------------------------------------------------------------------------------- 1 | // 2 | // STTabController.m 3 | // 4 | // Created by 陈裕强 on 2017/12/24. 5 | // Copyright © 2017年. All rights reserved. 6 | // 7 | 8 | #import "STTabController.h" 9 | #import "STUIView.h" 10 | #import "STUIViewController.h" 11 | @implementation STTabController 12 | 13 | #pragma mark ios 13.6 不能用扩展属性 处理的。 14 | //! Presentation 弹新窗口兼容 15 | - (UIModalPresentationStyle)modalPresentationStyle{ 16 | return UIModalPresentationFullScreen; 17 | } 18 | //!屏幕旋转 19 | -(UIInterfaceOrientationMask)supportedInterfaceOrientations 20 | { 21 | return [self.selectedViewController supportedInterfaceOrientations]; 22 | } 23 | //设置样式 24 | - (UIStatusBarStyle)preferredStatusBarStyle { 25 | return [self.selectedViewController preferredStatusBarStyle]; 26 | } 27 | 28 | -(instancetype)init 29 | { 30 | self=[super init]; 31 | //初始化全局设置,必须要在UI初始之前。 32 | [self onInit]; 33 | return self; 34 | } 35 | - (void)viewDidLoad { 36 | [super viewDidLoad]; 37 | [self initUI]; 38 | [self initData]; 39 | } 40 | 41 | //在UI加载之前处理的 42 | -(void)onInit{} 43 | //加载UI时处理的 44 | -(void)initUI{} 45 | //加载UI后处理的 46 | -(void)initData{} 47 | -(void)beforeViewAppear{} 48 | -(void)beforeViewDisappear{} 49 | 50 | 51 | -(void)viewWillDisappear:(BOOL)animated 52 | { 53 | [super viewWillDisappear:animated]; 54 | [self beforeViewDisappear]; 55 | } 56 | -(void)viewWillAppear:(BOOL)animated 57 | { 58 | [super viewWillAppear:animated]; 59 | [self beforeViewAppear]; 60 | } 61 | -(void)setViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers animated:(BOOL)animated 62 | { 63 | if(self.viewControllers.count>0)////清空旧的 64 | { 65 | for (NSInteger i=self.viewControllers.count-1; i>=0; i--) { 66 | [self.viewControllers[i] removeFromParentViewController]; 67 | } 68 | } 69 | if(viewControllers==nil || viewControllers.count==0) 70 | { 71 | return; 72 | } 73 | [super setViewControllers:viewControllers animated:animated]; 74 | for (NSInteger i=0; i *)viewControllers 80 | { 81 | [self setViewControllers:viewControllers animated:NO]; 82 | } 83 | -(void)addChildViewController:(UIViewController *)childController 84 | { 85 | if(childController==nil){return;} 86 | [self setBar:childController]; 87 | [super addChildViewController:childController]; 88 | } 89 | -(void)setBar:(UIViewController*)controller 90 | { 91 | if(controller==nil){return;} 92 | if(controller.navigationController!=nil) 93 | { 94 | [controller.navigationController.viewControllers[0] needTabBar:YES]; 95 | } 96 | else 97 | { 98 | [controller needTabBar:YES]; 99 | } 100 | } 101 | -(void)dealloc 102 | { 103 | NSLog(@"STTabController relase -> %@", [self class]); 104 | } 105 | @end 106 | -------------------------------------------------------------------------------- /Sagit/STTool/Tool/CropImage/CropClipAreaLayer.m: -------------------------------------------------------------------------------- 1 | 2 | #import "CropClipAreaLayer.h" 3 | #import 4 | 5 | #define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width 6 | #define SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height 7 | 8 | static CGFloat const lineWidth = 3; 9 | 10 | @implementation CropClipAreaLayer 11 | 12 | - (instancetype)init 13 | { 14 | self = [super init]; 15 | if (self) { 16 | _cropAreaLeft = 50; 17 | _cropAreaTop = 50; 18 | _cropAreaRight = SCREEN_WIDTH - self.cropAreaLeft; 19 | _cropAreaBottom = 400; 20 | } 21 | return self; 22 | } 23 | 24 | - (void)drawInContext:(CGContextRef)ctx 25 | { 26 | UIGraphicsPushContext(ctx); 27 | 28 | CGContextSetStrokeColorWithColor(ctx, [UIColor whiteColor].CGColor); 29 | CGContextSetLineWidth(ctx, lineWidth); 30 | CGContextMoveToPoint(ctx, self.cropAreaLeft, self.cropAreaTop); 31 | CGContextAddLineToPoint(ctx, self.cropAreaLeft, self.cropAreaBottom); 32 | CGContextSetShadow(ctx, CGSizeMake(2, 0), 2.0); 33 | CGContextStrokePath(ctx); 34 | 35 | CGContextSetStrokeColorWithColor(ctx, [UIColor whiteColor].CGColor); 36 | CGContextSetLineWidth(ctx, lineWidth); 37 | CGContextMoveToPoint(ctx, self.cropAreaLeft, self.cropAreaTop); 38 | CGContextAddLineToPoint(ctx, self.cropAreaRight, self.cropAreaTop); 39 | CGContextSetShadow(ctx, CGSizeMake(0, 2), 2.0); 40 | CGContextStrokePath(ctx); 41 | 42 | CGContextSetStrokeColorWithColor(ctx, [UIColor whiteColor].CGColor); 43 | CGContextSetLineWidth(ctx, lineWidth); 44 | CGContextMoveToPoint(ctx, self.cropAreaRight, self.cropAreaTop); 45 | CGContextAddLineToPoint(ctx, self.cropAreaRight, self.cropAreaBottom); 46 | CGContextSetShadow(ctx, CGSizeMake(-2, 0), 2.0); 47 | CGContextStrokePath(ctx); 48 | 49 | CGContextSetStrokeColorWithColor(ctx, [UIColor whiteColor].CGColor); 50 | CGContextSetLineWidth(ctx, lineWidth); 51 | CGContextMoveToPoint(ctx, self.cropAreaLeft, self.cropAreaBottom); 52 | CGContextAddLineToPoint(ctx, self.cropAreaRight, self.cropAreaBottom); 53 | CGContextSetShadow(ctx, CGSizeMake(0, -2), 2.0); 54 | CGContextStrokePath(ctx); 55 | 56 | UIGraphicsPopContext(); 57 | } 58 | 59 | - (void)setCropAreaLeft:(NSInteger)cropAreaLeft 60 | { 61 | _cropAreaLeft = cropAreaLeft; 62 | [self setNeedsDisplay]; 63 | } 64 | 65 | - (void)setCropAreaTop:(NSInteger)cropAreaTop 66 | { 67 | _cropAreaTop = cropAreaTop; 68 | [self setNeedsDisplay]; 69 | } 70 | 71 | - (void)setCropAreaRight:(NSInteger)cropAreaRight 72 | { 73 | _cropAreaRight = cropAreaRight; 74 | [self setNeedsDisplay]; 75 | } 76 | 77 | - (void)setCropAreaBottom:(NSInteger)cropAreaBottom 78 | { 79 | _cropAreaBottom = cropAreaBottom; 80 | [self setNeedsDisplay]; 81 | } 82 | 83 | - (void)setCropAreaLeft:(NSInteger)cropAreaLeft CropAreaTop:(NSInteger)cropAreaTop CropAreaRight:(NSInteger)cropAreaRight CropAreaBottom:(NSInteger)cropAreaBottom 84 | { 85 | _cropAreaLeft = cropAreaLeft; 86 | _cropAreaRight = cropAreaRight; 87 | _cropAreaTop = cropAreaTop; 88 | _cropAreaBottom = cropAreaBottom; 89 | 90 | [self setNeedsDisplay]; 91 | } 92 | 93 | @end 94 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUIControl.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import "STUIControl.h" 10 | #import "STUIView.h" 11 | #import "STCategory.h" 12 | #import "STDefineFunc.h" 13 | @implementation UIControl (ST) 14 | 15 | #pragma mark 系统事件 16 | 17 | //!执行点击事件 18 | //-(UIControl*)action; 19 | //!绑定事件 event:指定事件名称,也可以是控制器名称,也可以指向其它UI的事件,如:Age.click (Age是其它UI的name) 20 | //-(UIControl*)addAction:(NSString*)event; 21 | //!绑定事件 并指定target 22 | //-(UIControl*)addAction:(NSString *)event target:(UIViewController*)target 23 | //{ 24 | // 25 | // return self; 26 | //} 27 | //!绑定事件 用代码块的形式 28 | -(UIControl*)onAction:(UIControlEvents)event on:(OnAction)block 29 | { 30 | if(block) 31 | { 32 | SEL sel=NSSelectorFromString(@"exeAction:a1"); 33 | NSString *eventKey=@"event1"; 34 | for (int i=1; i<10; i++) { 35 | NSString *key=[@"event" append:STNumString(i)]; 36 | if(![self.keyValue has:key]) 37 | { 38 | eventKey=key; 39 | sel=NSSelectorFromString(STString(@"exeAction:a%d:",i)); 40 | break; 41 | } 42 | } 43 | 44 | NSString *searchKey=[@"event_"append:STNumString(event)]; 45 | NSString *searchValue=[self key:searchKey];//用于移除查找事件。 46 | if(searchValue==nil) 47 | { 48 | [self key:searchKey value:eventKey]; 49 | } 50 | else 51 | { 52 | [self key:searchKey value:STString(@"%@,%@",searchValue,eventKey)];//指向同一个事件。 53 | } 54 | [self key:eventKey value:block]; 55 | [self addTarget:self action:sel forControlEvents:event]; 56 | } 57 | return self; 58 | } 59 | //由于无法知道事件来源,只能事先定义多个不同参方法来识别。 60 | -(void)exeAction:(id)sender a1:(id)a{[self exeAction:1];} 61 | -(void)exeAction:(id)sender a2:(id)a{[self exeAction:2];} 62 | -(void)exeAction:(id)sender a3:(id)a{[self exeAction:3];} 63 | -(void)exeAction:(id)sender a4:(id)a{[self exeAction:4];} 64 | -(void)exeAction:(id)sender a5:(id)a{[self exeAction:5];} 65 | -(void)exeAction:(id)sender a6:(id)a{[self exeAction:6];} 66 | -(void)exeAction:(id)sender a7:(id)a{[self exeAction:7];} 67 | -(void)exeAction:(id)sender a8:(id)a{[self exeAction:8];} 68 | -(void)exeAction:(id)sender a9:(id)a{[self exeAction:9];} 69 | -(void)exeAction:(NSInteger)num 70 | { 71 | //目前只处理一个 72 | OnAction action=[self key:[@"event" append:STNumString(num)]]; 73 | if(action) 74 | { 75 | action(self); 76 | } 77 | } 78 | //!移除绑定点击事件 79 | -(UIControl*)removeAction:(UIControlEvents)event 80 | { 81 | [self removeTarget:self action:nil forControlEvents:event]; 82 | NSString *key=[self key:[@"event_"append:STNumString(event)]]; 83 | if(key!=nil) 84 | { 85 | NSArray *items=[key split:@","]; 86 | for (NSString *item in items) { 87 | [self key:item value:nil];//移除方法block 88 | } 89 | 90 | } 91 | return self; 92 | } 93 | 94 | #pragma mark 系统属性 95 | -(UIControl *)enabled:(BOOL)yesNo 96 | { 97 | [self alpha:yesNo?1:0.4]; 98 | [self setEnabled:yesNo]; 99 | return self; 100 | } 101 | -(UIControl *)selected:(BOOL)yesNo 102 | { 103 | [self setSelected:yesNo]; 104 | return self; 105 | } 106 | -(UIControl *)highlighted:(BOOL)yesNo 107 | { 108 | [self setHighlighted:yesNo]; 109 | return self; 110 | } 111 | //-(void)dealloc 112 | //{ 113 | // //[self removeTarget:self action:nil forControlEvents:nil]; 114 | //} 115 | @end 116 | -------------------------------------------------------------------------------- /Sagit/Define/STDefine.m: -------------------------------------------------------------------------------- 1 | // 2 | // STDefine.m 3 | // Created by 陈裕强 on 2020/9/11. 4 | // 5 | 6 | #import "STDefine.h" 7 | @interface STDefine() 8 | @property (nonatomic,assign) NSInteger _StandardScale; 9 | @property (nonatomic,assign) NSInteger _DefaultShowNav; 10 | @property (nonatomic,assign) NSInteger _DefaultShowTab; 11 | @property (nonatomic,assign) NSInteger _DefaultShowStatus; 12 | @property (nonatomic,copy) NSString *_DefaultNavLeftTitle; 13 | @property (nonatomic,copy) NSString *_DefaultNavLeftImage; 14 | @property (nonatomic,assign) NSUInteger _DefaultOrientation; 15 | @property (nonatomic,assign) NSUInteger _DefaultOrientationMask; 16 | 17 | @end 18 | @implementation STDefine 19 | 20 | + (instancetype)share 21 | { 22 | 23 | static STDefine *_share = nil; 24 | static dispatch_once_t onceToken; 25 | dispatch_once(&onceToken, ^{ 26 | _share = [[STDefine alloc] init]; 27 | }); 28 | return _share; 29 | } 30 | -(NSString *)Version 31 | { 32 | return @"V2.1.0"; 33 | } 34 | -(NSString *)VersionNum 35 | { 36 | return @"202110261100"; 37 | } 38 | - (NSInteger)StandardScale 39 | { 40 | if(self._StandardScale>0 && self._StandardScale<4) 41 | { 42 | return self._StandardScale; 43 | } 44 | return 2; 45 | } 46 | -(void)setStandardScale:(NSInteger)StandardScale 47 | { 48 | self._StandardScale=StandardScale; 49 | } 50 | - (BOOL)DefaultShowNav 51 | { 52 | if(self._DefaultShowNav>0) 53 | { 54 | return self._DefaultShowNav==1; 55 | } 56 | return YES; 57 | } 58 | - (void)setDefaultShowNav:(BOOL)DefaultShowNav 59 | { 60 | self._DefaultShowNav=DefaultShowNav?1:2; 61 | } 62 | 63 | - (BOOL)DefaultShowTab 64 | { 65 | if(self._DefaultShowTab>0) 66 | { 67 | return self._DefaultShowTab==1; 68 | } 69 | return YES; 70 | } 71 | - (void)setDefaultShowTab:(BOOL)DefaultShowTab 72 | { 73 | self._DefaultShowTab=DefaultShowTab?1:2; 74 | } 75 | -(BOOL)DefaultShowStatus 76 | { 77 | if(self._DefaultShowStatus>0) 78 | { 79 | return self._DefaultShowStatus==1; 80 | } 81 | return YES; 82 | } 83 | - (void)setDefaultShowStatus:(BOOL)DefaultShowStatus 84 | { 85 | self._DefaultShowStatus=DefaultShowStatus?1:2; 86 | } 87 | - (NSString *)DefaultNavLeftTitle 88 | { 89 | if(self._DefaultNavLeftTitle!=nil) 90 | { 91 | return self._DefaultNavLeftTitle; 92 | } 93 | return @"STEmpty"; 94 | } 95 | -(void)setDefaultNavLeftTitle:(NSString *)DefaultNavLeftTitle 96 | { 97 | self._DefaultNavLeftTitle=DefaultNavLeftTitle; 98 | } 99 | -(NSString *)DefaultNavLeftImage 100 | { 101 | return self._DefaultNavLeftImage; 102 | } 103 | -(void)setDefaultNavLeftImage:(NSString *)DefaultNavLeftImage 104 | { 105 | self._DefaultNavLeftImage=DefaultNavLeftImage; 106 | } 107 | 108 | 109 | - (UIInterfaceOrientation)DefaultOrientation 110 | { 111 | if(self._DefaultOrientation!= 0) 112 | { 113 | return (UIInterfaceOrientation)self._DefaultOrientation; 114 | } 115 | return UIInterfaceOrientationPortrait; 116 | } 117 | -(void)setDefaultOrientation:(UIInterfaceOrientation)DefaultOrientation 118 | { 119 | self._DefaultOrientation=(NSInteger)DefaultOrientation; 120 | } 121 | 122 | 123 | -(UIInterfaceOrientationMask)DefaultOrientationMask 124 | { 125 | if(self._DefaultOrientationMask!= 0) 126 | { 127 | return (UIInterfaceOrientationMask)self._DefaultOrientationMask; 128 | } 129 | return UIInterfaceOrientationMaskAllButUpsideDown; 130 | } 131 | -(void)setDefaultOrientationMask:(UIInterfaceOrientationMask)DefaultOrientationMask 132 | { 133 | self._DefaultOrientationMask=(NSInteger)DefaultOrientationMask; 134 | } 135 | @end 136 | -------------------------------------------------------------------------------- /Sagit/STTool/Common/STCache.m: -------------------------------------------------------------------------------- 1 | // 2 | // STCache.m 3 | // IT恋 4 | // 5 | // Created by 陈裕强 on 2018/1/10. 6 | // Copyright © 2018年 . All rights reserved. 7 | // 8 | 9 | #import "STCache.h" 10 | #import "STCategory.h" 11 | @interface STCache() 12 | @property (nonatomic,retain)NSMutableDictionary*timeOutDic; 13 | @property (nonatomic,assign)NSInteger sleepSecond; 14 | @property (nonatomic,assign)BOOL isStartClearTask; 15 | @property (retain)NSLock* lock; 16 | @end 17 | @implementation STCache 18 | + (instancetype)share 19 | { 20 | static STCache *_share = nil; 21 | static dispatch_once_t onceToken; 22 | dispatch_once(&onceToken, ^{ 23 | _share = [[STCache alloc] init]; 24 | _share.lock=[NSLock new]; 25 | }); 26 | return _share; 27 | } 28 | //清除过期的缓存 29 | -(void)clearTimeOutCache 30 | { 31 | self.sleepSecond=5*60;//5分钟 32 | NSMutableArray *keys=[NSMutableArray new]; 33 | while (true) { 34 | [NSThread sleepForTimeInterval:self.sleepSecond]; 35 | if(!_timeOutDic || _timeOutDic.count==0)//有过期的Cache 36 | { 37 | self.isStartClearTask=NO; 38 | return; 39 | } 40 | @try 41 | { 42 | [self.lock lock]; 43 | for (NSString*key in _timeOutDic) 44 | { 45 | NSDate *date=_timeOutDic[key]; 46 | // 时间2与时间1之间的时间差(秒) 47 | if([date timeIntervalSinceReferenceDate] - [NSDate.date timeIntervalSinceReferenceDate]<0) 48 | { 49 | [keys addObject:key]; 50 | } 51 | } 52 | [self.lock unlock]; 53 | if(keys.count>0) 54 | { 55 | for (NSString* key in keys) { 56 | [self remove:key]; 57 | [_timeOutDic remove:key]; 58 | } 59 | [keys removeAllObjects]; 60 | } 61 | } 62 | @catch(NSException*err) 63 | { 64 | NSLog(@"%@",err); 65 | return;//异常则退出,不清缓存了。 66 | } 67 | 68 | } 69 | } 70 | 71 | -(NSMutableDictionary *)cacheObj 72 | { 73 | return [NSMutableDictionary share]; 74 | } 75 | -(NSMutableDictionary *)timeOutDic 76 | { 77 | if(!_timeOutDic) 78 | { 79 | _timeOutDic=[NSMutableDictionary new]; 80 | } 81 | return _timeOutDic; 82 | } 83 | #pragma 基本方法 84 | -(BOOL)has:(NSString*)key{ 85 | return [self.cacheObj get:key]!=nil; 86 | } 87 | -(id)get:(NSString*)key 88 | { 89 | //检测对象是否过期 90 | NSDate *date=[self.timeOutDic get:key]; 91 | if(date) 92 | { 93 | // 时间2与时间1之间的时间差(秒) 94 | if([date timeIntervalSinceReferenceDate] - [NSDate.date timeIntervalSinceReferenceDate]<0) 95 | { 96 | return nil; 97 | } 98 | } 99 | return [self.cacheObj get:key]; 100 | } 101 | -(void)set:(NSString*)key value:(id)value 102 | { 103 | [self.cacheObj set:key value:value]; 104 | } 105 | -(void)set:(NSString *)key value:(id)value second:(NSInteger)timeOutSecond 106 | { 107 | [self.cacheObj set:key value:value]; 108 | if(timeOutSecond>0) 109 | { 110 | [self.lock lock]; 111 | [self.timeOutDic set:key value:[NSDate.date addSecond:timeOutSecond]]; 112 | if(!self.isStartClearTask) 113 | { 114 | self.isStartClearTask=YES; 115 | dispatch_async(dispatch_get_global_queue(0, 0), ^{ 116 | [self clearTimeOutCache]; 117 | }); 118 | } 119 | [self.lock unlock]; 120 | } 121 | } 122 | -(void)remove:(NSString*)key 123 | { 124 | [self.cacheObj remove:key]; 125 | } 126 | - (void)clear 127 | { 128 | [self.cacheObj removeAllObjects]; 129 | } 130 | @end 131 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUIPageControl.m: -------------------------------------------------------------------------------- 1 | // 2 | // STUIPageControl.m 3 | // IT恋 4 | // 5 | // Created by 陈裕强 on 2018/2/1. 6 | // Copyright © 2018年 . All rights reserved. 7 | // 8 | 9 | #import "STUIPageControl.h" 10 | #import "STUIScrollView.h" 11 | #import "STCategory.h" 12 | @implementation UIPageControl (ST) 13 | -(UIPageControl*)numberOfPages:(NSInteger)num 14 | { 15 | self.numberOfPages=num; 16 | return self; 17 | } 18 | -(UIPageControl*)currentPage:(NSInteger)pagerIndex 19 | { 20 | self.currentPage=pagerIndex; 21 | if(self.scrollView && self.scrollView.pagerIndex!=pagerIndex) 22 | { 23 | self.scrollView.pagerIndex=pagerIndex; 24 | } 25 | return self; 26 | } 27 | -(UIPageControl*)pageColor:(id)colorOrHex 28 | { 29 | self.pageIndicatorTintColor=[UIColor toColor:colorOrHex]; 30 | return self; 31 | } 32 | -(UIPageControl*)currentColor:(id)colorOrHex 33 | { 34 | self.currentPageIndicatorTintColor=[UIColor toColor:colorOrHex]; 35 | return self; 36 | } 37 | #pragma mark 扩展 38 | -(UIScrollView *)scrollView 39 | { 40 | return [self key:@"scrollView"]; 41 | } 42 | -(BOOL)isTimering 43 | { 44 | NSString *flag=[self key:@"isTimering"]; 45 | if(flag!=nil) 46 | { 47 | return [flag isEqualToString:@"1"]; 48 | } 49 | return NO; 50 | } 51 | -(NSTimer *)timer 52 | { 53 | return [self key:@"timer"]; 54 | } 55 | -(UIPageControl *)startTimer:(NSInteger)second onTimer:(OnPageTimer)onTimer 56 | { 57 | if(!self.isTimering) 58 | { 59 | [self key:@"isTimering" value:@"1"]; 60 | NSTimer *timer=[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(onTimering) userInfo:nil repeats:YES]; 61 | [self key:@"NSTimer" value:timer]; 62 | if(onTimer) 63 | { 64 | [self key:@"OnTimerEvent" value:onTimer]; 65 | } 66 | [timer fire]; 67 | } 68 | return self; 69 | } 70 | -(void)onTimering 71 | { 72 | if(!self.isTimering) 73 | { 74 | NSTimer *timer=[self key:@"NSTimer"]; 75 | if(timer) 76 | { 77 | [timer invalidate]; 78 | timer=nil; 79 | [self key:@"NSTimer" value:nil]; 80 | [self key:@"OnTimerEvent" value:nil]; 81 | } 82 | return; 83 | } 84 | NSInteger pagerIndex=self.currentPage; 85 | pagerIndex=pagerIndex+1; 86 | if(pagerIndex>=self.numberOfPages) 87 | { 88 | pagerIndex=0; 89 | } 90 | [self currentPage:pagerIndex]; 91 | OnPageTimer event=[self key:@"OnTimerEvent"]; 92 | if(event) 93 | { 94 | event([self key:@"NSTimer"]); 95 | } 96 | } 97 | -(UIPageControl *)stopTimer 98 | { 99 | [self key:@"isTimering" value:nil]; 100 | return self; 101 | } 102 | #pragma mark 分页点击事件 103 | -(OnPagerChange)onPagerChange 104 | { 105 | return [self key:@"onPagerChange"]; 106 | } 107 | -(void)setOnPagerChange:(OnPagerChange)onPagerChange 108 | { 109 | [self key:@"onPagerChange" value:onPagerChange]; 110 | } 111 | -(BOOL)allowClickPager 112 | { 113 | return self.userInteractionEnabled; 114 | } 115 | -(void)setAllowClickPager:(BOOL)allowClickPager 116 | { 117 | self.userInteractionEnabled=allowClickPager; 118 | [self removeTarget:self action:@selector(onValueChange) forControlEvents:UIControlEventValueChanged]; 119 | if(allowClickPager) 120 | { 121 | [self addTarget:self action:@selector(onValueChange) forControlEvents:UIControlEventValueChanged]; 122 | } 123 | } 124 | -(void)onValueChange 125 | { 126 | if(self.onPagerChange) 127 | { 128 | self.onPagerChange(self); 129 | } 130 | [self currentPage:self.currentPage];//内部检测给滚动视图赋值。 131 | } 132 | -(void)dispose 133 | { 134 | [self removeTarget:self action:@selector(onValueChange) forControlEvents:UIControlEventValueChanged]; 135 | } 136 | @end 137 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUIViewAutoLayout.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "STController.h" 12 | #import "STView.h" 13 | 14 | @interface UIView(STAutoLayout) 15 | #pragma mark 属性定义 16 | //!记录每个UI的移动轨迹,系统自动控制,不需要用户处理 17 | - (NSMutableDictionary*)LayoutTracer; 18 | - (UIView*)setLayoutTracer:(NSMutableDictionary*)tracer; 19 | //!当前UI第一次设置的frame,方便以后归位。 20 | - (CGRect)OriginFrame; 21 | - (UIView*)setOriginFrame:(CGRect)frame; 22 | //!获取修正后父窗体的宽高。 23 | -(CGSize)superSizeWithFix; 24 | //-(CGSize)superSize; 25 | #pragma mark [相对布局方法] RelativeLayout 26 | //当前UI将布局于指定UI的右侧 27 | -(UIView*)onRight:(id)uiOrName; 28 | -(UIView*)onRight:(id)uiOrName x:(CGFloat)x; 29 | -(UIView*)onRight:(id)uiOrName x:(CGFloat)x y:(CGFloat)y; 30 | //当前UI将布局于指定UI的左侧 31 | -(UIView*)onLeft:(id)uiOrName; 32 | -(UIView*)onLeft:(id)uiOrName x:(CGFloat)x; 33 | -(UIView*)onLeft:(id)uiOrName x:(CGFloat)x y:(CGFloat)y; 34 | //当前UI将布局于指定UI的上方 35 | -(UIView*)onTop:(id)uiOrName; 36 | -(UIView*)onTop:(id)uiOrName y:(CGFloat)y; 37 | -(UIView*)onTop:(id)uiOrName y:(CGFloat)y x:(CGFloat)x; 38 | //当前UI将布局于指定UI的下方 39 | -(UIView *)onBottom:(id)uiOrName; 40 | -(UIView *)onBottom:(id)uiOrName y:(CGFloat)y; 41 | -(UIView *)onBottom:(id)uiOrName y:(CGFloat)y x:(CGFloat)x; 42 | //!相对当前UI的父视图布局 XYLocation 决定相对的位置 43 | -(UIView*)relate:(XYLocation)location v:(CGFloat)value; 44 | -(UIView*)relate:(XYLocation)location v:(CGFloat)value v2:(CGFloat)value2; 45 | -(UIView*)relate:(XYLocation)location v:(CGFloat)value v2:(CGFloat)value2 v3:(CGFloat)value3; 46 | -(UIView*)relate:(XYLocation)location v:(CGFloat)value v2:(CGFloat)value2 v3:(CGFloat)value3 v4:(CGFloat)value4; 47 | //!将当前的UI居中 (不传参默认上下左右都居中) 48 | -(UIView*)toCenter; 49 | //!将当前的UI居中 XYFlag 指定左右或上下 50 | -(UIView*)toCenter:(XYFlag)xyFlag; 51 | //!获取当前UI的X值(px) 52 | -(CGFloat)stX; 53 | //!获取当前UI的相对屏幕X值(px) 54 | -(CGFloat)stScreenX; 55 | //!获取当前UI的Y值(px) 56 | -(CGFloat)stY; 57 | //!获取当前UI的相对屏幕Y值(px) 58 | -(CGFloat)stScreenY; 59 | //!获取当前UI的width值(px) 60 | -(CGFloat)stWidth; 61 | //!获取当前UI的height值(px) 62 | -(CGFloat)stHeight; 63 | -(UIView*)frame:(CGRect) frame; 64 | //!用px值设置当前UI的坐标体系或宽高 65 | -(UIView*)x:(CGFloat)x; 66 | -(UIView*)x:(CGFloat)x y:(CGFloat)y; 67 | -(UIView*)x:(CGFloat)x y:(CGFloat)y width:(CGFloat)width height:(CGFloat)height; 68 | //!用px值设置当前UI的坐标体系或宽高 69 | -(UIView*)y:(CGFloat)y; 70 | //!用px值设置当前UI的坐标体系或宽高 71 | -(UIView*)width:(CGFloat)width; 72 | -(UIView*)width:(CGFloat)width height:(CGFloat)height; 73 | //!用px值设置当前UI的坐标体系或宽高 74 | -(UIView*)width:(CGFloat)width height:(CGFloat)height x:(CGFloat)x y:(CGFloat)y; 75 | //!用px值设置当前UI的坐标体系或宽高 76 | -(UIView*)height:(CGFloat)height; 77 | //!将当前的UI移动到指定的坐标(及视情况改变宽高) 78 | -(UIView*)moveTo:(CGRect)frame; 79 | //!还原第一次设置的坐标系及宽高 80 | -(UIView*)backToOrigin; 81 | //!刷新当前UI及子UI的布局以及宽高 82 | -(UIView*)refleshLayout; 83 | //!刷新当前UI及子UI的布局以及[宽高(可控制)] withWidthHeight : 是否改变宽与高,默认是YES 84 | -(UIView*)refleshLayout:(BOOL)withWidthHeight; 85 | //!刷新[当前UI(可控制)]及子UI的布局 withWidthHeight:是否改变宽与高,默认是YES ignoreSelf:忽略自身,默认是NO 86 | -(UIView*)refleshLayout:(BOOL)withWidthHeight ignoreSelf:(BOOL)ignoreSelf; 87 | //!刷新布局【屏幕旋转后】 88 | -(void)refleshLayoutAfterRotate; 89 | 90 | //!遍历检测其子UI,如果子UI部分超过,则扩展宽与高,但不会缩小。 91 | -(UIView*)stSizeToFit; 92 | //!遍历检测其子UI,如果子UI部分超过,则扩展宽与高,但不会缩小。px参数:扩展后再追加的长度或高度,默认0 93 | -(UIView*)stSizeToFit:(NSInteger)widthPx y:(NSInteger)heightPx; 94 | //!图片拉伸(一般适用于背景拉伸或聊天图片的拉伸) 95 | -(UIView*)stretch; 96 | //!图片拉伸(一般适用于背景拉伸或聊天图片的拉伸) x:是px值 97 | -(UIView*)stretch:(CGFloat)x; 98 | //!图片拉伸(一般适用于背景拉伸或聊天图片的拉伸) x、y: 都是px值 99 | -(UIView*)stretch:(CGFloat)x y:(CGFloat)y; 100 | 101 | //!缩小UIView的两边宽高、并保持中心点不变。 102 | -(UIView*)cut:(NSInteger)widthPx height:(NSInteger)heightPx; 103 | //#pragma mark 【px<=>pt】动态转换系数 104 | //+(NSInteger)stStandardWidthPt:(id)viewOrController; 105 | //+(NSInteger)stStandardHeightPt:(id)viewOrController; 106 | //+(CGFloat)xToPt; 107 | //+(CGFloat)yToPt; 108 | //+(CGFloat)xToPx; 109 | //+(CGFloat)yToPx; 110 | @end 111 | -------------------------------------------------------------------------------- /Sagit/Category/Controller/STUIViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // Copyright © 2017-2027年. All rights reserved. 6 | // 7 | 8 | #import 9 | #import 10 | #import "STEnum.h" 11 | 12 | @interface UIViewController(ST) 13 | //!当前控制器的视图的根视图 14 | -(UIView*)baseView; 15 | //!前一个页面控制器 16 | -(UIViewController*)preController; 17 | //!后一个页面控制器(系统用于检测是否释放使用) 18 | -(UIViewController *)nextController; 19 | //!设置自身为根控制器 20 | -(UIViewController*)asRoot; 21 | /**设置自身为根控制器 22 | @param rootType 设置的根类型 23 | */ 24 | -(UIViewController*)asRoot:(RootViewControllerType) rootType; 25 | //!获取当前主Window 26 | -(UIWindow*)keyWindow; 27 | #pragma mark 扩展导航栏事件 28 | //!返回当前视图是否需要导航栏 29 | -(BOOL)needNavBar; 30 | //!设置当前视图是否需要导航栏 31 | -(UIViewController*)needNavBar:(BOOL)yesNo; 32 | //!设置当前视图是否需要导航栏 forThisView:标记当前UIView是否设置隐藏或显示 33 | -(UIViewController*)needNavBar:(BOOL)yesNo forThisView:(BOOL)forThisView; 34 | 35 | //!返回当前视图是否需要Tab栏 36 | -(BOOL)needTabBar; 37 | //!设置当前视图是否需要Tab栏 38 | -(UIViewController*)needTabBar:(BOOL)yesNo; 39 | //!设置当前视图是否需要Tab栏 forThisView:标记当前UIView是否设置隐藏或显示 默认:YES 40 | -(UIViewController*)needTabBar:(BOOL)yesNo forThisView:(BOOL)forThisView; 41 | 42 | //!返回当前视图是否需要Status栏 43 | -(BOOL)needStatusBar; 44 | //!设置当前视图是否需要Status栏 45 | -(UIViewController*)needStatusBar:(BOOL)yesNo; 46 | //!设置当前视图是否需要Status栏 forThisView:标记当前UIView是否设置隐藏或显示 47 | -(UIViewController*)needStatusBar:(BOOL)yesNo forThisView:(BOOL)forThisView; 48 | //!设置视图Status栏显示的样式:默认全局 49 | -(UIViewController*)setStatusBarStyle:(UIStatusBarStyle)style; 50 | //!设置当前视图Status栏显示的样式:默认全局 @forThisView 是否只在当前View失效 默认:NO 51 | -(UIViewController*)setStatusBarStyle:(UIStatusBarStyle)style forThisView:(BOOL)forThisView; 52 | //【系统内部方法】:用于还原导航栏和状态栏和Tab栏 53 | -(void)reSetBarState:(BOOL)animated; 54 | 55 | #pragma mark keyvalue 56 | //!扩展一个字典属性,方便存档及数据传递 57 | -(NSMutableDictionary*)keyValue; 58 | //!从keyValue属性中获取字指定key的值 59 | -(id)key:(NSString*)key; 60 | //!为keyValue属性设置键与值 61 | -(UIViewController*)key:(NSString*)key value:(id)value; 62 | //当value不存在时,才允许赋值(保证该方法仅赋值一次) 63 | -(UIViewController*)key:(NSString *)key valueIfNil:(id)value; 64 | //!为keyValue属性设置键与值 其中value为弱引用 65 | -(UIViewController*)key:(NSString*)key valueWeak:(id)value; 66 | #pragma mark 代码说明块 67 | typedef void(^OnControllerDescription)(UIViewController *controller); 68 | //!提供一个代码块,方便代码规范 description处可以写代码块的说明文字 69 | -(UIViewController*)block:(OnControllerDescription)descBlock; 70 | -(UIViewController*)block:(NSString*)description on:(OnControllerDescription)descBlock; 71 | #pragma mark 导航栏功能 72 | //!压入视图并显示下一个页面(通过此方法跳转视图,系统会自动控制导航栏和Tab栏的显示与隐藏,以及滑动返回事件) 73 | - (void)stPush:(UIViewController *)viewController; 74 | //!压入视图并显示下一个页面(通过此方法跳转视图,系统会自动控制导航栏和Tab栏的显示与隐藏,以及滑动返回事件) 75 | - (void)stPush:(UIViewController *)viewController title:(NSString *)title; 76 | //!压入视图并显示下一个页面(通过此方法跳转视图,系统会自动控制导航栏和Tab栏的显示与隐藏,以及滑动返回事件) 77 | - (void)stPush:(UIViewController *)viewController title:(NSString *)title img:(id)imgOrName; 78 | //!退弹出视图并返回上一个页面(对应stPush方法) 79 | - (void)stPop; 80 | //!退弹出视图并返回首页(对应stPush方法) 81 | -(void)stPopToTop; 82 | //!设置左侧导航栏的按钮为文字或图片(优先) 83 | -(UIViewController*)leftNav:(NSString*)title img:(id)imgOrName; 84 | //!左侧导航栏的默认点击事件 return YES 则系统调stPop返回方法。 85 | -(BOOL)onLeftNavBarClick:(UIBarButtonItem*)view; 86 | //!左侧导航栏的默认长按事件 return YES 则系统调stPopToTop返回方法。 87 | -(BOOL)onLeftNavBarLongPress:(UIBarButtonItem*)view; 88 | //!设置右侧导航栏的按钮为文字或图片(优先) 89 | -(UIViewController*)rightNav:(NSString*)title img:(id)imgOrName; 90 | //!右侧导航栏的默认点击事件 91 | -(void)onRightNavBarClick:(UIBarButtonItem*)view; 92 | //系统内部调用的方法 93 | -(UIViewController*)reSetNav:(UINavigationController*)navController; 94 | //!隐藏导航条下面的阴线 95 | -(UIViewController*)hideNavShadow; 96 | //!跳转到其它页面(内部方法) 97 | -(void)redirect:(UITapGestureRecognizer*)recognizer; 98 | #pragma mark 共用接口 99 | //!重新加载数据(一般由子类重写,由于方法统一,在不同控制器中都可以直接调用,而不用搞代理事件) 100 | -(void)reloadData; 101 | //!重新加载数据(一般由子类重写,只是多了个参数,方便根据参数重新加载不同的数据) 102 | -(void)reloadData:(NSString*)para; 103 | 104 | 105 | #pragma mark for TabBar 属性扩展 106 | -(UIViewController*)title:(NSString*)title; 107 | -(UIViewController*)tabTitle:(NSString*)title; 108 | -(UIViewController*)tabImage:(id)imgOrName; 109 | -(UIViewController*)tabSelectedImage:(id)imgOrName; 110 | -(UIViewController*)tabBadgeValue:(NSString*)value; 111 | -(UIViewController*)tabBadgeColor:(id)colorOrHex; 112 | -(UINavigationController*)toUINavigationController; 113 | //!【系统内部方法】:框架自动释放资源(不需要人工调用) 114 | -(void)dispose; 115 | @end 116 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUILabel.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import "STUILabel.h" 10 | #import "STDefineUI.h" 11 | #import "STUIView.h" 12 | #import "STUIViewEvent.h" 13 | #import "STDictionary.h" 14 | #import "STCategory.h" 15 | @implementation UILabel(ST) 16 | #pragma mark 扩展系统事件 17 | -(UILabel *)longPressCopy:(BOOL)yesNo 18 | { 19 | if(yesNo) 20 | { 21 | if([self key:@"longPressCopy"]==nil) 22 | { 23 | [self key:@"longPressCopy" value:@"1"]; 24 | 25 | [self onLongPress:^(UILabel *this) { 26 | [this key:@"backgroundColor" value:this.backgroundColor]; 27 | [[NSNotificationCenter defaultCenter] addObserver:this selector:@selector(didHideMenu:) name:UIMenuControllerDidHideMenuNotification object:nil];//注册菜单隐藏事件,在隐藏时会注销事件 28 | 29 | [this becomeFirstResponder]; 30 | UIMenuController *menuC = [UIMenuController sharedMenuController];//全局的,其它地方修改也会影响 31 | UIMenuItem *menuCopy = [[UIMenuItem alloc] initWithTitle:@"复制" action:@selector(copy)]; 32 | menuC.menuItems=@[menuCopy]; 33 | [menuC setTargetRect:this.frame inView:this.superview]; 34 | [[this backgroundColor:ColorGray] alpha:0.7];//设置背景色 35 | [menuC setMenuVisible:YES animated:YES]; 36 | }]; 37 | } 38 | } 39 | else 40 | { 41 | [self removeLongPress]; 42 | [self.keyValue remove:@"longPressCopy"]; 43 | } 44 | return self; 45 | } 46 | -(void)didHideMenu:(id)sender 47 | { 48 | UIColor *color=[self key:@"backgroundColor"]; 49 | if(color) 50 | { 51 | [self backgroundColor:color];//菜单隐藏,恢复 52 | } 53 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UIMenuControllerDidHideMenuNotification object:nil]; 54 | } 55 | - (BOOL)canBecomeFirstResponder 56 | { 57 | return [self key:@"longPressCopy"]!=nil; 58 | 59 | } 60 | 61 | - (BOOL)canPerformAction:(SEL)action withSender:(id)sender{ 62 | return action == @selector(copy); 63 | } 64 | 65 | //!复制文本 66 | -(UILabel*)copy 67 | { 68 | UIPasteboard *pboard = [UIPasteboard generalPasteboard]; 69 | if(self.text) 70 | { 71 | pboard.string = self.text; 72 | } 73 | else if(self.attributedText.string) 74 | { 75 | pboard.string = self.attributedText.string; 76 | } 77 | return self; 78 | } 79 | 80 | #pragma mark 扩展文字高级属性 81 | //-(NSAttributedString*)rand 82 | //{ 83 | // if(!self.attributedText) 84 | // { 85 | // self.attributedText=[[NSMutableAttributedString alloc] initWithString:self.text]; 86 | // } 87 | // 88 | // NSMutableAttributedString *attr = [[NSMutableAttributedString alloc] initWithString:self.text]; 89 | // 20 [attributedString addAttribute:NSLinkAttributeName 90 | // 21 value:@"zhifubao://" 91 | // 22 range:[[attributedString string] rangeOfString:@"《支付宝协议》"]]; 92 | // 23 [attributedString addAttribute:NSLinkAttributeName 93 | // 24 value:@"weixin://" 94 | // 25 range:[[attributedString string] rangeOfString:@"《微信协议》"]]; 95 | // 26 [attributedString addAttribute:NSLinkAttributeName 96 | // 27 value:@"jianhang://" 97 | // 28 range:[[attributedString string] rangeOfString:@"《建行协议》"]]; 98 | //} 99 | 100 | #pragma mark 扩展系统属性 101 | 102 | -(UILabel*)text:(NSString*)text 103 | { 104 | if([text isKindOfClass:[NSNull class]]) 105 | { 106 | self.text=nil; 107 | } 108 | else 109 | { 110 | self.text=text; 111 | } 112 | return self; 113 | } 114 | -(UILabel*)textColor:(id)colorOrHex 115 | { 116 | self.textColor=[UIColor toColor:colorOrHex]; 117 | return self; 118 | } 119 | -(UILabel*)textAlignment:(NSTextAlignment)align 120 | { 121 | self.textAlignment=align; 122 | return self; 123 | } 124 | -(UILabel*)font:(CGFloat)px 125 | { 126 | self.font=[UIFont toFont:px]; 127 | return self; 128 | } 129 | -(UILabel*)numberOfLines:(NSInteger)value 130 | { 131 | self.numberOfLines=value; 132 | return self; 133 | } 134 | -(UILabel *)adjustsFontSizeToFitWidth:(BOOL)yesNo 135 | { 136 | self.adjustsFontSizeToFitWidth=yesNo; 137 | return self; 138 | } 139 | @end 140 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUIViewAddUI.h: -------------------------------------------------------------------------------- 1 | // 2 | // STUIViewAddUI.h 3 | // IT恋 4 | // 5 | // Created by 陈裕强 on 2017/12/23. 6 | // Copyright © 2017年 . All rights reserved. 7 | // 8 | 9 | #import 10 | #import "STEnum.h" 11 | #import "STNSMapTable.h" 12 | @class STView; 13 | //#import "STTable.h" 14 | @interface UIView (STUIViewAddUI) 15 | 16 | #pragma mark UI属性 17 | //!当前UI下最后一次被添加的UI 18 | -(UIView*)lastAddView; 19 | //!当前UI的最后一个子UI 20 | -(UIView*)lastSubView; 21 | //!当前UI的最后一个子UI 22 | -(UIView*)lastSubView:(NSString*)className; 23 | //!当前UI的第一个子UI 24 | -(UIView*)firstSubView; 25 | //!当前UI的第一个子UI 26 | -(UIView*)firstSubView:(NSString*)className; 27 | //!当前UI的前一个UI 28 | - (UIView*)preView; 29 | //!设置当前UI的前一个UI 30 | - (UIView*)preView:(UIView*)view; 31 | //!当前UI的下一个UI 32 | - (UIView*)nextView; 33 | //!设置当前UI的下一个UI 34 | - (UIView*)nextView:(UIView*)view; 35 | //!从当前的UI中寻找控件。 36 | -(UIView*)find:(id)name; 37 | //!根据类名,获取第一个UI 38 | -(UIView*)firstView:(NSString*)className; 39 | //!当前UI是否表单UI【如果是,可以通过self.formData 取值】 40 | - (BOOL)isFormUI; 41 | //!设置当前UI是否表单UI 42 | - (UIView*)isFormUI:(BOOL)yesNo; 43 | //!有name的控件的集合 44 | - (STMapTable *)UIList; 45 | 46 | #pragma mark 添置UI 47 | //!移除自身(前会修改前后视图的指向关系) 48 | -(void)removeSelf; 49 | //!移除所有的subViews 50 | -(UIView*)removeAllSubViews; 51 | //!所有添加View的最后总入口。 52 | -(UIView*)addView:(UIView *)view name:(NSString*)name; 53 | //!添加一个STView类型的子控件 54 | -(STView*)addSTView:(NSString*)name; 55 | //!添加一个空的UIView 56 | -(UIView*)addUIView:(NSString*)name; 57 | -(UISwitch*)addSwitch:(NSString*)name; 58 | -(UISwitch*)addSwitch:(NSString*)name on:(BOOL)yesNo; 59 | -(UISwitch*)addSwitch:(NSString*)name on:(BOOL)yesNo onColor:(id)colorOrHex; 60 | -(UIStepper *)addStepper:(NSString *)name; 61 | -(UISlider *)addSlider:(NSString *)name; 62 | -(UIProgressView *)addProgress:(NSString *)name; 63 | 64 | -(UILabel*)addLabel:(NSString*)name; 65 | -(UILabel*)addLabel:(NSString*)name text:(NSString*)text; 66 | -(UILabel*)addLabel:(NSString*)name text:(NSString*)text font:(CGFloat)px; 67 | -(UILabel*)addLabel:(NSString*)name text:(NSString*)text font:(CGFloat)px color:(id)colorOrHex; 68 | -(UILabel*)addLabel:(NSString*)name text:(NSString*)text font:(CGFloat)px color:(id)colorOrHex row:(NSInteger)num; 69 | -(UIImageView*)addImageView:(NSString*)name; 70 | -(UIImageView*)addImageView:(NSString*)name img:(id)imgOrName; 71 | -(UIImageView*)addImageView:(NSString*)name img:(id)imgOrName direction:(XYFlag)direction; 72 | 73 | -(UITextField*)addTextField:(NSString*)name; 74 | -(UITextField*)addTextField:(NSString*)name placeholder:(NSString*)placeholder; 75 | -(UITextField*)addTextField:(NSString*)name placeholder:(NSString*)placeholder font:(CGFloat)px; 76 | -(UITextField*)addTextField:(NSString*)name placeholder:(NSString*)placeholder font:(CGFloat)px color:(id)colorOrHex; 77 | -(UITextView*)addTextView:(NSString*)name; 78 | -(UITextView*)addTextView:(NSString*)name placeholder:(NSString*)placeholder; 79 | -(UITextView*)addTextView:(NSString*)name placeholder:(NSString*)placeholder font:(CGFloat)px; 80 | -(UITextView*)addTextView:(NSString*)name placeholder:(NSString*)placeholder font:(CGFloat)px color:(id)colorOrHex; 81 | 82 | -(UIButton*)addButton:(NSString*)name; 83 | -(UIButton*)addButton:(NSString*)name buttonType:(UIButtonType)buttonType; 84 | -(UIButton*)addButton:(NSString*)name img:(id)imgOrName; 85 | -(UIButton*)addButton:(NSString*)name title:(NSString*)title; 86 | -(UIButton*)addButton:(NSString*)name title:(NSString*)title font:(CGFloat)px; 87 | -(UIButton*)addButton:(NSString*)name title:(NSString*)title font:(CGFloat)px color:(id)colorOrHex; 88 | -(UIButton*)addButton:(NSString*)name title:(NSString*)title font:(CGFloat)px color:(id)colorOrHex img:(id)imgOrName; 89 | -(UIButton*)addButton:(NSString*)name title:(NSString*)title font:(CGFloat)px color:(id)colorOrHex bgImg:(id)bgImgOrName; 90 | 91 | -(UIView*)addLine:name color:(id)colorOrHex; 92 | -(UIScrollView*)addScrollView:(NSString*)name; 93 | -(UIScrollView *)addScrollView:(NSString*)name direction:(XYFlag)direction; 94 | -(UIScrollView *)addScrollView:(NSString*)name direction:(XYFlag)direction isImageFull:(BOOL)isImageFull; 95 | //-(UIScrollView *)addScrollView:(NSString*)name direction:(XYFlag)direction img:(id)imgOrName,...NS_REQUIRES_NIL_TERMINATION; 96 | //-(UIScrollView *)addScrollView:(NSString*)name direction:(XYFlag)direction imgArray:(NSArray*)imgArray; 97 | -(UIPickerView*)addPickerView:(NSString*)name; 98 | -(UITableView*)addTableView:(NSString*)name; 99 | -(UITableView*)addTableView:(NSString*)name style:(UITableViewStyle)style; 100 | -(UICollectionView*)addCollectionView:(NSString*)name; 101 | -(UICollectionView*)addCollectionView:(NSString*)name layout:(UICollectionViewLayout*)layout; 102 | @end 103 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUIImage.m: -------------------------------------------------------------------------------- 1 | // 2 | // STUIImage.m 3 | // 4 | // Created by 陈裕强 on 2020/8/19. 5 | // 6 | 7 | #import "STUIImage.h" 8 | #import "STUIViewEvent.h" 9 | #import "STCategory.h" 10 | @implementation UIImage(ST) 11 | static char nameChar='n'; 12 | -(NSString *)name 13 | { 14 | return (NSString*)objc_getAssociatedObject(self, &nameChar); 15 | } 16 | -(void)setName:(NSString *)name 17 | { 18 | objc_setAssociatedObject(self, &nameChar, name, OBJC_ASSOCIATION_COPY_NONATOMIC); 19 | } 20 | -(NSData*)compress:(NSInteger)maxKb 21 | { 22 | // Compress by quality 23 | NSInteger maxLength=maxKb*1024;//转字节处理 24 | CGFloat quality = 1; 25 | NSData *data = UIImageJPEGRepresentation(self, quality); 26 | if (data.length <= maxLength || maxKb<=0) return data; 27 | 28 | CGFloat max = 1; 29 | CGFloat min = 0; 30 | for (int i = 0; i < 7; ++i) 31 | { 32 | quality = (max + min) / 2; 33 | data = UIImageJPEGRepresentation(self, quality); 34 | if (data.length < maxLength * 0.8) { 35 | min = quality; 36 | } else if (data.length > maxLength) { 37 | max = quality; 38 | } else { 39 | break; 40 | } 41 | } 42 | return data; 43 | } 44 | static char afterImageSaveBlockChar='c'; 45 | -(OnAfterImageSave)afterImageSaveBlock 46 | { 47 | return (OnAfterImageSave)objc_getAssociatedObject(self, &afterImageSaveBlockChar); 48 | } 49 | -(void)setAfterImageSaveBlock:(OnAfterImageSave)afterImageSaveBlock 50 | { 51 | objc_setAssociatedObject(self, &afterImageSaveBlockChar, afterImageSaveBlock, OBJC_ASSOCIATION_COPY_NONATOMIC); 52 | } 53 | -(void)save:(OnAfterImageSave)afterSaveBlock 54 | { 55 | self.afterImageSaveBlock=afterSaveBlock; 56 | UIImageWriteToSavedPhotosAlbum(self, self, @selector(afterImageSave:error:contextInfo:),nil); 57 | } 58 | - (void)afterImageSave:(UIImage *)image error:(NSError *)error contextInfo:(void *)contextInfo 59 | { 60 | if(self.afterImageSaveBlock) 61 | { 62 | self.afterImageSaveBlock(error); 63 | self.afterImageSaveBlock = nil; 64 | } 65 | } 66 | - (UIImage *)reSize:(CGSize)maxSize 67 | { 68 | return [self reSize:maxSize point:CGPointZero]; 69 | } 70 | -(UIImage *)reSize:(CGSize)maxSize point:(CGPoint)point 71 | { 72 | //[self width:maxSize.width height:maxSize.height]; 73 | UIImage *image=self; 74 | if (image.size.width < maxSize.width && image.size.height < maxSize.height) return image; 75 | CGFloat imageW = image.size.width; 76 | CGFloat imageH = image.size.height; 77 | CGFloat k = 0.0f; 78 | CGSize size = CGSizeMake(maxSize.width, maxSize.height); 79 | if (image.size.width > maxSize.width) 80 | { 81 | k = image.size.width / maxSize.width; 82 | imageH = ceil(image.size.height / k); 83 | size = CGSizeMake(maxSize.width, imageH); 84 | } 85 | if (imageH > maxSize.height) { 86 | k = image.size.height / maxSize.height; 87 | imageW = ceil(image.size.width / k); 88 | size = CGSizeMake(imageW, maxSize.height); 89 | } 90 | UIGraphicsBeginImageContext(size); 91 | [image drawInRect:CGRectMake(point.x, point.y, size.width, size.height)]; 92 | image = UIGraphicsGetImageFromCurrentImageContext(); 93 | UIGraphicsEndPDFContext(); 94 | return image; 95 | } 96 | -(NSData *)data 97 | { 98 | return UIImagePNGRepresentation(self); 99 | } 100 | -(UIImage *)drawIn:(CGSize)size point:(CGPoint)point 101 | { 102 | // Setup a new context with the correct size 103 | UIGraphicsBeginImageContextWithOptions(size,NO,0.0); 104 | CGContextRef context = UIGraphicsGetCurrentContext(); 105 | UIGraphicsPushContext(context); 106 | 107 | // Now we can draw anything we want into this new context. 108 | [self drawAtPoint:point]; 109 | 110 | // Clean up and get the new image. 111 | UIGraphicsPopContext(); 112 | UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 113 | UIGraphicsEndImageContext(); 114 | return newImage; 115 | } 116 | +(UIImage*)toImage:(id)imgOrName 117 | { 118 | if([imgOrName isKindOfClass:[NSString class]]) 119 | { 120 | NSString* name=(NSString*)imgOrName; 121 | if([name startWith:@"http://"] || [name startWith:@"https://"]) 122 | { 123 | return nil;//------------------------------------------------------------------------------------- 124 | } 125 | else 126 | { 127 | UIImage *img=[UIImage imageNamed:imgOrName]; 128 | img.name=imgOrName; 129 | return img; 130 | } 131 | } 132 | else if([imgOrName isKindOfClass:[NSData class]]) 133 | { 134 | return [UIImage imageWithData:imgOrName]; 135 | } 136 | else if([imgOrName isKindOfClass:[UIImage class]]) 137 | { 138 | return imgOrName; 139 | } 140 | else if([imgOrName isKindOfClass:[UIImageView class]]) 141 | { 142 | return ((UIImageView*)imgOrName).image; 143 | } 144 | return nil; 145 | } 146 | -(CGSize)getMaxScale:(CGSize)scaleSize 147 | { 148 | return scaleSize; 149 | } 150 | @end 151 | -------------------------------------------------------------------------------- /Sagit/Category/Object/STNSMutableDictionary.m: -------------------------------------------------------------------------------- 1 | // 2 | // STNSMutableDictionary.m 3 | // 4 | // Created by 陈裕强 on 2020/8/18. 5 | // 6 | 7 | #import "STNSMutableDictionary.h" 8 | #import "STCategory.h" 9 | @implementation NSMutableDictionary(ST) 10 | 11 | +(instancetype)share 12 | { 13 | static NSMutableDictionary *_share = nil; 14 | static dispatch_once_t onceToken; 15 | dispatch_once(&onceToken, ^{ 16 | _share = [NSMutableDictionary new]; 17 | }); 18 | return _share; 19 | } 20 | 21 | -(BOOL)has:(NSString*)key{ 22 | return self[key]!=nil; 23 | } 24 | -(id)get:(NSString*)key 25 | { 26 | return self[key]; 27 | } 28 | -(id)getWithIgnoreCase:(NSString *)key 29 | { 30 | id v=self[key]; 31 | if(v!=nil) 32 | { 33 | return v; 34 | } 35 | NSString *lowerKey=[key toLower]; 36 | for (NSString* k in self) { 37 | if([lowerKey isEqual:[k toLower]]) 38 | { 39 | return self[k]; 40 | } 41 | } 42 | return nil; 43 | } 44 | -(void)set:(NSString*)key value:(id)value 45 | { 46 | if(value!=nil) 47 | { 48 | [self setObject:value forKey:key]; 49 | } 50 | else 51 | { 52 | [self remove:key]; 53 | } 54 | } 55 | 56 | -(void)remove:(NSString*)key 57 | { 58 | NSArray *items=[key split:@","]; 59 | for (NSString* item in items) 60 | { 61 | [self removeObjectForKey:item]; 62 | } 63 | 64 | } 65 | -(NSString*)toJson 66 | { 67 | return [NSJSONSerialization dicToJson:self]; 68 | } 69 | 70 | #pragma mark CreateFormEntity 71 | +(id)initWithJsonOrEntity:(id)jsonOrEntity 72 | { 73 | if([jsonOrEntity isKindOfClass:[NSString class]]) 74 | { 75 | return [NSMutableDictionary creteFromJson:jsonOrEntity]; 76 | } 77 | return [NSMutableDictionary creteFromEntity:jsonOrEntity]; 78 | } 79 | 80 | //!把格式化的JSON格式的字符串转换成字典 81 | + (NSMutableDictionary *)creteFromJson:(NSString *)json { 82 | if (json == nil) { 83 | return nil; 84 | } 85 | 86 | NSData *jsonData = [json dataUsingEncoding:NSUTF8StringEncoding]; 87 | NSError *err; 88 | NSMutableDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData 89 | options:NSJSONReadingMutableContainers 90 | error:&err]; 91 | if(err) { 92 | NSLog(@"json解析失败:%@",err); 93 | return nil; 94 | } 95 | return dic; 96 | } 97 | + (NSMutableDictionary*)creteFromEntity:(id)obj 98 | { 99 | NSMutableDictionary *dic = [NSMutableDictionary dictionary]; 100 | unsigned int propsCount; 101 | objc_property_t *props = class_copyPropertyList([obj class], &propsCount);//获得属性列表 102 | 103 | //判断属性是否需要忽略 104 | SEL sel = NSSelectorFromString(@"isIgnore:"); 105 | BOOL hasMethod=[obj respondsToSelector:sel]; 106 | for(int i = 0;i < propsCount; i++) 107 | { 108 | objc_property_t prop = props[i]; 109 | NSString *propName = [NSString stringWithUTF8String:property_getName(prop)];//获得属性的名称 110 | 111 | if (hasMethod && [obj performSelector:sel withObject:propName]) { 112 | continue; 113 | } 114 | id value = [obj valueForKey:propName];//kvc读值 115 | if(value == nil) 116 | { 117 | value = [NSNull null]; 118 | } 119 | else 120 | { 121 | value = [NSMutableDictionary getEntityValue:value];//自定义处理数组,字典,其他类 122 | } 123 | [dic setObject:value forKey:propName]; 124 | } 125 | return dic; 126 | } 127 | + (id)getEntityValue:(id)obj 128 | { 129 | if([obj isKindOfClass:[NSArray class]] || [obj isKindOfClass:[NSMutableArray class]]) 130 | { 131 | NSArray *objarr = obj; 132 | NSMutableArray *arr = [NSMutableArray arrayWithCapacity:objarr.count]; 133 | for(int i = 0;i < objarr.count; i++) 134 | { 135 | [arr setObject:[NSMutableDictionary getEntityValue:[objarr objectAtIndex:i]] atIndexedSubscript:i]; 136 | } 137 | return arr; 138 | } 139 | else if([obj isKindOfClass:[NSDictionary class]] || [obj isKindOfClass:[NSMutableDictionary class]]) 140 | { 141 | NSDictionary *objdic = obj; 142 | NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithCapacity:[objdic count]]; 143 | for(NSString *key in objdic.allKeys) 144 | { 145 | [dic setObject:[self getEntityValue:[objdic objectForKey:key]] forKey:key];//对字典类型进行解析,递归调用 146 | } 147 | return dic; 148 | } 149 | else 150 | { 151 | NSString* className= NSStringFromClass([obj class]); 152 | if([className startWith:@"NS"] || [className startWith:@"__NS"]) 153 | { 154 | return obj; 155 | } 156 | if([className isEqual:@"BOOL"] || [className isEqual:@"float"] || [className isEqual:@"int"] || [className isEqual:@"long"] 157 | || [className isEqual:@"double"] || [className isEqual:@"short"] || [className isEqual:@"Block"] ) 158 | { 159 | return obj; 160 | } 161 | } 162 | return [NSMutableDictionary creteFromEntity:obj];//对其他class解析,递归调用 163 | } 164 | @end 165 | 166 | 167 | -------------------------------------------------------------------------------- /Sagit/STTool/Tool/LocationConverter.m: -------------------------------------------------------------------------------- 1 | 2 | #import "LocationConverter.h" 3 | #import 4 | #define LAT_OFFSET_0(x,y) -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * sqrt(fabs(x)) 5 | #define LAT_OFFSET_1 (20.0 * sin(6.0 * x * M_PI) + 20.0 * sin(2.0 * x * M_PI)) * 2.0 / 3.0 6 | #define LAT_OFFSET_2 (20.0 * sin(y * M_PI) + 40.0 * sin(y / 3.0 * M_PI)) * 2.0 / 3.0 7 | #define LAT_OFFSET_3 (160.0 * sin(y / 12.0 * M_PI) + 320 * sin(y * M_PI / 30.0)) * 2.0 / 3.0 8 | 9 | #define LON_OFFSET_0(x,y) 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * sqrt(fabs(x)) 10 | #define LON_OFFSET_1 (20.0 * sin(6.0 * x * M_PI) + 20.0 * sin(2.0 * x * M_PI)) * 2.0 / 3.0 11 | #define LON_OFFSET_2 (20.0 * sin(x * M_PI) + 40.0 * sin(x / 3.0 * M_PI)) * 2.0 / 3.0 12 | #define LON_OFFSET_3 (150.0 * sin(x / 12.0 * M_PI) + 300.0 * sin(x / 30.0 * M_PI)) * 2.0 / 3.0 13 | 14 | #define RANGE_LON_MAX 137.8347 15 | #define RANGE_LON_MIN 72.004 16 | #define RANGE_LAT_MAX 55.8271 17 | #define RANGE_LAT_MIN 0.8293 18 | // jzA = 6378245.0, 1/f = 298.3 19 | // b = a * (1 - f) 20 | // ee = (a^2 - b^2) / a^2; 21 | #define jzA 6378245.0 22 | #define jzEE 0.00669342162296594323 23 | 24 | 25 | 26 | @implementation LocationConverter 27 | 28 | + (double)transformLat:(double)x bdLon:(double)y 29 | { 30 | double ret = LAT_OFFSET_0(x, y); 31 | ret += LAT_OFFSET_1; 32 | ret += LAT_OFFSET_2; 33 | ret += LAT_OFFSET_3; 34 | return ret; 35 | } 36 | 37 | + (double)transformLon:(double)x bdLon:(double)y 38 | { 39 | double ret = LON_OFFSET_0(x, y); 40 | ret += LON_OFFSET_1; 41 | ret += LON_OFFSET_2; 42 | ret += LON_OFFSET_3; 43 | return ret; 44 | } 45 | 46 | + (BOOL)outOfChina:(double)lat bdLon:(double)lon 47 | { 48 | if (lon < RANGE_LON_MIN || lon > RANGE_LON_MAX) 49 | return true; 50 | if (lat < RANGE_LAT_MIN || lat > RANGE_LAT_MAX) 51 | return true; 52 | return false; 53 | } 54 | 55 | + (CLLocationCoordinate2D)gcj02Encrypt:(double)ggLat bdLon:(double)ggLon 56 | { 57 | CLLocationCoordinate2D resPoint; 58 | double mgLat; 59 | double mgLon; 60 | if ([self outOfChina:ggLat bdLon:ggLon]) { 61 | resPoint.latitude = ggLat; 62 | resPoint.longitude = ggLon; 63 | return resPoint; 64 | } 65 | double dLat = [self transformLat:(ggLon - 105.0)bdLon:(ggLat - 35.0)]; 66 | double dLon = [self transformLon:(ggLon - 105.0) bdLon:(ggLat - 35.0)]; 67 | double radLat = ggLat / 180.0 * M_PI; 68 | double magic = sin(radLat); 69 | magic = 1 - jzEE * magic * magic; 70 | double sqrtMagic = sqrt(magic); 71 | dLat = (dLat * 180.0) / ((jzA * (1 - jzEE)) / (magic * sqrtMagic) * M_PI); 72 | dLon = (dLon * 180.0) / (jzA / sqrtMagic * cos(radLat) * M_PI); 73 | mgLat = ggLat + dLat; 74 | mgLon = ggLon + dLon; 75 | 76 | resPoint.latitude = mgLat; 77 | resPoint.longitude = mgLon; 78 | return resPoint; 79 | } 80 | 81 | + (CLLocationCoordinate2D)gcj02Decrypt:(double)gjLat gjLon:(double)gjLon { 82 | CLLocationCoordinate2D gPt = [self gcj02Encrypt:gjLat bdLon:gjLon]; 83 | double dLon = gPt.longitude - gjLon; 84 | double dLat = gPt.latitude - gjLat; 85 | CLLocationCoordinate2D pt; 86 | pt.latitude = gjLat - dLat; 87 | pt.longitude = gjLon - dLon; 88 | return pt; 89 | } 90 | 91 | + (CLLocationCoordinate2D)bd09Decrypt:(double)bdLat bdLon:(double)bdLon 92 | { 93 | CLLocationCoordinate2D gcjPt; 94 | double x = bdLon - 0.0065, y = bdLat - 0.006; 95 | double z = sqrt(x * x + y * y) - 0.00002 * sin(y * M_PI); 96 | double theta = atan2(y, x) - 0.000003 * cos(x * M_PI); 97 | gcjPt.longitude = z * cos(theta); 98 | gcjPt.latitude = z * sin(theta); 99 | return gcjPt; 100 | } 101 | 102 | +(CLLocationCoordinate2D)bd09Encrypt:(double)ggLat bdLon:(double)ggLon 103 | { 104 | CLLocationCoordinate2D bdPt; 105 | double x = ggLon, y = ggLat; 106 | double z = sqrt(x * x + y * y) + 0.00002 * sin(y * M_PI); 107 | double theta = atan2(y, x) + 0.000003 * cos(x * M_PI); 108 | bdPt.longitude = z * cos(theta) + 0.0065; 109 | bdPt.latitude = z * sin(theta) + 0.006; 110 | return bdPt; 111 | } 112 | 113 | 114 | + (CLLocationCoordinate2D)wgs84ToGcj02:(CLLocationCoordinate2D)location 115 | { 116 | return [self gcj02Encrypt:location.latitude bdLon:location.longitude]; 117 | } 118 | 119 | + (CLLocationCoordinate2D)gcj02ToWgs84:(CLLocationCoordinate2D)location 120 | { 121 | return [self gcj02Decrypt:location.latitude gjLon:location.longitude]; 122 | } 123 | 124 | 125 | + (CLLocationCoordinate2D)wgs84ToBd09:(CLLocationCoordinate2D)location 126 | { 127 | CLLocationCoordinate2D gcj02Pt = [self gcj02Encrypt:location.latitude 128 | bdLon:location.longitude]; 129 | return [self bd09Encrypt:gcj02Pt.latitude bdLon:gcj02Pt.longitude] ; 130 | } 131 | 132 | + (CLLocationCoordinate2D)gcj02ToBd09:(CLLocationCoordinate2D)location 133 | { 134 | return [self bd09Encrypt:location.latitude bdLon:location.longitude]; 135 | } 136 | 137 | + (CLLocationCoordinate2D)bd09ToGcj02:(CLLocationCoordinate2D)location 138 | { 139 | return [self bd09Decrypt:location.latitude bdLon:location.longitude]; 140 | } 141 | 142 | + (CLLocationCoordinate2D)bd09ToWgs84:(CLLocationCoordinate2D)location 143 | { 144 | CLLocationCoordinate2D gcj02 = [self bd09ToGcj02:location]; 145 | return [self gcj02Decrypt:gcj02.latitude gjLon:gcj02.longitude]; 146 | } 147 | 148 | @end 149 | -------------------------------------------------------------------------------- /Sagit/Category/Object/STDictionary.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // Copyright © 2017-2027年. All rights reserved. 6 | // 7 | #import "STDictionary.h" 8 | #import "STString.h" 9 | #import "STCategory.h" 10 | @implementation NSDictionary(ST) 11 | 12 | -(NSMutableDictionary *)toNSMutableDictionary 13 | { 14 | NSMutableDictionary*dic=[NSMutableDictionary new]; 15 | for (NSString*key in self) { 16 | [dic set:key value:self[key]]; 17 | } 18 | return dic; 19 | } 20 | -(id)firstObject 21 | { 22 | if(self.count>0) 23 | { 24 | for (NSString* key in self) { 25 | return self[key]; 26 | } 27 | } 28 | return nil; 29 | } 30 | -(id)get:(NSString*)key 31 | { 32 | return self[key]; 33 | } 34 | -(id)getWithIgnoreCase:(NSString *)key 35 | { 36 | id v=self[key]; 37 | if(v!=nil) 38 | { 39 | return v; 40 | } 41 | NSString *lowerKey=[key toLower]; 42 | for (NSString* k in self) { 43 | if([lowerKey isEqual:[k toLower]]) 44 | { 45 | return self[k]; 46 | } 47 | } 48 | return nil; 49 | } 50 | 51 | -(BOOL)has:(NSString*)key{ 52 | return self[key]!=nil; 53 | } 54 | -(NSString*)toJson{ 55 | return [NSJSONSerialization dicToJson:self]; 56 | } 57 | //!把格式化的JSON格式的字符串转换成字典 58 | +(id)initWithJsonOrEntity:(id)jsonOrEntity 59 | { 60 | return [NSMutableDictionary initWithJsonOrEntity:jsonOrEntity]; 61 | } 62 | 63 | #pragma mark ToEntity 64 | +(void)dictionaryToEntity:(NSDictionary*)dic to:(id)entity 65 | { 66 | if(entity==nil || dic==nil || dic.count==0){return;} 67 | unsigned int propsCount; 68 | objc_property_t *props = class_copyPropertyList([entity class], &propsCount);//获得属性列表 69 | //Class superClass=class_getSuperclass([entity class]); 70 | //判断属性是否需要忽略 71 | SEL sel = NSSelectorFromString(@"isIgnore:"); 72 | BOOL hasMethod=[entity respondsToSelector:sel]; 73 | 74 | for(int i = 0;i < propsCount; i++) 75 | { 76 | objc_property_t prop = props[i]; 77 | NSString *propName = [NSString stringWithUTF8String:property_getName(prop)];//获得属性的名称 78 | id v=[dic getWithIgnoreCase:propName]; 79 | if(v==nil || [v isKindOfClass:[NSNull class]]) 80 | { 81 | continue; 82 | } 83 | if (hasMethod && [entity performSelector:sel withObject:propName]) { 84 | continue; 85 | } 86 | NSString *atts= [NSString stringWithUTF8String:property_getAttributes(prop)]; 87 | if([atts startWith:@"R"]){continue;} 88 | 89 | if([atts contains:@"\"NS"] || [atts contains:@"\",&,N,V_photos" 0x0000600002e9a200 94 | { 95 | NSString *className= [[[atts split:@","][0] split:@"<"][1] trimEnd:@">\""]; 96 | Class class=NSClassFromString(className); 97 | if(class!=nil)//view 98 | { 99 | NSMutableArray *arr=[NSMutableArray new]; 100 | NSArray *arrValue=(NSArray*)v; 101 | for (int i=0; i\",&,N,V_user" 0x0000600000df0e80 115 | Class class=NSClassFromString(className); 116 | if(class!=nil)//view 117 | { 118 | id obj=[[class alloc] init]; 119 | [self dictionaryToEntity:v to:obj]; 120 | [entity setValue:obj forKey:propName]; 121 | } 122 | continue;; 123 | } 124 | 125 | [entity setValue:v forKey:propName]; 126 | 127 | } 128 | free(props); 129 | } 130 | @end 131 | 132 | @implementation NSJSONSerialization(ST) 133 | 134 | +(NSString *)dicToJson:(NSDictionary*)dic 135 | { 136 | if(dic==nil || dic.count==0) 137 | { 138 | return @"{}"; 139 | } 140 | NSString *json = nil; 141 | NSError *error; 142 | NSData *jsonData = [self dataWithJSONObject:dic options:0 error:&error]; 143 | if (jsonData) 144 | { 145 | json = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; 146 | } 147 | return json; 148 | } 149 | + (NSString *)arrayToJson:(NSArray *)array 150 | { 151 | if(array==nil || array.count==0) 152 | { 153 | return @"[]"; 154 | } 155 | NSString *json = nil; 156 | NSError *error; 157 | NSData *jsonData = [self dataWithJSONObject:array options:0 error:&error]; 158 | if (jsonData) 159 | { 160 | json = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; 161 | } 162 | return json; 163 | } 164 | @end 165 | -------------------------------------------------------------------------------- /Sagit/Category/Object/STDate.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // Copyright © 2017-2027年. All rights reserved. 6 | // 7 | #import "STDate.h" 8 | #import "STString.h" 9 | #import "STDefineFunc.h" 10 | @implementation NSDate(ST) 11 | -(NSString *)toString{return [self toString:nil];} 12 | -(NSString *)toString:(NSString*)formatter{ 13 | if([NSString isNilOrEmpty:formatter]){formatter=@"yyyy-MM-dd HH:mm:ss";} 14 | NSDateComponents *com=self.component; 15 | return [[[[[[[formatter replace:@"yyyy" with:[self intToString:com.year len:4]] 16 | replace:@"MM" with:[self intToString:com.month]] 17 | replace:@"dd" with:[self intToString:com.day]] 18 | replace:@"HH" with:[self intToString:com.hour]] 19 | replace:@"mm" with:[self intToString:com.minute]] 20 | replace:@"ss" with:[self intToString:com.second]] 21 | replace:@"SSS" with:[self intToString:com.nanosecond len:3]]; 22 | } 23 | -(NSString*)intToString:(NSInteger)value 24 | { 25 | return [self intToString:value len:2]; 26 | } 27 | -(NSString*)intToString:(NSInteger)value len:(NSInteger)len 28 | { 29 | NSString *num=STNumString(value); 30 | if(num.length>len) 31 | { 32 | return [num substringWithRange:NSMakeRange(0, len)]; 33 | } 34 | else if(num.length0 && textView.isFirstResponder)// && CGPointEqualToPoint(CGPointZero, baseView.frame.origin) 75 | { 76 | NSInteger screenY=textView.stScreenY*Ypt; 77 | NSInteger textHeight=textView.frame.size.height; 78 | NSInteger moveY=screenY+textHeight+kbHeight-[UIScreen mainScreen].bounds.size.height; 79 | if(moveY>0) 80 | { 81 | CGRect frame=baseView.frame; 82 | frame.origin.y-=(moveY+8); 83 | [baseView moveTo:frame]; 84 | //注册键盘回收事件 85 | //注册键盘出现与隐藏时候的通知 86 | [[NSNotificationCenter defaultCenter] addObserver:self 87 | selector:@selector(keyboardHide:) 88 | name:UIKeyboardWillHideNotification 89 | object:nil]; 90 | } 91 | } 92 | } 93 | //第一次执行了两次(216、258) 先没有文字,然后出现提示文字(+42pt) 94 | -(void)keyboardShow:(NSNotification*)notify 95 | { 96 | //[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil]; 97 | NSDictionary *info = [notify userInfo]; 98 | CGRect keyboardRect = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];//键盘的frame 99 | self.keyboardHeight=keyboardRect.size.height; 100 | //键盘高度遮挡事件处理 101 | UIView *textView=self.editingTextUI; 102 | if(textView && textView.isFirstResponder) 103 | { 104 | UIView *baseView=textView.baseView;// self.rootViewController.view;//这个view包含已 105 | [baseView backToOrigin]; 106 | [self moveView:textView]; 107 | } 108 | } 109 | -(void)keyboardHide:(NSNotification*)notify 110 | { 111 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil]; 112 | UIView *textView=self.editingTextUI; 113 | if(textView) 114 | { 115 | UIView *baseView=textView.baseView;// self.rootViewController.view;//这个view包含已 116 | [baseView backToOrigin]; 117 | } 118 | } 119 | 120 | +(id)mainWindow 121 | { 122 | 123 | UIApplication *app=[UIApplication sharedApplication]; 124 | Class c= NSClassFromString(@"SceneDelegate"); 125 | if(c==nil) 126 | { 127 | if(app.delegate && app.delegate.window) 128 | { 129 | return app.delegate.window; 130 | } 131 | 132 | } 133 | if (@available(iOS 13.0, *)) { 134 | // 获取keywindow 135 | // NSArray *array = app.windows; 136 | // UIWindow *window = [array objectAtIndex:0]; 137 | // 138 | // // 判断取到的window是不是keywidow 139 | // if (!window.hidden || window.isKeyWindow) { 140 | // return window; 141 | // } 142 | // 143 | // 如果上面的方式取到的window 不是keywidow时 通过遍历windows取keywindow 144 | for (UIWindow *window in app.windows) { 145 | if (!window.hidden || window.isKeyWindow) { 146 | return window; 147 | } 148 | } 149 | } 150 | 151 | UIWindow *win=app.keyWindow; 152 | if(win!=nil) 153 | { 154 | return win; 155 | } 156 | return app.delegate.window; 157 | } 158 | @end 159 | 160 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUITextField.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import "STUITextField.h" 10 | #import "STUIView.h" 11 | #import "STDefineUI.h" 12 | #import "STCategory.h" 13 | 14 | @implementation UITextField(ST) 15 | -(OnTextFieldEdit)onEdit 16 | { 17 | return [self key:@"onEdit"]; 18 | } 19 | -(void)setOnEdit:(OnTextFieldEdit)onEdit 20 | { 21 | [self key:@"onEdit" value:onEdit]; 22 | } 23 | #pragma mark 自定义追加属系统 24 | - (NSInteger)maxLength 25 | { 26 | NSString *max=[self key:@"maxLength"]; 27 | if(max) 28 | { 29 | return [max intValue]; 30 | } 31 | return 0; 32 | } 33 | - (UITextField*)maxLength:(NSInteger)length 34 | { 35 | if(length>0 && self.maxLength==0) 36 | { 37 | //注册事件 38 | [self addTarget:self action:@selector(onTextChange:) forControlEvents:UIControlEventEditingChanged]; 39 | } 40 | [self key:@"maxLength" value:[@(length) stringValue]]; 41 | 42 | return self; 43 | } 44 | 45 | #pragma mark 扩展系统属性 46 | -(UITextField*)keyboardType:(UIKeyboardType)type 47 | { 48 | self.keyboardType=type; 49 | return self; 50 | } 51 | -(UITextField*)secureTextEntry:(BOOL)yesNo 52 | { 53 | self.secureTextEntry=yesNo; 54 | return self; 55 | } 56 | -(UITextField*)text:(NSString*)text 57 | { 58 | if([text isKindOfClass:[NSNull class]]) 59 | { 60 | text=@""; 61 | } 62 | if(self.maxLength>0 && text.length>self.maxLength) 63 | { 64 | text=[text substringToIndex:self.maxLength-1]; 65 | } 66 | self.text=text; 67 | return self; 68 | } 69 | -(UITextField*)font:(CGFloat)px 70 | { 71 | self.font=[UIFont toFont:px]; 72 | return self; 73 | } 74 | -(UITextField*)textColor:(id)colorOrHex 75 | { 76 | self.textColor=[UIColor toColor:colorOrHex]; 77 | return self; 78 | } 79 | -(UITextField*)textAlignment:(NSTextAlignment)value 80 | { 81 | self.textAlignment=value; 82 | return self; 83 | } 84 | -(UITextField*)placeholder:(NSString*)text 85 | { 86 | if([text isKindOfClass:[NSNull class]]) 87 | { 88 | text=@""; 89 | } 90 | self.placeholder=text; 91 | return self; 92 | } 93 | -(UITextField*)borderStyle:(UITextBorderStyle)style 94 | { 95 | self.borderStyle=style; 96 | return self; 97 | } 98 | -(UITextField*)enabled:(BOOL)yesNo 99 | { 100 | self.enabled=yesNo; 101 | return self; 102 | } 103 | #pragma mark TextFiled 协议实现 104 | -(void)onTextChange:(UITextField*)textField 105 | { 106 | if(self.onEdit) 107 | { 108 | self.onEdit(textField,NO); 109 | } 110 | NSString *text=textField.text; 111 | if(self.maxLength>0 && text.length>self.maxLength) 112 | { 113 | textField.text=[text substringWithRange:NSMakeRange(0, self.maxLength)]; 114 | } 115 | } 116 | //ios 13 117 | - (void)textFieldDidChangeSelection:(UITextField *)textField 118 | { 119 | [self resetCursorToEnd:textField]; 120 | [self onTextChange:textField]; 121 | } 122 | 123 | -(void)resetCursorToEnd:(UITextField *)textField 124 | { 125 | if(textField.text.length>0) 126 | { 127 | NSRange rang= [self getRange:textField]; 128 | if(rang.location==0) 129 | { 130 | switch (textField.keyboardType) 131 | { 132 | case UIKeyboardTypePhonePad: 133 | case UIKeyboardTypeNumberPad: 134 | case UIKeyboardTypeNumbersAndPunctuation: 135 | case UIKeyboardTypeDecimalPad: 136 | case UIKeyboardTypeASCIICapableNumberPad: 137 | [self cursorLocation:textField index:textField.text.length]; 138 | break; 139 | } 140 | } 141 | } 142 | } 143 | 144 | // 获取光标位置 145 | -(NSRange)getRange:(UITextField *)textField 146 | { 147 | UITextPosition* beginning = textField.beginningOfDocument; 148 | 149 | UITextRange* selectedRange = textField.selectedTextRange; 150 | UITextPosition* selectionStart = selectedRange.start; 151 | UITextPosition* selectionEnd = selectedRange.end; 152 | 153 | NSInteger location = [textField offsetFromPosition:beginning toPosition:selectionStart]; 154 | NSInteger length = [textField offsetFromPosition:selectionStart toPosition:selectionEnd]; 155 | 156 | return NSMakeRange(location, length); 157 | } 158 | - (void)cursorLocation:(UITextField*)textField index:(NSInteger)index 159 | 160 | { 161 |     NSRange range =NSMakeRange(index,0); 162 |     UITextPosition *start = [textField positionFromPosition:[textField beginningOfDocument]offset:range.location]; 163 |     UITextPosition *end = [textField positionFromPosition:start offset:range.length]; 164 |     [textField setSelectedTextRange:[textField textRangeFromPosition:start toPosition:end]]; 165 | } 166 | 167 | //- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 168 | //{//此方法不支持中文(只能在change事件中处理) 169 | // if (textField.maxLength>0 && range.location >=textField.maxLength) { 170 | // return NO; 171 | // } 172 | // return YES; 173 | 174 | 175 | //} 176 | - (void)textFieldDidBeginEditing:(UITextField *)textField // became first responder 177 | { 178 | self.window.editingTextUI=textField;//注册键盘遮挡事件 179 | if(self.onEdit) 180 | { 181 | self.onEdit(textField,NO); 182 | } 183 | } 184 | 185 | - (void)textFieldDidEndEditing:(UITextField *)textField 186 | { 187 | if(self.onEdit) 188 | { 189 | self.onEdit(textField,YES); 190 | } 191 | } 192 | -(void)dispose 193 | { 194 | if(self.maxLength>0) 195 | { 196 | [self removeTarget:self action:@selector(onTextChange:) forControlEvents:UIControlEventEditingChanged]; 197 | } 198 | } 199 | @end 200 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUIButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import "STUIButton.h" 10 | //#import 11 | #import "STDefineUI.h" 12 | #import "STUIView.h" 13 | #import "STUIViewAutoLayout.h" 14 | #import "STString.h" 15 | #import "STUIControl.h" 16 | #import "STSagit.h" 17 | #import "STDefineFunc.h" 18 | @implementation UIButton (ST) 19 | 20 | //static char ActionTag; 21 | // 22 | //- (void)addAction:(onAction)block { 23 | // objc_setAssociatedObject(self, &ActionTag, block, OBJC_ASSOCIATION_COPY_NONATOMIC); 24 | // [self addTarget:self action:@selector(action:) forControlEvents:UIControlEventTouchUpInside]; 25 | //} 26 | // 27 | //- (void)addClick:(onAction)block { 28 | // 29 | // [self addAction:block forControlEvents:UIControlEventTouchUpInside]; 30 | //} 31 | // 32 | //- (void)addAction:(onAction)block forControlEvents:(UIControlEvents)controlEvents { 33 | // objc_setAssociatedObject(self, &ActionTag, block, OBJC_ASSOCIATION_COPY_NONATOMIC); 34 | // [self addTarget:self action:@selector(action:) forControlEvents:controlEvents]; 35 | //} 36 | // 37 | //- (void)action:(id)sender { 38 | // onAction blockAction = (onAction)objc_getAssociatedObject(self, &ActionTag); 39 | // if (blockAction) { 40 | // blockAction(self); 41 | // } 42 | //} 43 | //复盖UIView的方法。 44 | //- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event { 45 | // CGRect bounds = self.bounds; 46 | // //若原热区小于44x44,则放大热区,否则保持原大小不变 47 | // CGFloat widthDelta = MAX(50.0 - bounds.size.width, 0); 48 | // CGFloat heightDelta = MAX(50.0 - bounds.size.height, 0); 49 | // bounds = CGRectInset(bounds, -0.5 * widthDelta, -0.5 * heightDelta); 50 | // return CGRectContainsPoint(bounds, point); 51 | //} 52 | #pragma mark 扩展系统属性 53 | -(UIButton*)backgroundImage:(id)img 54 | { 55 | [self backgroundImage:img forState:UIControlStateNormal]; 56 | return self; 57 | } 58 | -(UIButton*)backgroundImage:(id)img forState:(UIControlState)state 59 | { 60 | [self setBackgroundImage:[UIImage toImage:img] forState:state]; 61 | return self; 62 | } 63 | -(UIButton*)image:(id)img 64 | { 65 | [self image:img forState:UIControlStateNormal]; 66 | return self; 67 | } 68 | -(UIButton*)image:(id)img forState:(UIControlState)state 69 | { 70 | 71 | [self setImage:[UIImage toImage:img] forState:state]; 72 | 73 | return self; 74 | } 75 | -(UIButton*)title:(NSString*)title 76 | { 77 | [self setTitle:title forState:UIControlStateNormal]; 78 | return self; 79 | } 80 | -(UIButton*)title:(NSString*)title forState:(UIControlState)state 81 | { 82 | [self setTitle:title forState:state]; 83 | return self; 84 | } 85 | -(UIButton*)titleColor:(id)colorOrHex 86 | { 87 | [self titleColor:colorOrHex forState:UIControlStateNormal]; 88 | return self; 89 | } 90 | -(UIButton*)titleColor:(id)colorOrHex forState:(UIControlState)state 91 | { 92 | [self setTitleColor:[UIColor toColor:colorOrHex] forState:state]; 93 | return self; 94 | } 95 | -(UIButton*)titleFont:(CGFloat)px 96 | { 97 | self.titleLabel.font=[UIFont toFont:px]; 98 | return self; 99 | } 100 | -(UIButton*)adjustsImageWhenHighlighted:(BOOL)yesNo 101 | { 102 | self.adjustsImageWhenHighlighted=yesNo; 103 | return self; 104 | } 105 | -(UIButton*)stWidthToFit 106 | { 107 | [self layoutIfNeeded];//Button setImage 后,Lable的坐标不是即时移动的。 108 | UILabel *label=self.titleLabel; 109 | CGFloat labelWidth=label.stWidth; 110 | if(label.text.length>0) 111 | { 112 | CGSize size=[self.titleLabel.text sizeWithFont:label.font maxSize:self.frame.size]; 113 | //计算文字的长度 114 | labelWidth=MAX(labelWidth, size.width*Xpx); 115 | } 116 | CGFloat width=MAX(labelWidth+label.stX, self.imageView.stX+self.imageView.stWidth); 117 | [self width:width]; 118 | return self; 119 | } 120 | 121 | -(UIButton *)showTime:(NSInteger)second 122 | { 123 | return [self showTime:second resetStateOnEnd:YES]; 124 | } 125 | -(UIButton *)showTime:(NSInteger)second resetStateOnEnd:(BOOL)resetStateOnEnd 126 | { 127 | if(second>0) 128 | { 129 | if([self key:@"NSTimer"]) 130 | { 131 | [self key:@"newSecond" value:STNumString(second)]; 132 | return self;//直接返回 133 | } 134 | 135 | [self enabled:NO]; 136 | NSTimer *timer=[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(onTimer) userInfo:nil repeats:YES]; 137 | 138 | [self key:@"NSTimer" value:timer]; 139 | if(resetStateOnEnd) 140 | { 141 | [self key:@"defaultTitle" value:self.currentTitle]; 142 | } 143 | interval=second; 144 | [timer fire];//开启 145 | } 146 | return self; 147 | } 148 | static int interval=0; 149 | -(void)onTimer 150 | { 151 | 152 | NSString *newSecond=[self key:@"newSecond"]; 153 | if(newSecond) 154 | { 155 | interval=newSecond.integerValue; 156 | [self key:@"newSecond" value:nil];//移除key 157 | } 158 | else 159 | { 160 | [self title:[[@(interval)stringValue] append:@"s"]]; 161 | } 162 | interval--; 163 | if(interval<=-1)//==0的话到2s就恢复了,也不解为什么少了1。 164 | { 165 | if([self key:@"defaultTitle"]) 166 | { 167 | [self title:[self key:@"defaultTitle"]]; 168 | [self key:@"defaultTitle" value:nil]; 169 | } 170 | [self enabled:YES]; 171 | NSTimer *timer=[self key:@"NSTimer"]; 172 | if(timer) 173 | { 174 | [timer invalidate]; 175 | timer=nil; 176 | [self key:@"NSTimer" value:nil]; 177 | } 178 | if(self.onAfter) 179 | { 180 | self.onAfter(@"showTime",self); 181 | } 182 | } 183 | } 184 | -(void)dispose 185 | { 186 | NSTimer *timer=[self key:@"NSTimer"]; 187 | if(timer) 188 | { 189 | [timer invalidate]; 190 | timer=nil; 191 | } 192 | [super dispose]; 193 | } 194 | @end 195 | -------------------------------------------------------------------------------- /Sagit/Category/Object/STString.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // Copyright © 2017-2027年. All rights reserved. 6 | // 7 | 8 | #import "STString.h" 9 | #import "STDefineFunc.h" 10 | @implementation NSString(ST) 11 | //+(instancetype)format:(NSString *)format, ... 12 | //{ 13 | // va_list ap; 14 | // va_start(ap, format); 15 | // NSString *item; 16 | // while ((item = va_arg(ap, NSString *))) 17 | // { 18 | // if(item==nil) 19 | // { 20 | // item=@""; 21 | // } 22 | // } 23 | // NSString *result=[[NSString alloc] initWithFormat:format arguments:ap]; 24 | // va_end(ap); 25 | // return result; 26 | //} 27 | -(NSString *)reverse 28 | { 29 | NSMutableString *newString = [[NSMutableString alloc] initWithCapacity:self.length]; 30 | for (long i = self.length - 1; i >=0 ; i --) { 31 | unichar ch = [self characterAtIndex:i]; 32 | [newString appendFormat:@"%c",ch]; 33 | } 34 | return newString; 35 | 36 | } 37 | 38 | - (BOOL)isInt{ 39 | NSScanner* scan = [NSScanner scannerWithString:self]; 40 | int val; 41 | return[scan scanInt:&val] && [scan isAtEnd]; 42 | } 43 | 44 | //判断是否为浮点形: 45 | 46 | - (BOOL)isFloat{ 47 | NSScanner* scan = [NSScanner scannerWithString:self]; 48 | float val; 49 | return[scan scanFloat:&val] && [scan isAtEnd]; 50 | } 51 | -(NSString *)appendIfNotEndWith:(NSString *)string 52 | { 53 | if(![self endWith:string]) 54 | { 55 | return [self append:string]; 56 | } 57 | return self; 58 | } 59 | -(NSString *)append:(NSString *)string 60 | { 61 | return [NSString stringWithFormat:@"%@%@",self,string]; 62 | } 63 | -(NSString *)replace:(NSString *)a with:(NSString *)b 64 | { 65 | return [self replace:a with:b ignoreCase:NO]; 66 | } 67 | -(NSString *)replace:(NSString *)a with:(NSString *)b ignoreCase:(BOOL)ignoreCase 68 | { 69 | if(a==nil){return self;} 70 | if(b==nil){b=@"";} 71 | if(!ignoreCase) 72 | { 73 | return [self stringByReplacingOccurrencesOfString:a withString:b]; 74 | } 75 | NSRange range = NSMakeRange(0, [self length]); 76 | return [self stringByReplacingOccurrencesOfString:a withString:b options:NSCaseInsensitiveSearch range:range]; 77 | } 78 | -(NSArray*)split:(NSString*)separator 79 | { 80 | return [self componentsSeparatedByString:separator]; 81 | } 82 | -(NSString*)toUpper{return [self uppercaseString];} 83 | -(NSString*)toLower{return [self lowercaseString];} 84 | -(BOOL)startWith:(NSString *)value{return [self hasPrefix:value];} 85 | -(BOOL)endWith:(NSString *)value{return [self hasSuffix:value];} 86 | -(BOOL)contains:(NSString *)value{return [self containsString:value];} 87 | -(BOOL)contains:(NSString *)value ignoreCase:(BOOL)ignoreCase{return [self indexOf:value ignoreCase:ignoreCase]>=0;} 88 | -(BOOL)isEmpty{return [self isEqualToString:@""];} 89 | +(BOOL)isNilOrEmpty:(NSString*)value{return value==nil || [value isKindOfClass:[NSNull class]] || [value isEmpty];} 90 | -(BOOL)eq:(id)value 91 | { 92 | if([value isKindOfClass:[NSNumber class]]) 93 | { 94 | value=((NSNumber*)value).stringValue; 95 | } 96 | return [self isEqualToString:value]; 97 | } 98 | +(NSString *)toString:(id)value 99 | { 100 | return [NSString stringWithFormat:@"%@",value]; 101 | } 102 | +(NSString *)newGuid 103 | { 104 | CFUUIDRef theUUID = CFUUIDCreate(NULL); 105 | CFStringRef string = CFUUIDCreateString(NULL, theUUID); 106 | CFRelease(theUUID); 107 | return (__bridge NSString *)string; 108 | } 109 | -(NSString*)trim 110 | { 111 | return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 112 | } 113 | -(NSString *)trimStart:(NSString *)value 114 | { 115 | if(value==nil || ![self startWith:value]){return self;} 116 | return [self substringFromIndex:value.length]; 117 | } 118 | -(NSString *)trimEnd:(NSString *)value 119 | { 120 | if(value==nil || ![self endWith:value]){return self;} 121 | return [self substringToIndex:self.length-value.length]; 122 | } 123 | //!去除两位小数点的尾数0,如:13.00=》13,134.30=》134.3 124 | -(NSString *)trimDecimalZero 125 | { 126 | NSString *value= [[self trimEnd:@".00"] trimEnd:@".0"]; 127 | if([value contains:@"."]) 128 | { 129 | return [value trimEnd:@"0"]; 130 | } 131 | return value; 132 | } 133 | -(NSInteger)indexOf:(NSString*)searchString 134 | { 135 | return [self indexOf:searchString ignoreCase:NO]; 136 | } 137 | -(NSInteger)indexOf:(NSString*)searchString ignoreCase:(BOOL)ignoreCase 138 | { 139 | NSRange rnd=NSMakeRange(-1, 0); 140 | if(!ignoreCase) 141 | { 142 | rnd=[self rangeOfString:searchString]; 143 | } 144 | else 145 | { 146 | rnd=[self rangeOfString:searchString options:NSCaseInsensitiveSearch]; 147 | } 148 | return rnd.length>0?rnd.location:-1; 149 | } 150 | -(NSString*)firstCharUpper 151 | { 152 | if(self.length>0) 153 | { 154 | if(self.length==0) 155 | { 156 | return [NSString stringWithFormat:@"%c",STCharUpper([self characterAtIndex:0])]; 157 | } 158 | return [NSString stringWithFormat:@"%c%@",STCharUpper([self characterAtIndex:0]),[self substringFromIndex:1]]; 159 | } 160 | return self; 161 | } 162 | -(NSString*)firstCharLower 163 | { 164 | if(self.length>0) 165 | { 166 | if(self.length==0) 167 | { 168 | return [NSString stringWithFormat:@"%c",STCharLower([self characterAtIndex:0])]; 169 | } 170 | return [NSString stringWithFormat:@"%c%@",STCharLower([self characterAtIndex:0]),[self substringFromIndex:1]]; 171 | } 172 | return self; 173 | } 174 | - (NSString *)remove:(NSInteger)startIndex length:(NSInteger)length 175 | { 176 | NSMutableString *str=[NSMutableString stringWithString:self]; 177 | [str deleteCharactersInRange:NSMakeRange(startIndex, length)]; 178 | return str; 179 | } 180 | /** 181 | 获取字符串的大小 182 | txt:label或button的title 183 | font:字体大小 184 | size:允许最大size 185 | */ 186 | -(CGSize) sizeWithFont:font maxSize:(CGSize)maxSize 187 | { 188 | 189 | CGSize _size; 190 | #if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_6_1 191 | 192 | NSDictionary *attribute = @{NSFontAttributeName: font}; 193 | 194 | NSStringDrawingOptions options = NSStringDrawingTruncatesLastVisibleLine | 195 | 196 | NSStringDrawingUsesLineFragmentOrigin | 197 | 198 | NSStringDrawingUsesFontLeading; 199 | 200 | _size = [self boundingRectWithSize:maxSize options: options attributes:attribute context:nil].size; 201 | 202 | #else 203 | 204 | _size = [txt sizeWithFont:font constrainedToSize:maxSize]; 205 | 206 | #endif 207 | 208 | return _size; 209 | 210 | } 211 | @end 212 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUITableView.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import "STUITableView.h" 10 | #import "STDefineUI.h" 11 | #import "STUIView.h" 12 | #import "STUIViewAutoLayout.h" 13 | #import "STArray.h" 14 | #import "STDictionary.h" 15 | #import "STString.h" 16 | #import "STSagit.h" 17 | @implementation UITableView(ST) 18 | 19 | #pragma mark 核心扩展 20 | -(NSMutableArray *)source 21 | { 22 | return [self key:@"source"]; 23 | } 24 | -(void)setSource:(NSMutableArray *)source 25 | { 26 | [self source:source]; 27 | } 28 | -(UITableView *)source:(NSMutableArray *)dataSource 29 | { 30 | if(![dataSource isKindOfClass:[NSMutableArray class]]) 31 | { 32 | dataSource=[dataSource toNSMutableArray]; 33 | } 34 | //清掉高度缓存 35 | [self.heightForCells removeAllObjects]; 36 | [self key:@"source" value:dataSource]; 37 | return self; 38 | } 39 | -(OnAddTableCell)addCell 40 | { 41 | return [self key:@"addCell"]; 42 | } 43 | -(void)setAddCell:(OnAddTableCell)addCell 44 | { 45 | if(addCell!=nil) 46 | { 47 | //addCell=[addCell copy]; 48 | [self key:@"addCell" value:addCell]; 49 | } 50 | else 51 | { 52 | [self.keyValue remove:@"addCell"]; 53 | } 54 | } 55 | -(OnDelTableCell)delCell 56 | { 57 | return [self key:@"delCell"]; 58 | } 59 | -(void)setDelCell:(OnDelTableCell)delCell 60 | { 61 | if(delCell==nil) 62 | { 63 | [self.keyValue remove:@"delCell"]; 64 | } 65 | else 66 | { 67 | [self key:@"delCell" value:delCell]; 68 | } 69 | } 70 | -(OnAddTableCellAction)addCellAction 71 | { 72 | return [self key:@"addCellAction"]; 73 | } 74 | -(void)setAddCellAction:(OnAddTableCellAction)addCellAction 75 | { 76 | if(addCellAction==nil) 77 | { 78 | [self.keyValue remove:@"addCellAction"]; 79 | } 80 | else 81 | { 82 | [self key:@"addCellAction" value:addCellAction]; 83 | } 84 | } 85 | -(OnAddTableCellAction)addCellMove 86 | { 87 | return [self key:@"addCellMove"]; 88 | } 89 | - (void)setAddCellMove:(OnAddTableCellAction)addCellMove 90 | { 91 | if(addCellMove==nil) 92 | { 93 | [self.keyValue remove:@"addCellMove"]; 94 | } 95 | else 96 | { 97 | [self key:@"addCellMove" value:addCellMove]; 98 | } 99 | } 100 | -(OnAddTableSectionHeaderView)addSectionHeaderView 101 | { 102 | return [self key:@"addSectionHeaderView"]; 103 | } 104 | -(void)setAddSectionHeaderView:(OnAddTableSectionHeaderView)addSectionHeaderView 105 | { 106 | if(addSectionHeaderView==nil) 107 | { 108 | [self.keyValue remove:@"addSectionHeaderView"]; 109 | } 110 | else 111 | { 112 | [self key:@"addSectionHeaderView" value:addSectionHeaderView]; 113 | } 114 | } 115 | -(OnAddTableSectionFooterView)addSectionFooterView 116 | { 117 | return [self key:@"addSectionView"]; 118 | } 119 | -(void)setAddSectionFooterView:(OnAddTableSectionFooterView)addSectionFooterView 120 | { 121 | if(addSectionFooterView==nil) 122 | { 123 | [self.keyValue remove:@"addSectionFooterView"]; 124 | } 125 | else 126 | { 127 | [self key:@"addSectionFooterView" value:addSectionFooterView]; 128 | } 129 | } 130 | -(NSMutableDictionary*)heightForCells 131 | { 132 | NSMutableDictionary *heights=[self key:@"heightForCells"]; 133 | if(!heights) 134 | { 135 | heights=[NSMutableDictionary new]; 136 | [self key:@"heightForCells" value:heights]; 137 | } 138 | return heights; 139 | } 140 | -(OnAfterTableReloadData)afterReload 141 | { 142 | return [self key:@"afterReload"]; 143 | } 144 | -(void)setAfterReload:(OnAfterTableReloadData)afterReload 145 | { 146 | [self key:@"afterReload" value:afterReload]; 147 | } 148 | -(BOOL)reuseCell 149 | { 150 | if([self key:@"reuseCell"]!=nil) 151 | { 152 | return [[self key:@"reuseCell"] isEqualToString:@"1"]; 153 | } 154 | return YES; 155 | } 156 | -(BOOL)reuseCell:(BOOL)yesNo 157 | { 158 | [self.keyValue set:@"reuseCell" value:yesNo?@"1":@"0"]; 159 | return self; 160 | } 161 | -(BOOL)autoHeight 162 | { 163 | if([self key:@"autoHeight"]!=nil) 164 | { 165 | return [[self key:@"autoHeight"] isEqualToString:@"1"]; 166 | } 167 | return NO; 168 | } 169 | -(UITableView *)autoHeight:(BOOL)yesNo 170 | { 171 | [self.keyValue set:@"autoHeight" value:yesNo?@"1":@"0"]; 172 | if(yesNo){ 173 | // [self height:0];//先置为0,避免没有数据时全屏空白 174 | [self scrollEnabled:NO];//自动计算高度时,滚动条默认没必要存在但如果计算高度超屏时,则自动还原回来。。 175 | } 176 | return self; 177 | } 178 | -(UITableViewCellStyle)cellStyle 179 | { 180 | NSString* style=[self key:@"cellStyle"]; 181 | if(style==nil) 182 | { 183 | return UITableViewCellStyleDefault; 184 | } 185 | return (UITableViewCellStyle)[style intValue]; 186 | } 187 | -(UITableView *)cellStyle:(UITableViewCellStyle)style 188 | { 189 | [self key:@"cellStyle" value:[@(style) stringValue]]; 190 | return self; 191 | } 192 | -(BOOL)allowEdit 193 | { 194 | return [self key:@"allowEdit"]!=nil && [[self key:@"allowEdit"] isEqualToString:@"1"]; 195 | } 196 | -(UITableView *)allowEdit:(BOOL)yesNo 197 | { 198 | [self key:@"allowEdit" value:yesNo?@"1":@"0"]; 199 | return self; 200 | } 201 | -(UITableView*)afterDelCell:(NSIndexPath*)indexPath 202 | { 203 | // dispatch_async(dispatch_get_main_queue(), ^{ 204 | //重置Cell高度的缓存 205 | [self.heightForCells remove:[NSString stringWithFormat:@"%ld_%ld",indexPath.section,indexPath.row]]; 206 | NSMutableArray *rows=self.heightForCells[@(indexPath.section)]; 207 | if(rows && rows.count>indexPath.row) 208 | { 209 | [rows removeObjectAtIndex:indexPath.row]; 210 | } 211 | [self.source removeObjectAtIndex:indexPath.row]; 212 | [self deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; 213 | 214 | if(self.autoHeight) 215 | { 216 | [self height:(self.contentSize.height-1)*Ypx]; 217 | } 218 | return self; 219 | // }); 220 | 221 | } 222 | #pragma mark 属性扩展 223 | -(UITableView*)scrollEnabled:(BOOL)yesNo 224 | { 225 | self.scrollEnabled=yesNo; 226 | return self; 227 | } 228 | -(UITableView*)sectionCount:(NSInteger)count 229 | { 230 | [self key:@"sectionCount" value:[@(count) stringValue]]; 231 | return self; 232 | } 233 | -(UITableView*)rowCountInSections:(id)nums 234 | { 235 | NSArray *items; 236 | if([nums isKindOfClass:[NSString class]]) 237 | { 238 | items=[nums split:@","]; 239 | } 240 | else 241 | { 242 | items=nums; 243 | } 244 | [self key:@"rowCountInSections" value:items]; 245 | return self; 246 | } 247 | -(void)dealloc 248 | { 249 | //移除全局缓存中的事件 250 | 251 | NSLog(@"%@ ->STUITableView relase", [self class]); 252 | } 253 | @end 254 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUIViewEvent.h: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "STEnum.h" 11 | @interface UIView (STUIViewEvent) 12 | typedef void(^OnAfterEvent)(NSString *eventType, id para); 13 | //可以附加的点击事件 (存档在keyvalue中时,无法传参(内存地址失效),只能针对性存runtime的属性) 14 | typedef void(^OnViewClick)(id view); 15 | //!双击事件 16 | typedef void(^OnViewDbClick)(id view); 17 | typedef BOOL(^OnViewDrag)(id view,UIPanGestureRecognizer *recognizer); 18 | //!滑动事件:return true 滑动View;return false 不滑动View 19 | typedef void(^OnViewSlide)(id view,UISwipeGestureRecognizer *recognizer); 20 | //!屏幕侧滑【只有左右事件】 21 | typedef void(^OnScreenEdgeSlide)(id view,UIScreenEdgePanGestureRecognizer *recognizer); 22 | typedef void(^OnViewLongPress)(id view); 23 | //!定时器事件。 24 | typedef void(^OnTimer)(id view,NSTimer *timer, NSInteger count); 25 | typedef void(^OnViewDescription)(id view); 26 | 27 | #pragma mark 扩展系统事件 - 点击 28 | //!点击事件的间隔(单位秒s) 29 | -(NSInteger)clickInterval; 30 | //!设置点击事件的间隔(单位秒s) 31 | -(UIView*)clickInterval:(NSInteger)sencond; 32 | //!执行点击事件 33 | -(UIView*)click; 34 | //!绑定事件 event:指定事件名称,也可以是控制器名称,也可以指向其它UI的事件,如:Age.click (Age是其它UI的name) 35 | -(UIView*)addClick:(NSString*)event; 36 | //!绑定事件 event:指定事件名称,也可以是控制器名称,也可以指向其它UI的事件,如:Age.click (Age是其它UI的name) enlarge: 扩大点击范围(上下左右)大小。 37 | -(UIView*)addClick:(NSString*)event enlarge:(CGFloat)value; 38 | -(UIView*)addClick:(NSString*)event enlarge:(CGFloat)left top:(CGFloat)top right:(CGFloat)right bottom:(CGFloat)bottom; 39 | //!绑定事件 并指定target 40 | -(UIView*)addClick:(NSString *)event target:(UIViewController*)target; 41 | -(UIView*)addClick:(NSString *)event target:(UIViewController*)target enlarge:(CGFloat)value; 42 | -(UIView*)addClick:(NSString *)event target:(UIViewController*)target enlarge:(CGFloat)left top:(CGFloat)top right:(CGFloat)right bottom:(CGFloat)bottom; 43 | //!绑定事件 用代码块的形式 44 | -(UIView*)onClick:(OnViewClick)block; 45 | //!绑定事件 用代码块的形式 enlarge: 扩大点击范围(上下左右)大小。 46 | -(UIView*)onClick:(OnViewClick)block enlarge:(CGFloat)value; 47 | -(UIView*)onClick:(OnViewClick)block enlarge:(CGFloat)left top:(CGFloat)top right:(CGFloat)right bottom:(CGFloat)bottom; 48 | //!移除绑定点击事件 49 | -(UIView*)removeClick; 50 | #pragma mark 扩展系统事件 - 双击 51 | //!执行双击事件 52 | -(UIView*)dbClick; 53 | //!绑定事件 event:指定事件名称,也可以是控制器名称,也可以指向其它UI的事件,如:Age.click (Age是其它UI的name) 54 | -(UIView*)addDbClick:(NSString*)event; 55 | //!绑定事件 event:指定事件名称,也可以是控制器名称,也可以指向其它UI的事件,如:Age.click (Age是其它UI的name) enlarge: 扩大点击范围(上下左右)大小。 56 | -(UIView*)addDbClick:(NSString*)event enlarge:(CGFloat)value; 57 | -(UIView*)addDbClick:(NSString*)event enlarge:(CGFloat)left top:(CGFloat)top right:(CGFloat)right bottom:(CGFloat)bottom; 58 | //!绑定事件 并指定target 59 | -(UIView*)addDbClick:(NSString *)event target:(UIViewController*)target; 60 | -(UIView*)addDbClick:(NSString *)event target:(UIViewController*)target enlarge:(CGFloat)value; 61 | -(UIView*)addDbClick:(NSString *)event target:(UIViewController*)target enlarge:(CGFloat)left top:(CGFloat)top right:(CGFloat)right bottom:(CGFloat)bottom; 62 | //!绑定事件 用代码块的形式 63 | -(UIView*)onDbClick:(OnViewDbClick)block; 64 | //!绑定事件 用代码块的形式 enlarge: 扩大点击范围(上下左右)大小。 65 | -(UIView*)onDbClick:(OnViewDbClick)block enlarge:(CGFloat)value; 66 | -(UIView*)onDbClick:(OnViewDbClick)block enlarge:(CGFloat)left top:(CGFloat)top right:(CGFloat)right bottom:(CGFloat)bottom; 67 | //!移除绑定双击事件 68 | -(UIView*)removeDbClick; 69 | #pragma mark 扩展系统事件 - 长按 70 | //!执行长按事件 71 | -(UIView*)longPress; 72 | //!绑定事件 event:指定事件名称,也可以是控制器名称,也可以指向其它UI的事件,如:Age.click (Age是其它UI的name) 73 | -(UIView*)addLongPress:(NSString*)event; 74 | //!绑定事件 event:指定事件名称,也可以是控制器名称,也可以指向其它UI的事件,如:Age.click (Age是其它UI的name) enlarge: 扩大点击范围(上下左右)大小。 75 | -(UIView*)addLongPress:(NSString*)event enlarge:(CGFloat)value; 76 | -(UIView*)addLongPress:(NSString*)event enlarge:(CGFloat)left top:(CGFloat)top right:(CGFloat)right bottom:(CGFloat)bottom; 77 | //!绑定事件 并指定target 78 | -(UIView*)addLongPress:(NSString *)event target:(UIViewController*)target; 79 | -(UIView*)addLongPress:(NSString *)event target:(UIViewController*)target enlarge:(CGFloat)value; 80 | -(UIView*)addLongPress:(NSString *)event target:(UIViewController*)target enlarge:(CGFloat)left top:(CGFloat)top right:(CGFloat)right bottom:(CGFloat)bottom; 81 | //!绑定事件 用代码块的形式 82 | -(UIView*)onLongPress:(OnViewLongPress)block; 83 | //!绑定事件 用代码块的形式 enlarge: 扩大点击范围(上下左右)大小。 84 | -(UIView*)onLongPress:(OnViewLongPress)block enlarge:(CGFloat)value; 85 | -(UIView*)onLongPress:(OnViewLongPress)block enlarge:(CGFloat)left top:(CGFloat)top right:(CGFloat)right bottom:(CGFloat)bottom; 86 | //!移除绑定长按事件 87 | -(UIView*)removeLongPress; 88 | 89 | #pragma mark 扩展系统事件 - 拖动 90 | //!执行拖动事件 91 | -(UIView*)drag; 92 | //!绑定事件 event:指定事件名称,也可以是控制器名称,也可以指向其它UI的事件,如:Age.drag (Age是其它UI的name) 93 | -(UIView*)addDrag:(NSString*)event; 94 | //!绑定事件 并指定target 95 | -(UIView*)addDrag:(NSString *)event target:(UIViewController*)target; 96 | //!绑定事件 用代码块的形式 97 | -(UIView*)onDrag:(OnViewDrag)block; 98 | //!绑定事件 用代码块的形式 99 | -(UIView*)onDrag:(OnViewDrag)block direction:(DragDirection)direction; 100 | //!移除绑定拖动事件 101 | -(UIView*)removeDrag; 102 | 103 | #pragma mark 扩展系统事件 - 滑动 104 | 105 | //!绑定事件 event:指定事件名称,也可以是控制器名称,也可以指向其它UI的事件,如:Age.drag (Age是其它UI的name) 106 | -(UIView*)addSlide:(NSString*)event; 107 | //!绑定事件 并指定target 108 | -(UIView*)addSlide:(NSString *)event target:(UIViewController*)target; 109 | //!绑定事件 用代码块的形式 110 | -(UIView*)onSlide:(OnViewSlide)block; 111 | //!移除绑定事件 112 | -(UIView*)removeSlide; 113 | 114 | #pragma mark 扩展系统事件 - 屏幕侧滑(左边缘滑动) 115 | //!绑定事件 event:指定事件名称,也可以是控制器名称,也可以指向其它UI的事件,如:Age.drag (Age是其它UI的name) 116 | -(UIView*)addScreenLeftEdgeSlide:(NSString*)event; 117 | //!绑定事件 并指定target 118 | -(UIView*)addScreenLeftEdgeSlide:(NSString *)event target:(UIViewController*)target; 119 | //!绑定事件 用代码块的形式 120 | -(UIView*)onScreenLeftEdgeSlide:(OnScreenEdgeSlide)block; 121 | //!移除绑定事件 122 | -(UIView*)removeScreenLeftEdgeSlide; 123 | 124 | #pragma mark 扩展系统事件 - 屏幕侧滑(右边缘滑动) 125 | //!绑定事件 event:指定事件名称,也可以是控制器名称,也可以指向其它UI的事件,如:Age.drag (Age是其它UI的name) 126 | -(UIView*)addScreenRightEdgeSlide:(NSString*)event; 127 | //!绑定事件 并指定target 128 | -(UIView*)addScreenRightEdgeSlide:(NSString *)event target:(UIViewController*)target; 129 | //!绑定事件 用代码块的形式 130 | -(UIView*)onScreenRightEdgeSlide:(OnScreenEdgeSlide)block; 131 | //!移除绑定事件 132 | -(UIView*)removeScreenRightEdgeSlide; 133 | 134 | #pragma mark 定时器事件 135 | //!绑定事件 用代码块的形式 136 | -(UIView*)onTimer:(OnTimer)block; 137 | -(UIView*)onTimer:(OnTimer)block interval:(double)sencond; 138 | //!移除绑定事件 139 | -(UIView*)removeTimer; 140 | 141 | #pragma mark 扩展的回调事件 142 | -(OnAfterEvent)onAfter; 143 | //!绑定事件 用代码块的形式 144 | -(UIView*)onAfter:(OnAfterEvent)block; 145 | 146 | #pragma mark 增加描述 147 | //!提供一个代码块,方便代码规范 description处可以写代码块的说明文字 148 | -(UIView*)block:(NSString*)description on:(OnViewDescription)descBlock; 149 | //!块写法,用于包含添加子视图 150 | -(UIView*)block:(OnViewDescription)descBlock; 151 | @end 152 | -------------------------------------------------------------------------------- /Sagit/STTool/Common/STFile.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import "STFile.h" 10 | #import "STDictionary.h" 11 | #import "STSagit.h" 12 | #import "STCategory.h" 13 | @interface STFile() 14 | @property (nonatomic,assign)NSSearchPathDirectory directory; 15 | @property (nonatomic,retain)NSMutableDictionary *cacheDic; 16 | @property (nonatomic,copy) NSString* STBigFileFoler; 17 | @end 18 | 19 | @implementation STFile 20 | 21 | + (instancetype)share 22 | { 23 | static STFile *_share = nil; 24 | static dispatch_once_t onceToken; 25 | dispatch_once(&onceToken, ^{ 26 | _share = [[STFile alloc] init]; 27 | _share.directory=NSCachesDirectory; 28 | }); 29 | return _share; 30 | } 31 | -(STFile *)Home 32 | { 33 | if(!_Home) 34 | { 35 | _Home=[STFile new]; 36 | _Home.directory=NSUserDirectory; 37 | } 38 | return _Home; 39 | } 40 | -(STFile *)Document 41 | { 42 | if(!_Document) 43 | { 44 | _Document=[STFile new]; 45 | _Document.directory=NSDocumentDirectory; 46 | } 47 | return _Document; 48 | } 49 | -(STFile *)Libaray 50 | { 51 | if(!_Libaray) 52 | { 53 | _Libaray=[STFile new]; 54 | _Libaray.directory=NSLibraryDirectory; 55 | } 56 | return _Libaray; 57 | } 58 | -(STFile *)Temp 59 | { 60 | if(!_Temp) 61 | { 62 | _Temp=[STFile new]; 63 | _Temp.directory=NSDemoApplicationDirectory; 64 | } 65 | return _Temp; 66 | } 67 | -(NSUserDefaults *)Setting 68 | { 69 | return [NSUserDefaults standardUserDefaults]; 70 | } 71 | -(NSString *)fileName 72 | { 73 | return @"stfile.plist"; 74 | } 75 | -(CGFloat)size 76 | { 77 | CGFloat folderSize = 0.0f; 78 | //获取路径 79 | NSString *cachePath = [self folderPath]; 80 | //获取所有文件的数组 81 | NSArray *files = [[NSFileManager defaultManager] subpathsAtPath:cachePath]; 82 | // NSLog(@"文件数:%ld",files.count); 83 | for(NSString *path in files) { 84 | NSString *filePath = [cachePath stringByAppendingString:[NSString stringWithFormat:@"/%@",path]]; 85 | //累加 86 | folderSize += [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil].fileSize; 87 | } 88 | //转换为M为单位 89 | CGFloat sizeM = (CGFloat)(folderSize /1024.0/1024.0); 90 | 91 | return sizeM; 92 | } 93 | 94 | - (void)clear:(void(^)(BOOL success))block { 95 | //获取路径 96 | NSString *cachePath=self.folderPath; 97 | //返回路径中的文件数组 98 | NSArray*files = [[NSFileManager defaultManager] subpathsAtPath:cachePath]; 99 | BOOL result=YES; 100 | for(NSString *p in files) 101 | { 102 | NSError *error; 103 | NSString *path = [cachePath stringByAppendingString:[NSString stringWithFormat:@"/%@",p]]; 104 | if([[NSFileManager defaultManager] fileExistsAtPath:path]) 105 | { 106 | result = [[NSFileManager defaultManager] removeItemAtPath:path error:&error]; 107 | } 108 | } 109 | _cacheDic=nil; 110 | _STBigFileFoler=nil;//需要重新创建文件夹。 111 | if(block!=nil){block(result);} 112 | 113 | } 114 | -(void)set:(NSString *)key value:(id)value 115 | { 116 | if(key==nil || value==nil){return;} 117 | @try 118 | { 119 | NSData *data = [NSKeyedArchiver archivedDataWithRootObject:value]; 120 | if(data) 121 | { 122 | if(data.length>4*1024) // >4K转存独立文件 123 | { 124 | NSString *fileName=[[@"STBigFile_" append:[@([key hash]) stringValue]] append:@".dat"]; 125 | [data writeToFile:[self.STBigFileFoler append:fileName] atomically:YES]; 126 | [self.cacheDic set:key value:fileName]; 127 | } 128 | else 129 | { 130 | [self.cacheDic set:key value:data]; 131 | } 132 | [self writeToFile]; 133 | } 134 | } 135 | @catch(NSException * e) 136 | {} 137 | } 138 | -(id)get:(NSString *)key 139 | { 140 | if(key==nil){return nil;} 141 | @try 142 | { 143 | if(self.cacheDic.count>0) 144 | { 145 | id data = [self.cacheDic get:key]; 146 | if(data) 147 | { 148 | if([data isKindOfClass:[NSString class]] && [((NSString*)data) startWith:@"STBigFile_"]) 149 | { 150 | NSString *path=[self.STBigFileFoler append:(NSString*)data]; 151 | data=[[NSData alloc] initWithContentsOfFile:path]; 152 | } 153 | if(data) 154 | { 155 | return [NSKeyedUnarchiver unarchiveObjectWithData:data]; 156 | } 157 | } 158 | } 159 | } 160 | @catch(NSException * e) 161 | {} 162 | return nil; 163 | } 164 | -(void)remove:(NSString *)key 165 | { 166 | if(key==nil){return;} 167 | @try 168 | { 169 | [self.cacheDic remove:key]; 170 | [self writeToFile]; 171 | } 172 | @catch(NSException * e) 173 | {} 174 | } 175 | -(NSMutableDictionary *)cacheDic 176 | { 177 | if(!_cacheDic) 178 | { 179 | _cacheDic=[self readFromFile]; 180 | } 181 | return _cacheDic; 182 | } 183 | -(void)writeToFile 184 | { 185 | [self.cacheDic writeToFile:self.filePath atomically:YES]; 186 | } 187 | 188 | - (NSMutableDictionary *)readFromFile 189 | { 190 | NSFileManager *fileManager = [NSFileManager defaultManager]; 191 | NSMutableDictionary *fileDic; 192 | if ([fileManager fileExistsAtPath:self.filePath]) 193 | { 194 | fileDic = [[NSMutableDictionary alloc] initWithContentsOfFile:self.filePath]; 195 | } 196 | else 197 | { 198 | fileDic = [NSMutableDictionary new]; 199 | } 200 | return fileDic; 201 | } 202 | -(NSString*)filePath 203 | { 204 | return [self.folderPath stringByAppendingPathComponent:self.fileName]; 205 | } 206 | -(NSString*)folderPath 207 | { 208 | NSString *folder=nil; 209 | switch (self.directory) { 210 | case NSUserDirectory: 211 | folder=NSHomeDirectory(); 212 | break; 213 | case NSDemoApplicationDirectory: 214 | folder=NSTemporaryDirectory(); 215 | break; 216 | default: 217 | folder=NSSearchPathForDirectoriesInDomains(self.directory, NSUserDomainMask, YES).lastObject; 218 | break; 219 | } 220 | return folder; 221 | } 222 | -(NSString *)STBigFileFoler 223 | { 224 | if(!_STBigFileFoler) 225 | { 226 | _STBigFileFoler=[[self folderPath] append:@"/STBigFile/"]; 227 | NSFileManager *fileManager = [NSFileManager defaultManager]; 228 | if(![fileManager fileExistsAtPath:_STBigFileFoler]) 229 | { 230 | [fileManager createDirectoryAtPath:_STBigFileFoler withIntermediateDirectories:YES attributes:nil error:nil]; 231 | } 232 | } 233 | return _STBigFileFoler; 234 | } 235 | @end 236 | -------------------------------------------------------------------------------- /Sagit/Category/UI/STUITextView.m: -------------------------------------------------------------------------------- 1 | // 2 | // 开源:https://github.com/cyq1162/Sagit 3 | // 作者:陈裕强 create on 2017/12/12. 4 | // 博客:(昵称:路过秋天) http://www.cnblogs.com/cyq1162/ 5 | // 6 | // Copyright © 2017-2027年. All rights reserved. 7 | // 8 | 9 | #import "STUITextView.h" 10 | #import "STUIView.h" 11 | #import "STDefineUI.h" 12 | #import "STUIViewAddUI.h" 13 | #import "STUIViewAutoLayout.h" 14 | #import "STUITableView.h" 15 | #import "STUITableViewCell.h" 16 | #import "STSagit.h" 17 | //#import "objc/runtime.h" 18 | 19 | //@interface UITextView() 20 | //@property (nonatomic,assign) NSInteger MaxLength; 21 | //@property (nonatomic,assign) CGFloat MaxHeight; 22 | //@end 23 | @implementation UITextView(ST) 24 | 25 | -(OnTextViewEdit)onEdit 26 | { 27 | return [self key:@"onEdit"]; 28 | } 29 | -(void)setOnEdit:(OnTextViewEdit)onEdit 30 | { 31 | [self key:@"onEdit" value:onEdit]; 32 | } 33 | #pragma mark 自定义追加属系统 34 | - (NSInteger)maxLength 35 | { 36 | NSString *max=[self key:@"maxLength"]; 37 | if(max) 38 | { 39 | return [max intValue]; 40 | } 41 | return 0; 42 | } 43 | - (UITextView*)maxLength:(NSInteger)length{ 44 | [self key:@"maxLength" value:[@(length) stringValue]]; 45 | //self.delegate = (id)self; 46 | return self; 47 | 48 | } 49 | 50 | - (NSInteger)maxRow 51 | { 52 | NSString *max=[self key:@"maxRow"]; 53 | if(max) 54 | { 55 | return [max integerValue]; 56 | } 57 | return 1; 58 | } 59 | -(UITextView *)maxRow:(NSInteger)num 60 | { 61 | [self key:@"maxRow" value:[@(num) stringValue]]; 62 | //self.delegate = (id)self; 63 | return self; 64 | } 65 | #pragma mark 扩展系统属性 66 | -(UITextView*)keyboardType:(UIKeyboardType)value 67 | { 68 | self.keyboardType=value; 69 | return self; 70 | } 71 | -(UITextView*)secureTextEntry:(BOOL)value 72 | { 73 | self.secureTextEntry=value; 74 | return self; 75 | } 76 | -(UITextView*)text:(NSString*)text 77 | { 78 | if([text isKindOfClass:[NSNull class]]) 79 | { 80 | text=@""; 81 | } 82 | if(self.maxLength>0 && text.length>self.maxLength) 83 | { 84 | text=[text substringToIndex:self.maxLength-1]; 85 | } 86 | self.text=text; 87 | [self textViewDidChange:self];//手工触发事件 88 | return self; 89 | } 90 | -(UITextView*)font:(CGFloat)px 91 | { 92 | self.font=[UIFont toFont:px]; 93 | return self; 94 | } 95 | -(UITextView*)textColor:(id)colorOrHex 96 | { 97 | self.textColor=[UIColor toColor:colorOrHex]; 98 | return self; 99 | } 100 | -(UITextView*)textAlignment:(NSTextAlignment)value 101 | { 102 | self.textAlignment=value; 103 | return self; 104 | } 105 | -(UITextView*)placeholder 106 | { 107 | return [self key:@"placeholder"]; 108 | } 109 | -(UITextView*)placeholder:(NSString*)text 110 | { 111 | if([text isKindOfClass:[NSNull class]]) 112 | { 113 | text=@""; 114 | } 115 | if([self key:@"placeholder"]==nil) 116 | { 117 | UILabel *placeholer=[[self addLabel:nil text:text font:self.font.pointSize*Ypx color:@"#cccccc"] relate:LeftTop v:8 v2:18]; 118 | [self key:@"placeholderLabel" value:placeholer]; 119 | } 120 | [self key:@"placeholder" value:text]; 121 | return self; 122 | } 123 | -(UITextView*)editable:(BOOL)yesNo 124 | { 125 | self.editable=yesNo; 126 | return self; 127 | } 128 | #pragma mark TextView 协议实现 129 | - (void)textViewDidChange:(UITextView *)textView 130 | { 131 | if(self.onEdit) 132 | { 133 | self.onEdit(textView,NO); 134 | } 135 | UILabel *label=[textView key:@"placeholderLabel"]; 136 | if(label!=nil) 137 | { 138 | label.alpha=textView.hasText?0:1; 139 | } 140 | if (textView.maxLength>0 && textView.text.length >=textView.maxLength) 141 | { 142 | textView.text=[textView.text substringWithRange:NSMakeRange(0, textView.maxLength)]; 143 | } 144 | if(self.maxRow!=1) 145 | { 146 | [self changeHeight]; 147 | } 148 | } 149 | //-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text 150 | //{ //此方法不支持中文(只能在change事件中处理) 151 | // if (textView.maxLength>0 && range.location >=textView.maxLength) 152 | // { 153 | // return NO; 154 | // } 155 | // return YES; 156 | //} 157 | 158 | #pragma mark 实现高度自适应变化 159 | //UITextView 160 | -(void)changeHeight 161 | { 162 | 163 | if(CGRectEqualToRect(self.OriginFrame, CGRectZero))//第一次先记录原始坐标 164 | { 165 | self.OriginFrame=self.frame; 166 | } 167 | CGRect frame=self.frame; 168 | NSInteger fontHeight=floor(self.font.lineHeight); 169 | //根据观察:contentSize 默认上下margin 4个pt,比height少8个pt。 170 | NSInteger nowRows=round((self.frame.size.height-8)/fontHeight); 171 | NSInteger needRows=MIN(round(self.contentSize.height/fontHeight)-1,self.maxRow); 172 | if(needRows==nowRows){return;}//没变化 173 | CGFloat addHeight=0; 174 | if(needRows==1) 175 | { 176 | //恢复到原来的状态,得到负数,降低高度。 177 | addHeight=self.OriginFrame.size.height-self.frame.size.height; 178 | } 179 | else 180 | { 181 | addHeight=ceil(needRows*fontHeight)+8-self.frame.size.height;//要修正的高度 182 | } 183 | if(addHeight!=0)//差值发生变化, 184 | { 185 | [self height:(frame.size.height+addHeight)*Ypx]; 186 | [self findSuperToFixHeight:self fix:addHeight]; 187 | } 188 | 189 | } 190 | //往上找,找到最后一个根视图,再自上而下刷新布局 191 | -(void)findSuperToFixHeight:(UIView*)me fix:(NSInteger)fixHeight 192 | { 193 | if([me isKindOfClass:[UITableViewCell class]]) // 表格内的特殊处理。 194 | { 195 | UITableViewCell *cell=me; 196 | [cell resetHeightCache]; 197 | UITableView *table= cell.table; 198 | if(table.autoHeight) 199 | { 200 | if(table.contentSize.height0) 224 | { 225 | if(me.frame.size.height+me.frame.origin.y>superView.frame.size.height) 226 | { 227 | [superView height:(superView.frame.size.height+fixHeight)*Ypx]; 228 | [superView key:@"maxHeightAutoFix" value:@"yes"]; 229 | return [self findSuperToFixHeight:superView fix:fixHeight]; 230 | } 231 | } 232 | else 233 | { 234 | if([superView key:@"maxHeightAutoFix"]!=nil) 235 | { 236 | [superView height:(superView.frame.size.height+fixHeight)*Ypx];//减少高度 237 | return [self findSuperToFixHeight:superView fix:fixHeight]; 238 | } 239 | } 240 | 241 | } 242 | - (void)textViewDidBeginEditing:(UITextView *)textView 243 | { 244 | self.window.editingTextUI=textView;//注册键盘遮挡事件 245 | if(self.onEdit) 246 | { 247 | self.onEdit(textView,NO); 248 | } 249 | } 250 | - (void)textViewDidEndEditing:(UITextView *)textView 251 | { 252 | if(self.onEdit) 253 | { 254 | self.onEdit(textView,YES); 255 | } 256 | 257 | } 258 | @end 259 | 260 | 261 | --------------------------------------------------------------------------------