1.刪除ToolBar下面的分割線
toolbar.showsBaselineSeparator = NO;
2.修改TextField的藍色或橙色邊框
self.textField.focusRingType = NSFocusRingTypeNone;
3.打開已安裝的其他軟件
// 1
NSString *appPath = @"/Applications/Foxmail.app";
[[NSWorkspace sharedWorkspace] openFile:appPath];
// 2
[[NSWorkspace sharedWorkspace] launchApplication:@"Foxmail"];
4.打開網頁
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://www.baidu.com"]];
5.Color生成純色圖片(iOS)
// 生成純色圖片
+ (UIImage *)pureColorImageWithColor:(UIColor *)color {
CGSize imageSize = CGSizeMake(1.0f, 1.0f);
UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0f);
CGContextRef theContext = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(theContext, color.CGColor);
CGContextFillRect(theContext, CGRectMake(0.0f, 0.0f, imageSize.width, imageSize.height));
CGImageRef theCGImage = CGBitmapContextCreateImage(theContext);
UIImage *theImage;
if ([[UIImage class] respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) {
theImage = [UIImage imageWithCGImage:theCGImage scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
} else {
theImage = [UIImage imageWithCGImage:theCGImage];
}
CGImageRelease(theCGImage);
return theImage;
}
// 生成純色圓角圖片
+ (UIImage *)pureColorImageWithSize:(CGSize)size
color:(UIColor *)color
cornRadius:(CGFloat)radius {
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
CGContextRef cxt = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(cxt, color.CGColor);
CGContextSetStrokeColorWithColor(cxt, color.CGColor);
CGContextMoveToPoint(cxt, size.width, size.height-radius);
CGContextAddArcToPoint(cxt, size.width, size.height, size.width-radius, size.height, radius);//右下角
CGContextAddArcToPoint(cxt, 0, size.height, 0, size.height-radius, radius);//左下角
CGContextAddArcToPoint(cxt, 0, 0, radius, 0, radius);//左上角
CGContextAddArcToPoint(cxt, size.width, 0, size.width, radius, radius);//右上角
CGContextClosePath(cxt);
CGContextDrawPath(cxt, kCGPathFillStroke);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
6.時間格式轉換
/// 根據格式生成時間字符串
/// @param date 時間NSDate
/// @param formatStr 時間格式 eg:"YYYY-MM-dd HH:mm:ss"
+ (NSString *)stringFromDate:(NSDate *)date formatStr:(NSString *)formatStr {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:formatStr];
return [formatter stringFromDate:date];
}
/// 根據格式生成NSDate
/// @param dateString 時間
/// @param formatStr 時間格式 eg:"YYYY-MM-dd HH:mm:ss"
+ (NSDate *)dateFromString:(NSString *)dateString formatStr:(NSString *)formatStr {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:formatStr];
return [formatter dateFromString:dateString];
}
/// 獲取當前時間戳(秒)
+ (NSNumber *)getCurrentTimeStampSec {
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:0];
NSTimeInterval timeInterval = [date timeIntervalSince1970];
NSNumber *u = [NSNumber numberWithInteger:timeInterval];
return u;
}
/// 獲取當前時間戳(毫秒)
+ (NSNumber *)getCurrentTimeStampMilliSec {
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:0];
long long timeInterval = [date timeIntervalSince1970] * 1000;
NSNumber *u = [NSNumber numberWithLongLong:timeInterval];
return u;
}
7.合法性
- 手機號是否合法
+ (BOOL)isValidMobile:(NSString *)mobile {
BOOL isValid = false;
if (!kStringIsEmpty(mobile) && mobile.length == 11) {
/**
* 移動號段正則表達式
*/
NSString *CM_NUM = @"^((13[4-9])|(147)|(15[0-2,7-9])|(178)|(18[2-4,7-8]))\\d{8}|(1705)\\d{7}$";
/**
* 聯通號段正則表達式
*/
NSString *CU_NUM = @"^((13[0-2])|(145)|(15[5-6])|(176)|(18[5,6]))\\d{8}|(1709)\\d{7}$";
/**
* 電信號段正則表達式
*/
NSString *CT_NUM = @"^((133)|(153)|(177)|(18[0,1,9]))\\d{8}$";
NSPredicate *pred1 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CM_NUM];
BOOL isMatch1 = [pred1 evaluateWithObject:mobile];
NSPredicate *pred2 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CU_NUM];
BOOL isMatch2 = [pred2 evaluateWithObject:mobile];
NSPredicate *pred3 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CT_NUM];
BOOL isMatch3 = [pred3 evaluateWithObject:mobile];
if (isMatch1 || isMatch2 || isMatch3) {
isValid = true;
}
}
return isValid;
}
- Url是否合法
+ (BOOL)isValidUrl:(NSString *)urlStr {
NSString *regex =@"[a-zA-z]+://[^\\s]*";
NSPredicate *urlTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];
return [urlTest evaluateWithObject:urlStr];
}
- 銀行卡是否合法
+ (BOOL)isValidCardNo:(NSString *)cardNumber {
int oddSum = 0; // 奇數和
int evenSum = 0; // 偶數和
int allSum =0; // 總和
// 循環加和
for(NSInteger i = 1; i <= cardNumber.length; i++) {
NSString *theNumber = [cardNumber substringWithRange:NSMakeRange(cardNumber.length-i,1)];
int lastNumber = [theNumber intValue];
if(i%2==0) {
// 偶數位
lastNumber *=2;
if(lastNumber >9) {
lastNumber -=9;
}
evenSum += lastNumber;
} else {
// 奇數位
oddSum += lastNumber;
}
}
allSum = oddSum + evenSum;
// 是否合法
if(allSum%10 == 0) {
return YES;
} else {
return NO;
}
}
- 判斷郵箱是否合法
+ (BOOL)isValidEmail:(NSString *)email {
if ([CCUtility checkEmptyString:email]) return NO;
NSString *emailRegex = @"^(([a-zA-Z0-9_-]+)|([a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)))@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$";
NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
return [emailTest evaluateWithObject:email];
}
+ (BOOL)isValidUrl:(NSString *)urlStr {
NSString *regex =@"[a-zA-z]+://[^\\s]*";
NSPredicate *urlTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];
return [urlTest evaluateWithObject:urlStr];
}
- 判斷身份證(中國大陸)身份證是否合法
+ (BOOL)isValidIDCardNo:(NSString *)value {
value = [value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSInteger length =0;
if (!value) {
return NO;
} else {
length = value.length;
//不滿足15位和18位,即身份證錯誤
if (length !=15 && length !=18) {
return NO;
}
}
// 省份代碼
NSArray *areasArray = @[@"11",@"12", @"13",@"14", @"15",@"21", @"22",@"23", @"31",@"32", @"33",@"34", @"35",@"36", @"37",@"41", @"42",@"43", @"44",@"45", @"46",@"50", @"51",@"52", @"53",@"54", @"61",@"62", @"63",@"64", @"65",@"71", @"81",@"82", @"91"];
// 檢測省份身份行政區代碼
NSString *valueStart2 = [value substringToIndex:2];
BOOL areaFlag =NO; //標識省份代碼是否正確
for (NSString *areaCode in areasArray) {
if ([areaCode isEqualToString:valueStart2]) {
areaFlag =YES;
break;
}
}
if (!areaFlag) {
return NO;
}
NSRegularExpression *regularExpression;
NSUInteger numberofMatch;
int year =0;
//分為15位、18位身份證進行校驗
switch (length) {
case 15:
//獲取年份對應的數字
year = [value substringWithRange:NSMakeRange(6,2)].intValue +1900;
if (year %4 ==0 || (year %100 ==0 && year %4 ==0)) {
//創建正則表達式 NSRegularExpressionCaseInsensitive:不區分字母大小寫的模式
regularExpression = [[NSRegularExpression alloc]initWithPattern:@"^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}$" options:NSRegularExpressionCaseInsensitive error:nil];//測試出生日期的合法性
} else {
regularExpression = [[NSRegularExpression alloc]initWithPattern:@"^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}$" options:NSRegularExpressionCaseInsensitive error:nil];//測試出生日期的合法性
}
//使用正則表達式匹配字符串 NSMatchingReportProgress:找到最長的匹配字符串后調用block回調
numberofMatch = [regularExpression numberOfMatchesInString:value options:NSMatchingReportProgress range:NSMakeRange(0, value.length)];
if(numberofMatch > 0) {
return YES;
} else {
return NO;
}
case 18:
year = [value substringWithRange:NSMakeRange(6,4)].intValue;
if (year %4 ==0 || (year %100 ==0 && year %4 ==0)) {
regularExpression = [[NSRegularExpression alloc]initWithPattern:@"^((1[1-5])|(2[1-3])|(3[1-7])|(4[1-6])|(5[0-4])|(6[1-5])|71|(8[12])|91)\\d{4}(((19|20)\\d{2}(0[13-9]|1[012])(0[1-9]|[12]\\d|30))|((19|20)\\d{2}(0[13578]|1[02])31)|((19|20)\\d{2}02(0[1-9]|1\\d|2[0-8]))|((19|20)([13579][26]|[2468][048]|0[048])0229))\\d{3}(\\d|X|x)?$" options:NSRegularExpressionCaseInsensitive error:nil];//測試出生日期的合法性
} else {
regularExpression = [[NSRegularExpression alloc]initWithPattern:@"^((1[1-5])|(2[1-3])|(3[1-7])|(4[1-6])|(5[0-4])|(6[1-5])|71|(8[12])|91)\\d{4}(((19|20)\\d{2}(0[13-9]|1[012])(0[1-9]|[12]\\d|30))|((19|20)\\d{2}(0[13578]|1[02])31)|((19|20)\\d{2}02(0[1-9]|1\\d|2[0-8]))|((19|20)([13579][26]|[2468][048]|0[048])0229))\\d{3}(\\d|X|x)?$" options:NSRegularExpressionCaseInsensitive error:nil];//測試出生日期的合法性
}
numberofMatch = [regularExpression numberOfMatchesInString:value options:NSMatchingReportProgress range:NSMakeRange(0, value.length)];
if(numberofMatch > 0) {
//1:校驗碼的計算方法 身份證號碼17位數分別乘以不同的系數。從第一位到第十七位的系數分別為:7-9-10-5-8-4-2-1-6-3-7-9-10-5-8-4-2。將這17位數字和系數相乘的結果相加。
int S = [value substringWithRange:NSMakeRange(0,1)].intValue*7 + [value substringWithRange:NSMakeRange(10,1)].intValue *7 + [value substringWithRange:NSMakeRange(1,1)].intValue*9 + [value substringWithRange:NSMakeRange(11,1)].intValue *9 + [value substringWithRange:NSMakeRange(2,1)].intValue*10 + [value substringWithRange:NSMakeRange(12,1)].intValue *10 + [value substringWithRange:NSMakeRange(3,1)].intValue*5 + [value substringWithRange:NSMakeRange(13,1)].intValue *5 + [value substringWithRange:NSMakeRange(4,1)].intValue*8 + [value substringWithRange:NSMakeRange(14,1)].intValue *8 + [value substringWithRange:NSMakeRange(5,1)].intValue*4 + [value substringWithRange:NSMakeRange(15,1)].intValue *4 + [value substringWithRange:NSMakeRange(6,1)].intValue*2 + [value substringWithRange:NSMakeRange(16,1)].intValue *2 + [value substringWithRange:NSMakeRange(7,1)].intValue *1 + [value substringWithRange:NSMakeRange(8,1)].intValue *6 + [value substringWithRange:NSMakeRange(9,1)].intValue *3;
//2:用加出來和除以11,看余數是多少?余數只可能有0-1-2-3-4-5-6-7-8-9-10這11個數字
int Y = S %11;
NSString *M =@"F";
NSString *JYM =@"10X98765432";
M = [JYM substringWithRange:NSMakeRange(Y,1)];// 3:獲取校驗位
NSString *lastStr = [value substringWithRange:NSMakeRange(17,1)];
//4:檢測ID的校驗位
if ([lastStr isEqualToString:@"x"]) {
if ([M isEqualToString:@"X"]) {
return YES;
} else {
return NO;
}
} else {
if ([M isEqualToString:[value substringWithRange:NSMakeRange(17,1)]]) {
return YES;
} else {
return NO;
}
}
} else {
return NO;
}
default:
return NO;
}
}
8.強弱引用
// 推薦使用(摘自YYKit)
/**
Synthsize a weak or strong reference.
Example:
@weakify(self)
[self doSomething^{
@strongify(self)
if (!self) return;
...
}];
*/
#ifndef weakify
#if DEBUG
#if __has_feature(objc_arc)
#define weakify(object) autoreleasepool{} __weak __typeof__(object) weak##_##object = object;
#else
#define weakify(object) autoreleasepool{} __block __typeof__(object) block##_##object = object;
#endif
#else
#if __has_feature(objc_arc)
#define weakify(object) try{} @finally{} {} __weak __typeof__(object) weak##_##object = object;
#else
#define weakify(object) try{} @finally{} {} __block __typeof__(object) block##_##object = object;
#endif
#endif
#endif
#ifndef strongify
#if DEBUG
#if __has_feature(objc_arc)
#define strongify(object) autoreleasepool{} __typeof__(object) object = weak##_##object;
#else
#define strongify(object) autoreleasepool{} __typeof__(object) object = block##_##object;
#endif
#else
#if __has_feature(objc_arc)
#define strongify(object) try{} @finally{} __typeof__(object) object = weak##_##object;
#else
#define strongify(object) try{} @finally{} __typeof__(object) object = block##_##object;
#endif
#endif
#endif
9.NSLog的宏定義
#ifdef DEBUG
#define NSLog(format,...) printf("\n[%s] %s [第%d行] %s\n",__TIME__,__FUNCTION__,__LINE__,[[NSString stringWithFormat:format,## __VA_ARGS__] UTF8String]);
#else
#define NSLog(format, ...)
#endif
10.判斷是否為空
#define kStringIsEmpty(string) (string == NULL || [string isKindOfClass:[NSNull class]] || string == nil || [string length] < 1)
#define kArrayIsEmpty(array) (array == nil || [array isKindOfClass:[NSNull class]] || array.count == 0)
#define kDictionaryIsEmpty(dictionary) (dictionary == nil || [dictionary isKindOfClass:[NSNull class]] || dictionary.allKeys.count == 0)
#define kObjectIsEmpty(object) (object == nil||[object isKindOfClass:[NSNull class]]||([object respondsToSelector:@selector(length)] && [(NSData *)object length] == 0)|| ([object respondsToSelector:@selector(count)] && [(NSArray *)object count] == 0))
11.使用xib
創建自定義View并在背景添加點擊事件
說明:
xib
創建的自定義視圖,添加的背景點擊動作不會觸發點擊事件,因此需要單獨添加一個xibView
,添加到自定義視圖上,點擊動作添加到xibView
上就可以觸發點擊事件了,具體步驟如下:
- 創建自定義
FSCommonView
、創建FSCommonView.xib
、關聯到自定義的FSCommonView
。
關聯自定義視圖 - 將xib添加到
FSCommonView
中
#import <UIKit/UIKit.h>
@interface FSCommonView : UIView
@end
#import "FSCommonView.h"
@interface FSCommonView ()
@property (strong, nonatomic) UIView *xibView;
@end
@implementation
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.xibView = [self loadViewFromNib];
[self settingUI];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if (self) {
self.xibView = [self loadViewFromNib];
[self settingUI];
}
return self;
}
- (UIView *)loadViewFromNib {
UIView *xibView = [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil].firstObject;
xibView.frame = self.bounds;
[xibView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(xibBgViewClick)]];
[self addSubview:xibView];
return xibView;
}
- (void)settingUI {
// 設置背景色、圓角、邊框、自定義子視圖等。
}
- (void)xibBgViewClick {
// 背景點擊事件
}
@end
12.啄幕鳥
啄幕鳥,阿里開源項目,即手機屏幕上的啄木鳥,專抓App里的Bug。啄幕鳥集合了UI檢查、對象查看、方法監聽等多種開發工具,通過拾取UI控件、查看對象屬性、監聽方法調用、App內抓包等,不依賴電腦聯調,直接獲取運行時數據,快速定位Bug,提高開發效率。
功能簡介
- UI檢查:快速查看頁面布局、UI控件間距、字體顏色、UI控件類名、對象屬性/成員變量、圖片URL等。
- JSON抓包:便捷JSON抓包工具,通過監聽系統json解析抓包。
- 方法監聽:Bug聽診器,可監聽App中任意OC方法的調用,輸出調用參數、返回值等信息,可以通過屏幕日志輸入監聽、KVC取值等命令,支持后臺配置命令。
- po命令:執行類似LLDB的po命令,在App運行時執行po命令,調用任意方法。
- 系統信息:查看各種系統名稱、版本、屏幕、UA等信息,支持外部添加信息。
- SandBox:查看沙盒文件,導出文件等。
- Bundle:查看、導出Bundle目錄中的內容。
- Crash:查看Crash日志,需先打開一次Crash插件以開啟Crash監控。
- Defaults:查看、新增、刪除User Defaults。
- 清除數據:清除所有沙盒數據、User Default。
- 觸點顯示:顯示手指觸控。
- UI對比:支持將設計圖導入到App中進行對比,并可畫線、標注需修改的地方,方便UI走查。
- 查看圖片資源:查看、導出App中的資源圖片。
- CPU:查看CPU占用。
- 內存:查看內存占用。
- FPS:查看App幀率。
- 網絡流量:查看發送、接收網絡流量。
pod 'YKWoodpecker'
官方github地址:YKWoodpecker
啄幕鳥
使用
// 顯示啄幕鳥,啟動默認打開UI檢查插件
[[YKWoodpeckerManager sharedInstance] show];
13.ViewController的生命周期
1. initWithCoder:通過nib文件初始化時觸發。
2. awakeFromNib:nib文件被加載的時候,會發生一個awakeFromNib的消息到nib文件中的每個對象。
3. loadView:開始加載視圖控制器自帶的view。
4. viewDidLoad:視圖控制器的view被加載完成。
5. viewWillAppear:視圖控制器的view將要顯示在window上。
6. updateViewConstraints:視圖控制器的view開始更新AutoLayout約束。
7. viewWillLayoutSubviews:視圖控制器的view將要更新內容視圖的位置。
8. viewDidLayoutSubviews:視圖控制器的view已經更新視圖的位置。
9. viewDidAppear:視圖控制器的view已經展示到window上。
10. viewWillDisappear:視圖控制器的view將要從window上消失。
11. viewDidDisappear:視圖控制器的view已經從window上消失。
14. 去除Cocopods
第三方庫部分警告和MobileCoreServices.framework
過期的問題
在Podfile
的末尾處添加如下代碼,再 pod install
post_install do |pi|
# 去除Pods版本警告
pi.pods_project.targets.each do |t|
t.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '9.0'
end
end
# 替換Pods引用的不再使用的靜態庫MobileCoreServices.framework
framework = pi.pods_project.frameworks_group["iOS"]["MobileCoreServices.framework"]
framework.referrers.each do |ref|
if ref.isa == "PBXBuildFile"
ref.remove_from_project
end
end
framework.remove_from_project
end
個人博客: ?? ForgetSou