本文對應github地址Tip001,若是因爲github調整致使資源找不到,請訪問githubgit
防止collection短期點擊多個itemgithub
[collectionView setUserInteractionEnabled:NO];
[collectionView performSelector:@selector(setUserInteractionEnabled:) withObject:[NSNumber numberWithBool:YES] afterDelay:0.05f];
複製代碼
防止短期點擊兩個按鈕web
[view setExclusiveTouch:YES];
複製代碼
防止按鈕短期屢次點擊json
- (void)todoSomething:(id)sender {
// 在這裏作真正的事情
}
- (void)handleButtonClick:(UIButton *)sender {
// 先將未到時間執行前的任務取消。
[[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(todoSomething:) object:sender];
[self performSelector:@selector(todoSomething:) withObject:sender afterDelay:0.2f];
}
複製代碼
好比在 -viewDidAppear: 打斷點,在控制檯輸入windows
po [self.view.superview recursiveDescription]
複製代碼
只針對首尾api
NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString: @", "];
NSString *newString = [trimString stringByTrimmingCharactersInSet:set];
複製代碼
平移、旋轉、縮放、復原bash
// 平移按鈕
CGAffineTransform transForm = self.buttonView.transform;
self.buttonView.transform = CGAffineTransformTranslate(transForm, 10, 0);
// 旋轉按鈕
CGAffineTransform transForm = self.buttonView.transform;
self.buttonView.transform = CGAffineTransformRotate(transForm, M_PI_4);
// 縮放按鈕
self.buttonView.transform = CGAffineTransformScale(transForm, 1.2, 1.2);
// 初始化復位
self.buttonView.transform = CGAffineTransformIdentity;
複製代碼
第一步: viewDidLayoutSubviews 添加多線程
- (void)viewDidLayoutSubviews {
if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
[self.tableView setSeparatorInset:UIEdgeInsetsZero];
}
if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) {
[self.tableView setLayoutMargins:UIEdgeInsetsZero];
}
}
複製代碼
第二步: 重寫willDisplayCell方法app
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell
forRowAtIndexPath:(NSIndexPath *)indexPath {
if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
[cell setSeparatorInset:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}
複製代碼
兩個宏定義dom
#define TICK CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
#define TOCK NSLog(@"Time: %f", CFAbsoluteTimeGetCurrent() - start)
複製代碼
隨機顏色
#define RANDOM_COLOR [UIColor colorWithRed:arc4random_uniform(256)/255.0 green:arc4random_uniform(256)/255.0 blue:arc4random_uniform(256)/255.0 alpha:1]
複製代碼
顏色(RGBA)
#define DDYRGBA(r, g, b, a) [UIColor colorWithRed:(r)/255.0f green:(g)/255.0f blue:(b)/255.0f alpha:(a)]
複製代碼
宏定義(再也不建議用UIAlertView,推薦UIAlertController)
#define Alert(_S_, ...) [[[UIAlertView alloc] initWithTitle:@"提示" message:[NSString stringWithFormat:(_S_), ##__VA_ARGS__] delegate:nil cancelButtonTitle:@"肯定" otherButtonTitles:nil] show]
複製代碼
利用相應keyPath
NSArray *array = [NSArray arrayWithObjects:@"2.0", @"2.3", @"3.0", @"4.0", @"10", nil];
CGFloat sum = [[array valueForKeyPath:@"@sum.floatValue"] floatValue];
CGFloat avg = [[array valueForKeyPath:@"@avg.floatValue"] floatValue];
CGFloat max =[[array valueForKeyPath:@"@max.floatValue"] floatValue];
CGFloat min =[[array valueForKeyPath:@"@min.floatValue"] floatValue];
NSLog(@"%f\n%f\n%f\n%f",sum,avg,max,min);
複製代碼
轉成富文本(attributedText)
+ (__kindof NSMutableAttributedString *_Nonnull)changeTotalString:(NSString *_Nonnull)totalString subStringArray:(NSArray *_Nonnull)subStringArray subStringColor:(UIColor *_Nonnull)color andFont:(UIFont *_Nonnull)font {
NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:totalString];
for (NSString *rangeStr in subStringArray) {
NSRange range = [totalString rangeOfString:rangeStr options:NSBackwardsSearch];
[attributedStr addAttribute:NSForegroundColorAttributeName value:color range:range];
[attributedStr addAttribute:NSFontAttributeName value:font range:range];
}
return attributedStr;
}
複製代碼
須要引入AVFoundation
// 1.獲取音效資源的路徑
NSString *path = [[NSBundle mainBundle]pathForResource:@"sound" ofType:@"wav"];
// 2.將路徑轉化爲url
NSURL *tempUrl = [NSURL fileURLWithPath:path];
// 3.用轉化成的url建立一個播放器
NSError *error = nil;
AVAudioPlayer *player = [[AVAudioPlayer alloc]initWithContentsOfURL:tempUrl error:&error];
// 4.播放
[player play];
複製代碼
若是層級改變可適當調整
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
searchBar.showsCancelButton = YES;
for(UIView *view in [[[searchBar subviews] objectAtIndex:0] subviews]) {
if([view isKindOfClass:[NSClassFromString(@"UINavigationButton") class]]) {
UIButton * cancel =(UIButton *)view;
[cancel setTitle:@" 取消" forState:UIControlStateNormal];
}
}
return YES;
}
複製代碼
drawViewHierarchyInRect可截取導航(能夠用window截圖)
- (UIImage *)ddy_SnapshotImage {
UIGraphicsBeginImageContext(self.bounds.size);
if([self respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]){
[self drawViewHierarchyInRect:self.bounds afterScreenUpdates:NO];
} else{
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
}
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *imageData = UIImageJPEGRepresentation(image, 0.6);
image = [UIImage imageWithData:imageData];
return image;
}
複製代碼
我只是想要截個屏 附 [view snapshotViewAfterScreenUpdates:YES];
不知道如今還能不能用
import <objc/runtime.h>
Class LSApplicationWorkspace_class = objc_getClass("LSApplicationWorkspace");
NSObject* workspace = [LSApplicationWorkspace_class performSelector:@selector(defaultWorkspace)];NSLog(@"apps: %@", [workspace performSelector:@selector(allApplications)]);
複製代碼
特徵碼 JPEG,JPG: 0xFF 0xD8 2字節 JPG是JPEG的縮寫
BMP: 0x42 0x4D 2字節
PNG: 0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A 8字節
GIF: 0x47 0x49 0x46 0x38 0x39/ 0x37 0x61 GIF有87a和89a兩種格式
// 經過圖片Data數據第一個字節 來獲取圖片擴展名
- (NSString *)contentTypeForImageData:(NSData *)data {
uint8_t c;
[data getBytes:&c length:1];
switch (c) {
case 0xFF:
return @"jpeg";
case 0x89:
return @"png";
case 0x47:
case 0x37:
return @"gif";
case 0x49:
case 0x4D:
return @"tiff";
case 0x42:
return @"bmp";
case 0x52:
if ([data length] < 12) {
return nil;
}
NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding];
if ([testString hasPrefix:@"RIFF"] && [testString hasSuffix:@"WEBP"]) {
return @"webp";
}
return nil;
}
return nil;
}
複製代碼
其實圖片數據的第一個字節是固定的,一種類型的圖片第一個字節就是它的標識, 咱們來調用一下這個方法:
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:picPathStr]];
NSString *string = [self contentTypeForImageData:data];
複製代碼
謹慎使用
[[UIApplication sharedApplication] performSelector:@selector(suspend)]; // suspend:暫停;
複製代碼
URL編碼
NSString *URLStr = @"http://static.tripbe.com/videofiles/視頻/個人自拍視頻.mp4";
// NSString *path = (__bridge_transfer NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, (__bridge CFStringRef)URLStr, CFSTR(""), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));
NSString* encodedURLString = [URLStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
複製代碼
使用UIImageView
[view setBackGroundColor:[UIColor colorWithPatternImage:img];
CALayer
view.layer.contents = (__bridge id)image.CGImage;
// 設置顯示的圖片範圍,四個值在0-1之間,對應的爲x, y, w, h
view.layer.contentsCenter = CGRectMake(0.25,0.25,0.5,0.5);
複製代碼
見上 22
// 不必添加UIImageView,直接在layer上畫
self.view.layer.contents = (__bridge id _Nullable)([UIImage imageNamed:@"beijing"].CGImage)
複製代碼
也能夠本身設定路徑
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:view2.bounds byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight cornerRadii:CGSizeMake(10, 10)];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = view2.bounds;
maskLayer.path = maskPath.CGPath;
view2.layer.mask = maskLayer;
//其中,
byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight
/* 指定了須要成爲圓角的角,用「|」組合。該參數是UIRectCorner類型的,可選的值有:
* UIRectCornerTopLeft
* UIRectCornerTopRight
* UIRectCornerBottomLeft
* UIRectCornerBottomRight
* UIRectCornerAllCorners
*/
複製代碼
通常用於視頻播放
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
複製代碼
刪庫跑路,謹慎用之
# 清空廢紙簍
sudo rm -rf ~/.Trash/
# 刪除Xcode 編譯的數據
rm -rf ~/Library/Developer/Xcode/DerivedData/
# 代碼不提示刪除
rm ~/Library/Caches/com.apple.dt.Xcode
# pod search 搜不出真的存在的庫 zsl 用本身的
rm /Users/zsl/Library/Caches/CocoaPods/search_index.json
複製代碼
能自定義的最好自定義
tableView.tintColor = [UIColor redColor];
複製代碼
[textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];
[textField setValue:[UIFont boldSystemFontOfSize:16] forKeyPath:@"_placeholderLabel.font"];
複製代碼
方法一
// waitUntilDone:是否線程任務完成執行
[self performSelectorOnMainThread:@selector(updateImage:) withObject:data waitUntilDone:YES];
複製代碼
方法二
dispatch_async(dispatch_get_main_queue(), ^{
//更新UI的代碼,不用主線程中調用
});
複製代碼
方法三
// 使用NSOperationQueue
// 第一種:
[[NSOperationQueuemainQueue]addOperationWithBlock:^{
// do something
}];
// 第二種:將工做內容封裝在NSOperation中,而後
// [[NSOperationQueue mainQueue] addOperation:myOperation];
複製代碼
方法一
NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
複製代碼
方法二
- (void)resetDefaults {
NSUserDefaults * defs = [NSUserDefaults standardUserDefaults];
NSDictionary * dict = [defs dictionaryRepresentation];
for (id key in dict) {
[defs removeObjectForKey:key];
}
[defs synchronize];
}
複製代碼
注意有時候0就不生效了
// 只設一個可能仍出現20的高度,也不可設置0
// Header底部間距
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 40;//section頭部高度
}
// footer底部間距
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 0.001;
}
複製代碼
詳見多線程部分
// 後臺執行:
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// something
});
// 主線程執行:
dispatch_async(dispatch_get_main_queue(), ^{
// something
});
// 一次性執行:
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// code to be executed once
});
// 延遲2秒執行:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// code to be executed after a specified delay
});
複製代碼
當咱們用tabBarController時,若已經到其中一個TabBar的子頁,又要跳轉到某一個一級的頁面時,若是這樣寫,致使底部出現黑邊,引發tabbar消失的bug
[self.navigationController popToRootViewControllerAnimated:YES];
((AppDelegate *)AppDelegateInstance).tabBarController.selectedIndex = 2;
複製代碼
解決方法一:刪除動畫
[self.navigationController popToRootViewControllerAnimated:NO];
((AppDelegate *)AppDelegateInstance).tabBarController.selectedIndex = 2;
複製代碼
解決方法二:延遲執行另外一個系統操做
[self.navigationController popToRootViewControllerAnimated:NO];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
((AppDelegate *)AppDelegateInstance).tabBarController.selectedIndex = 2;
});
複製代碼
titleLabel.text = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
複製代碼
AppDelegate 中 - (BOOL)application: didFinishLaunchingWithOptions:
NSDictionary *dict = @{@"UserAgent":@"appwebkit"};
[[NSUserDefaults standardUserDefaults] registerDefaults:dict];
複製代碼
應用
// 獲取webView userAgent
NSMutableString *userAgent = [NSMutableString stringWithString:[[UIWebView new] stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"]];
// 更改UserAgent
NSString *newUagent = [NSString stringWithFormat:@"%@ WMall/%@", userAgent, [SystemInfo appShortVersion]];
NSDictionary *dictionnary = [[NSDictionary alloc] initWithObjectsAndKeys:newUagent, @"UserAgent", nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:dictionnary];
複製代碼
考慮到兼容性,只對某些webview實施自定義UA。[這幾個方法必定要是靜態方法,要否則設置UA不生效]
NSString* defaultUserAgent = nil;
#pragma mark 獲取默認的UA,用於恢復UA
+ (void)initialize {
if (self == [WebViewController class]) {
defaultUserAgent = [[UIWebView new] stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
}
}
#pragma mark 在默認UA後追加自定義UA
+ (void)registeCustomizeWebViewUserAgent {
UIDevice *device = [UIDevice currentDevice];
NSString *iOSName = [device systemName];
NSString *iOSVersion = [device systemVersion];
NSString *customizeUserAgent = [NSString stringWithFormat:@"xxxxxMobile/%@ (Platform/%@; %@/%@)", APP_SHORT_VERSION, @"iPad", iOSName, iOSVersion];
NSString *webViewUserAgent = [[UIWebView new] stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
customizeUserAgent = [webViewUserAgent stringByAppendingFormat:@" %@", customizeUserAgent];
if (customizeUserAgent) {
[[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"UserAgent": customizeUserAgent}];
}
}
- (void)dealloc {
/*因爲自定義的userAgent沒法播放webview的視頻,因此。當webview銷燬的時候,重置一下userAgent*/
[[self class] recoverDefaultUserAgent];
}
+ (void) recoverDefaultUserAgent {
if (defaultUserAgent) {
[[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"UserAgent": defaultUserAgent}];
}
}
複製代碼
- (NSString *)Charactor:(NSString *)aString getFirstCharactor:(BOOL)isGetFirst {
// 轉成了可變字符串
NSMutableString *str = [NSMutableString stringWithString:aString];
// 先轉換爲帶聲調的拼音
CFStringTransform((CFMutableStringRef)str,NULL, kCFStringTransformMandarinLatin,NO);
// 再轉換爲不帶聲調的拼音
CFStringTransform((CFMutableStringRef)str,NULL, kCFStringTransformMandarinLatin,NO);
CFStringTransform((CFMutableStringRef)str, NULL, kCFStringTransformStripDiacritics, NO);
NSString *pinYin = [str capitalizedString];
//轉化爲大寫拼音
if(isGetFirst) {
// 獲取並返回首字母
return [pinYin substringToIndex:1];
} else {
return pinYin;
}
}
複製代碼
優化release,防止打印
// 處於開發階段
#ifdef DEBUG
#define DDYLog(...) NSLog(__VA_ARGS__)
//#define DDYInfoLog(fmt, ...) fprintf(stderr,"\nfunction:%s line:%d content:%s\n", __FUNCTION__, __LINE__, [NSString stringWithFormat:fmt, ##__VA_ARGS__] UTF8String]);
#define DDYInfoLog(fmt, ...) {\
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];\
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];\
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];\
[dateFormatter setDateFormat:@"HH:mm:ss:SSS"]; \
NSString *str = [dateFormatter stringFromDate:[NSDate date]];\
fprintf(stderr,"[%s %s %d]: %s\n",[str UTF8String], [[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, [[NSString stringWithFormat:fmt, ##__VA_ARGS__] UTF8String]);\
}
//#define DDYInfoLog(fmt, ...) NSLog((@"\n[fileName:%s]\n[methodName:%s]\n[lineNumber:%d]\n" fmt),__FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__)
// 處於發佈階段
#else
#define DDYLog(...)
#define DDYInfoLog(...)
#endif
複製代碼
Too many arguments to function call ,expected 0,have3
Project --> Build Settings --> 搜索objc --> ENABLE_STRICT_OBJC_MSGSEND --> 設置NO
複製代碼
void UncaughtExceptionHandler(NSException *exception) {
NSArray *callStackSymbols = [exception callStackSymbols];
NSString *callStackSymbolStr = [callStackSymbols componentsJoinedByString:@"\n"];
NSString *reason = [exception reason];
NSString *name = [exception name];
DDYInfoLog(@"異常名稱:%@\n異常緣由:%@\n堆棧標誌:%@",name, reason, callStackSymbolStr);
}
複製代碼
- application: didFinishLaunchingWithOptions:
NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
複製代碼
界限更鮮明
self.imageView = ({
UIImageView *imageView = [[UIImageView alloc] init];
imageView.image = [UIImage imageNamed:@"12345"];
imageView.frame = CGRectMake(0, 0, 100, 100);
[self.view addSubview:imageView];
imageView;
});
複製代碼
能不用最好不用,能不在View中跳轉最好別在View中跳轉
+ (UIViewController *)findCurrentResponderViewController{
UIViewController *currentVC = nil;
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
if (window.windowLevel != UIWindowLevelNormal) {
NSArray *windows = [[UIApplication sharedApplication] windows];
for(UIWindow *tmpWin in windows) {
if (tmpWin.windowLevel == UIWindowLevelNormal) {
window = tmpWin; break;
}
}
}
UIView *frontView = [[window subviews] objectAtIndex:0];
id nextResponder = [frontView nextResponder];
if ([nextResponder isKindOfClass:[UIViewController class]]) {
currentVC = nextResponder;
} else {
UIViewController *topVC = window.rootViewController.presentedViewController;
if (topVC) {
currentVC = topVC;
} else {
currentVC = window.rootViewController;
}
}
return currentVC;
}
複製代碼
view中跳轉
NASkillAptitudeVC *vc = [[NASkillAptitudeVC alloc] init];
[[self currentViewController].navigationController pushViewController:vc animated:YES];
- (UIViewController *)currentViewController {
UIResponder *next = self.nextResponder;
do {
//判斷響應者是否爲視圖控制器
if ([next isKindOfClass:[UIViewController class]]) {
return (UIViewController *)next;
}
next = next.nextResponder;
} while (next != nil);
return nil;
}
複製代碼
CAShapeLayer *borderLayer = [CAShapeLayer layer];
borderLayer.bounds = self.picView.frame;
borderLayer.position = self.picView.center;
borderLayer.path = [UIBezierPath bezierPathWithRoundedRect:borderLayer.bounds cornerRadius:3].CGPath;
borderLayer.lineWidth = 1;
borderLayer.lineDashPattern = @[@4, @2];
borderLayer.fillColor = [UIColor clearColor].CGColor;
borderLayer.strokeColor = [UIColor grayColor].CGColor;
[self.picView.layer addSublayer:borderLayer];
複製代碼
- (void)setFrame:(CGRect)frame {
// 總體向下 移動10
frame.origin.y += 10;
// 間隔10
frame.size.height -= 10;
[super setFrame:frame];
}
複製代碼
酌情選擇裏面代碼
- (void)deleteTopBlank {
self.edgesForExtendedLayout = UIRectEdgeNone;
self.navigationController.navigationBar.translucent = NO;
self.automaticallyAdjustsScrollViewInsets = NO;
self.extendedLayoutIncludesOpaqueBars = YES
}
複製代碼