iOS開發(fā)實用筆記(不斷更新)

先說下在項目中遇到問題前,個人的編程習(xí)慣:為網(wǎng)絡(luò)請求建立請求類,為按鈕創(chuàng)建類目節(jié)省代碼量,為網(wǎng)絡(luò)鏈接創(chuàng)建頭文件,合理運用PCH使代碼看起來更簡潔.接手一個新項目,快速的調(diào)試,查看某個模塊或者方法的作用,需要注釋掉一個方法,或者某個代碼塊,直接寫return;而不是全選,注釋掉.

1、禁止手機睡眠

//方法一
[UIApplication sharedApplication].idleTimerDisabled = YES;
//方法二
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];

2、修改xcode文件模板

Finder -> 應(yīng)用程序-> Xcode ->右鍵顯示包內(nèi)容,然后可以看到一個content文件夾,我們要找到這個路徑下的一個File Templates(文件模版)。
路徑為Contents -> Developer -> Platforms -> iPhoneOS.platform -> Developer -> Library -> Xcode -> Templates -> File Templates
大家看到File Templates文件夾下面有五個文件夾,我們需要修改的是Source文件夾下面的Cocoa Touch Class.xctemplate對應(yīng)的所有文件的.h和.m

3、block避免循環(huán)引用的三種方式

block會產(chǎn)生循環(huán)引用的原因是block會對其所包含的所有強指針變量強引用一次
//方式1
__weak typeof(self) weakSel = self;
__strong typeof(weakSel) strongeSelf = weakSel;
__weak 通常與 __strong 同時使用  避免因為控制器釋放后延遲操作被影響
//方式2
//self的本質(zhì)是一個指針
    __block ViewController *weakSelf = self;
    self.block = ^{
        NSLog(@"%@",weakSelf);
        //不要忘記指針置空
        weakSelf = nil;
    };
    self.block();
//方式3
self.block2 = ^(ViewController *obj){
        NSLog(@"%@",obj);
    };
    self.block2(self);

4、從網(wǎng)頁中跳轉(zhuǎn)到自己的 APP 中的方法 (Universal Links)

在系統(tǒng)自帶的 Safari 瀏覽器中輸入 scheme 并多加一個冒號和雙斜杠,就可以跳轉(zhuǎn)到自己的 APP 當中

5、強制讓App直接退出(非閃退,非崩潰)

UIWindow *window = [UIApplication sharedApplication].keyWindow;
    [UIView animateWithDuration:1.0f animations:^{
        window.alpha = 0;
    } completion:^(BOOL finished) {
        exit(0);
    }];

或者
[[UIApplication sharedApplication] performSelector:@selector(suspend)];

6、刪除NSUserDefaults所有記錄

//方法一
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];
}

7、iOS跳轉(zhuǎn)到App Store下載應(yīng)用評分

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=APPID"]];

8、根據(jù)UIView獲取所在的UIViewController

方法 1
id responder = self.nextResponder;
    while (![responder isKindOfClass: [UIViewController class]] && ![responder isKindOfClass: [UIWindow class]]){
            responder = [responder nextResponder];
        }
    if ([responder isKindOfClass: [UIViewController class]]){
        // responder就是view所在的控制器
    }

方法 2
- (UIViewController *)getControllerFromView:(UIView *)view {
    // 遍歷響應(yīng)者鏈。返回第一個找到視圖控制器
    UIResponder *responder = view;
    while ((responder = [responder nextResponder])){
        if ([responder isKindOfClass: [UIViewController class]]){
            return (UIViewController *)responder;
        }
    }
    // 如果沒有找到則返回nil
    return nil;
}

9、獲取一個類的所有子類

+ (NSArray *) allSubclasses
{
    Class myClass = [self class];
    NSMutableArray *mySubclasses = [NSMutableArray array];
    unsigned int numOfClasses;
    Class *classes = objc_copyClassList(&numOfClasses;);
    for (unsigned int ci = 0; ci < numOfClasses; ci++)
    {
        Class superClass = classes[ci];
        do{
            superClass = class_getSuperclass(superClass);
        } while (superClass && superClass != myClass);

        if (superClass)
        {
            [mySubclasses addObject: classes[ci]];
        }
    }
    free(classes);
    return mySubclasses;
}

10、防止scrollView手勢覆蓋側(cè)滑手勢

創(chuàng)建UIscrollview的類目,然后寫以下方法

//是否支持多手勢觸發(fā),返回YES,則可以多個手勢一起觸發(fā)方法,返回NO則為互斥.
//是否允許多個手勢識別器共同識別,一個控件的手勢識別后是否阻斷手勢識別繼續(xù)向下傳播,默認返回NO;如果為YES,響應(yīng)者鏈上層對象觸發(fā)手勢識別后,如果下層對象也添加了手勢并成功識別也會繼續(xù)執(zhí)行,否則上層對象識別后則不再繼續(xù)傳播
//一句話總結(jié)就是此方法返回YES時,手勢事件會一直往下傳遞,不論當前層次是否對該事件進行響應(yīng)。
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    
    if ([self panBack:gestureRecognizer]) {
        return YES;
    }
    return NO;
}

//location_X可自己定義,其代表的是滑動返回距左邊的有效長度
- (BOOL)panBack:(UIGestureRecognizer *)gestureRecognizer {
    
    //是滑動返回距左邊的有效長度
    int location_X =0.15*kSCREENWIDTH;
    
    if (gestureRecognizer ==self.panGestureRecognizer) {
        UIPanGestureRecognizer *pan = (UIPanGestureRecognizer *)gestureRecognizer;
        CGPoint point = [pan translationInView:self];
        UIGestureRecognizerState state = gestureRecognizer.state;
        if (UIGestureRecognizerStateBegan == state ||UIGestureRecognizerStatePossible == state) {
            CGPoint location = [gestureRecognizer locationInView:self];
            
            //這是允許每張圖片都可實現(xiàn)滑動返回
            int temp1 = location.x;
            int temp2 =kSCREENWIDTH;
            NSInteger XX = temp1 % temp2;
            if (point.x >0 && XX < location_X) {
                return YES;
            }
            //下面的是只允許在第一張時滑動返回生效
            //            if (point.x > 0 && location.x < location_X && self.contentOffset.x <= 0) {
            //                return YES;
            //            }
        }
    }
    return NO;
    
}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    
    if ([self panBack:gestureRecognizer]) {
        return NO;
    }
    return YES;
    
}

11、獲取手機安裝的應(yīng)用

Class c =NSClassFromString(@"LSApplicationWorkspace");
    id s = [(id)c performSelector:NSSelectorFromString(@"defaultWorkspace")];
    NSArray *array = [s performSelector:NSSelectorFromString(@"allInstalledApplications")];
    for (id item in array)
    {
        NSLog(@"%@",[item performSelector:NSSelectorFromString(@"applicationIdentifier")]);
        //NSLog(@"%@",[item performSelector:NSSelectorFromString(@"bundleIdentifier")]);
        NSLog(@"%@",[item performSelector:NSSelectorFromString(@"bundleVersion")]);
        NSLog(@"%@",[item performSelector:NSSelectorFromString(@"shortVersionString")]);
    }

12、解決NSTimer循環(huán)引用的幾種方式

1.在視圖已經(jīng)消失的方法中,將定時器銷毀掉
-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    [self.timer invalidate];
    self.timer = nil;
}
2.self強引用timer弱引用target
也就是創(chuàng)建定時器的時候,定時器用強引用的 self 修飾,但是在定時器執(zhí)行的方法中,self 需要用弱引用修飾
__weak typeof(self) weakSelf = self;
3. 借助runtime給對象添加消息處理的能力
_target = [[NSObject alloc] init];
    class_addMethod([_target class], @selector(fire), class_getMethodImplementation([self class], @selector(fire)), "v@:");
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:_target selector:@selector(fire) userInfo:nil repeats:YES];
4.通過消息轉(zhuǎn)發(fā)的方法的方式
創(chuàng)建一個集成自NSProxy的類PHJProxy 聲明一個target

    #import <Foundation/Foundation.h>
    #import <objc/runtime.h>
    
    @interface PHJProxy : NSProxy
    
    @property (nonatomic, weak) id target;
    
    @end
PHJProxy的實現(xiàn)

    @implementation PHJProxy
    // 發(fā)送給target
    - (void)forwardInvocation:(NSInvocation *)invocation {
        [invocation invokeWithTarget:self.target];
    }
    // 給target注冊一個方法簽名
    - (nullable NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
        return [self.target methodSignatureForSelector:sel];
    }
    
    @end
PHJProxy 和 NSTimer的使用

    self.proxy = [PHJProxy alloc];
    self.proxy.target = self;
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self.proxy selector:@selector(fire) userInfo:nil repeats:YES];
其原理為:self強引用timer強引用proxy弱引用self

13、開發(fā)中常用通知

// 當程序被推送到后臺時
UIKIT_EXTERN NSNotificationName const UIApplicationDidEnterBackgroundNotification       NS_AVAILABLE_IOS(4_0);
// 當程序從后臺將要重新回到前臺時
UIKIT_EXTERN NSNotificationName const UIApplicationWillEnterForegroundNotification      NS_AVAILABLE_IOS(4_0);
// 當程序完成載入后通知
UIKIT_EXTERN NSNotificationName const UIApplicationDidFinishLaunchingNotification;
// 應(yīng)用程序轉(zhuǎn)為激活狀態(tài)時
UIKIT_EXTERN NSNotificationName const UIApplicationDidBecomeActiveNotification;
// 用戶按下主屏幕按鈕調(diào)用通知,并未進入后臺狀態(tài)
UIKIT_EXTERN NSNotificationName const UIApplicationWillResignActiveNotification;
// 內(nèi)存較低時通知
UIKIT_EXTERN NSNotificationName const UIApplicationDidReceiveMemoryWarningNotification;
// 當程序?qū)⒁顺鰰r通知
UIKIT_EXTERN NSNotificationName const UIApplicationWillTerminateNotification;
// 當系統(tǒng)時間發(fā)生改變時通知
UIKIT_EXTERN NSNotificationName const UIApplicationSignificantTimeChangeNotification;
// 當StatusBar框方向?qū)⒁兓瘯r通知
UIKIT_EXTERN NSNotificationName const UIApplicationWillChangeStatusBarOrientationNotification __TVOS_PROHIBITED; // userInfo contains NSNumber with new orientation
// 當StatusBar框方向改變時通知
UIKIT_EXTERN NSNotificationName const UIApplicationDidChangeStatusBarOrientationNotification __TVOS_PROHIBITED;  // userInfo contains NSNumber with old orientation
// 當StatusBar框Frame將要改變時通知
UIKIT_EXTERN NSNotificationName const UIApplicationWillChangeStatusBarFrameNotification __TVOS_PROHIBITED;       // userInfo contains NSValue with new frame
// 當StatusBar框Frame改變時通知
UIKIT_EXTERN NSNotificationName const UIApplicationDidChangeStatusBarFrameNotification __TVOS_PROHIBITED;        // userInfo contains NSValue with old frame
// 后臺下載狀態(tài)發(fā)生改變時通知(iOS7.0以后可用)
UIKIT_EXTERN NSNotificationName const UIApplicationBackgroundRefreshStatusDidChangeNotification NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;
// 受保護的文件當前變?yōu)椴豢捎脮r通知
UIKIT_EXTERN NSNotificationName const UIApplicationProtectedDataWillBecomeUnavailable    NS_AVAILABLE_IOS(4_0);
// 受保護的文件當前變?yōu)榭捎脮r通知
UIKIT_EXTERN NSNotificationName const UIApplicationProtectedDataDidBecomeAvailable       NS_AVAILABLE_IOS(4_0);
// 截屏通知(iOS7.0以后可用)
UIKIT_EXTERN NSNotificationName const UIApplicationUserDidTakeScreenshotNotification NS_AVAILABLE_IOS(7_0);

UIKeyboardWillShowNotification       // 鍵盤即將顯示
UIKeyboardDidShowNotification        // 鍵盤顯示完畢
UIKeyboardWillHideNotification       // 鍵盤即將隱藏
UIKeyboardDidHideNotification        // 鍵盤隱藏完畢

14、自定義設(shè)置狀態(tài)欄背景顏色

/** 自定義設(shè)置狀態(tài)欄背景顏色  */
- (void)setStatusBarBackgroundColor:(UIColor *)color {
    UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
    if ([statusBar respondsToSelector:@selector(setBackgroundColor:)]){
        statusBar.backgroundColor = color;
    }
}

15、自定義通知的標準寫法

// 聲明文件
UIKIT_EXTERN NSNotificationName const ZOCFooDidBecomeBarNotification; 
// 實現(xiàn)文件
NSNotificationName const ZOCFooDidBecomeBarNotification = @"ZOCFooDidBecomeBarNotification";

16、navigationBar下面的橫線

首先說明下其實這是shadoImage 在作怪,這道橫線,其實是NaVigationBar下產(chǎn)生的陰影效果,貼在一起就出現(xiàn)了橫線的樣式.因此,只要去掉陰影效果即可.而且我們也可以用同樣的方法來去掉tabbar上面的橫線
[self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
//消除陰影
self.navigationController.navigationBar.shadowImage = [UIImage new];


//去除UINavigationBar的黑線
    [[UINavigationBar appearance]setShadowImage:[UIImage new]];
    [[UINavigationBar appearance]setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
    //去除UITabBar的黑線
    [[UITabBar appearance]setShadowImage:[UIImage new]];
    [[UITabBar appearance]setBackgroundImage:[UIImage new]];

17、表視圖的分割線向左頂格顯示

通常我們用的表視圖的分割線并不是左右兩邊都頂格顯示的,應(yīng)該是從左邊15的距離開始顯示的,但是有時候我們就想讓分割線頂格,這時候就需要將分割線左移15
首先在viewDidLoad方法中加上如下代碼:
    if ([tableView respondsToSelector:@selector(setSeparatorInset:)]) {
        [tableView setSeparatorInset: UIEdgeInsetsZero];
    }
    if ([tableView respondsToSelector:@selector(setLayoutMargins:)]) {
        [tableView setLayoutMargins: UIEdgeInsetsZero];
    }
然后再加上這個方法:
  - (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];
    }
}
當然,也可以在在自定義的cell視圖里重寫父視圖的setFrame方法進行設(shè)置,方法很多,并不是固定的

18、同時識別多個手勢,解決因為 ScrollView 橫向滑動造成的與手勢返回的沖突問題

//在 navigationcontroller 基類中添加上如下方法即可
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
    return YES;
}

19、使用終端查詢哪個 SDK 使用了 UIWebView 的 API

首先要 cd進入到工程的根目錄,然后輸入如下命令
grep -r "UIWebView" .

20、獲取目標視圖在window坐標系的frame

//獲取目標視圖在window坐標系的frame
CGRect rect = [self.view convertRect:self.wobBtn.frame toView:[UIApplication sharedApplication].keyWindow];
UIBezierPath *path = [UIBezierPath bezierPathWithRect:frame];
[path appendPath:[[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:5] bezierPathByReversingPath]];
// bezierPathByReversingPath 的意思就是反轉(zhuǎn) 就是將你設(shè)置的路徑以外的部分加入到路徑中這樣 你設(shè)置的路徑就不在繪制的范圍之內(nèi)。在setMaskLayer的時候 你設(shè)置的那部分路徑就沒有了 就成了鏤空的。 clockwise 這個值得意思也是這樣。

21、動畫效果切換根視圖

[UIView transitionWithView:[UIApplication sharedApplication].keyWindow duration:0.5f options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
        BOOL oldState = [UIView areAnimationsEnabled];
        [UIView setAnimationsEnabled:NO];
        [UIApplication sharedApplication].keyWindow.rootViewController = [[TabViewController alloc]init];
        [UIView setAnimationsEnabled:oldState];
    } completion:^(BOOL finished) {
        
    }];


//或者
[UIView transitionFromView:self.view toView:chatVC.view duration:1 options:UIViewAnimationOptionTransitionFlipFromBottom completion:^(BOOL finished) {

    }];

22、當我們想要在閃屏界面多顯示一段時間時,需要阻塞主線程

//延遲五秒  方法1
[NSThread sleepForTimeInterval:5];
//延遲五秒  方法2
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:5]];

23、簡單的圖文混排

-(NSMutableAttributedString *)setTextAttachmentImageName:(NSString *)attachImage andText:(NSString *)text{
    NSMutableAttributedString *textAttrStr = [[NSMutableAttributedString alloc] init];
    NSTextAttachment *attach = [[NSTextAttachment alloc] init];
    attach.image = [UIImage imageNamed:attachImage];
    //font.lineHeight  該字體大小所對應(yīng)的行高
    attach.bounds = CGRectMake(KScale(-2), KScale(-2) ,KScale(12), KScale(12));
    
    NSAttributedString *imgStr = [NSAttributedString attributedStringWithAttachment:attach];
    [textAttrStr appendAttributedString:[[NSAttributedString alloc] initWithString:text]];
    [textAttrStr appendAttributedString:imgStr];
    return textAttrStr;
}

24、顏色轉(zhuǎn)圖片

-(UIImage *)cl_imageWithColor:(UIColor *)color {
  CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
  UIGraphicsBeginImageContext(rect.size);
  CGContextRef context = UIGraphicsGetCurrentContext();

  CGContextSetFillColorWithColor(context, [color CGColor]);
  CGContextFillRect(context, rect);

  UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();

  return image;
}

25、Runtime常用 API

// 1.objc_xxx 系列函數(shù)
objc_getClass     獲取Class對象
objc_getMetaClass     獲取MetaClass對象
objc_allocateClassPair     分配空間,動態(tài)的創(chuàng)建一個類(僅在 創(chuàng)建之后,注冊之前 能夠添加成員變量)
objc_registerClassPair     注冊一個類(注冊后方可使用該類創(chuàng)建對象,要在注冊之前添加成員變量)
objc_disposeClassPair     注銷某個類
objc_allocateProtocol     開辟空間創(chuàng)建協(xié)議
objc_registerProtocol     注冊一個協(xié)議
objc_constructInstance     構(gòu)造一個實例對象(ARC下無效)
objc_destructInstance     析構(gòu)一個實例對象(ARC下無效)
objc_setAssociatedObject     為實例對象關(guān)聯(lián)對象
objc_getAssociatedObje*ct     獲取實例對象的關(guān)聯(lián)對象
objc_removeAssociatedObjects     清空實例對象的所有關(guān)聯(lián)對象

objc_系列函數(shù)關(guān)注于宏觀使用,如類與協(xié)議的空間分配,注冊,注銷等操作

// 2.class_xxx 系列函數(shù)
class_addIvar     為類添加實例變量
class_addProperty     為類添加屬性
class_addMethod     為類添加方法
class_addProtocol     為類遵循協(xié)議
class_replaceMethod     替換類某方法的實現(xiàn)
class_getName     獲取類名
class_isMetaClass     判斷是否為元類
objc_getProtocol     獲取某個協(xié)議
objc_copyProtocolList     拷貝在運行時中注冊過的協(xié)議列表
class_getSuperclass     獲取某類的父類
class_setSuperclass     設(shè)置某類的父類
class_getProperty     獲取某類的屬性
class_getInstanceVariable     獲取實例變量
class_getClassVariable     獲取類變量
class_getInstanceMethod     獲取實例方法
class_getClassMethod     獲取類方法
class_getMethodImplementation     獲取方法的實現(xiàn)
class_getInstanceSize     獲取類的實例的大小
class_respondsToSelector     判斷類是否實現(xiàn)某方法
class_conformsToProtocol     判斷類是否遵循某協(xié)議
class_createInstance     創(chuàng)建類的實例
class_copyIvarList     拷貝類的實例變量列表
class_copyMethodList     拷貝類的方法列表
class_copyProtocolList     拷貝類遵循的協(xié)議列表
class_copyPropertyList     拷貝類的屬性列表

class_系列函數(shù)關(guān)注于類的內(nèi)部,如實例變量,屬性,方法,協(xié)議等相關(guān)問題

// 3.object_xxx 系列函數(shù)
object_copy     對象copy(ARC無效)
object_dispose     對象釋放(ARC無效)
object_getClassName     獲取對象的類名
object_getClass     獲取對象的Class(獲取 isa 指針指向的類)
object_setClass     設(shè)置對象的Class(設(shè)置 isa 指針指向的類)
object_isClass    判斷一個 Class是否為元類
object_isMetaClass    判斷一個 oc 對象是否為 Class
object_getSuperClass    獲取父類
object_getIvar     獲取對象中實例變量的值
object_setIvar     設(shè)置對象中實例變量的值
object_getInstanceVariable     獲取對象中實例變量的值 (ARC中無效,使用object_getIvar)
object_setInstanceVariable     設(shè)置對象中實例變量的值 (ARC中無效,使用object_setIvar)

objcet_系列函數(shù)關(guān)注于對象的角度,如實例變量

// 4.method_xxx 系列函數(shù)
method_getName     獲取方法名
method_getImplementation     獲取方法的實現(xiàn)
method_getTypeEncoding     獲取方法的類型編碼
method_getNumberOfArguments     獲取方法的參數(shù)個數(shù)
method_copyReturnType     拷貝方法的返回類型
method_getReturnType     獲取方法的返回類型
method_copyArgumentType     拷貝方法的參數(shù)類型
method_getArgumentType     獲取方法的參數(shù)類型
method_getDescription     獲取方法的描述
method_setImplementation     設(shè)置方法的實現(xiàn)
method_exchangeImplementations     替換方法的實現(xiàn)

method_系列函數(shù)關(guān)注于方法內(nèi)部,如果方法的參數(shù)及返回值類型和方法的實現(xiàn)

// 5.property_xxx 系列函數(shù)
property_getName               獲取屬性名
property_getAttributes         獲取屬性的特性列表
property_copyAttributeList     拷貝屬性的特性列表
property_copyAttributeValue    拷貝屬性中某特性的值

property_系類函數(shù)關(guān)注與屬性*內(nèi)部,如屬性的特性等

// 6.protocol_xxx 系列函數(shù)
protocol_conformsToProtocol     判斷一個協(xié)議是否遵循另一個協(xié)議
protocol_isEqual     判斷兩個協(xié)議是否一致
protocol_getName     獲取協(xié)議名稱
protocol_copyPropertyList     拷貝協(xié)議的屬性列表
protocol_copyProtocolList     拷貝某協(xié)議所遵循的協(xié)議列表
protocol_copyMethodDescriptionList     拷貝協(xié)議的方法列表
protocol_addProtocol     為一個協(xié)議遵循另一協(xié)議
protocol_addProperty     為協(xié)議添加屬性
protocol_getProperty     獲取協(xié)議中的某個屬性
protocol_addMethodDescription     為協(xié)議添加方法描述
protocol_getMethodDescription     獲取協(xié)議中某方法的描述

// 7.ivar_xxx 系列函數(shù)
ivar_getName     獲取Ivar名稱
ivar_getTypeEncoding     獲取類型編碼
ivar_getOffset     獲取偏移量

// 8.sel_xxx 系列函數(shù)
sel_getName     獲取名稱
sel_getUid     注冊方法
sel_registerName     注冊方法
sel_isEqual     判斷方法是否相等

// 9.imp_xxx 系列函數(shù)
imp_implementationWithBlock     通過代碼塊創(chuàng)建IMP
imp_getBlock     獲取函數(shù)指針中的代碼塊
imp_removeBlock     移除IMP中的代碼塊

26、修改UITextField的placeholder顏色

方法1、使用富文本
@property(nonatomic,copy)   NSAttributedString     *attributedPlaceholder;
// 文字屬性
NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
attrs[NSForegroundColorAttributeName] = [UIColor grayColor];

// NSAttributedString : 帶有屬性的文字(富文本技術(shù))
NSAttributedString *placeholder = [[NSAttributedString alloc] initWithString:@"手機號" attributes:attrs];
self.phoneField.attributedPlaceholder = placeholder;

NSMutableAttributedString *placehoder = [[NSMutableAttributedString alloc] initWithString:@"手機號"];
[placehoder setAttributes:@{NSForegroundColorAttributeName : [UIColor whiteColor]} range:NSMakeRange(0, 1)];
[placehoder setAttributes:@{
                            NSForegroundColorAttributeName : [UIColor yellowColor],
                            NSFontAttributeName : [UIFont systemFontOfSize:30]
                            } range:NSMakeRange(1, 1)];
[placehoder setAttributes:@{NSForegroundColorAttributeName : [UIColor redColor]} range:NSMakeRange(2, 1)];
self.phoneField.attributedPlaceholder = placehoder;
方法2、重寫方法
- (void)drawPlaceholderInRect:(CGRect)rect
{
    [self.placeholder drawInRect:CGRectMake(0, 10, rect.size.width, 25) withAttributes:@{
                                                       NSForegroundColorAttributeName : [UIColor grayColor],
                                                       NSFontAttributeName : self.font}];
}
方法3、用KVC
[textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];
//同理還可以修改textField的placeholder的字體大小
[textField setValue:[UIFont boldSystemFontOfSize:16] forKeyPath:@"_placeholderLabel.font"];

27、給定的數(shù)字翻轉(zhuǎn)

-(int)reverse:(int)number{
    int result = 0;
    while (number) {
        result = result * 10 + number % 10;
        number = number / 10;
    }
    return result;
}

28、控制屏幕旋轉(zhuǎn),在控制器中寫

/** 是否支持自動轉(zhuǎn)屏 */
- (BOOL)shouldAutorotate {
    return YES;
}

/** 支持哪些屏幕方向 */
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}

/** 默認的屏幕方向(當前ViewController必須是通過模態(tài)出來的UIViewController(模態(tài)帶導(dǎo)航的無效)方式展現(xiàn)出來的,才會調(diào)用這個方法) */
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationLandscapeLeft | UIInterfaceOrientationLandscapeRight;
}

29、將頂部navigationbar設(shè)置為透明,但是返回按鈕和標題不透明

//iOS 11之前
[[[self.navigationController.navigationBar subviews] objectAtIndex:0] setAlpha:0];
//iOS11以后
UIView * barBackground = self.navigationController.navigationBar.subviews.firstObject;
 if (@available(iOS 11.0, *))
    {
        [barBackground.subviews setValue:@(0) forKeyPath:@"alpha"];
    } else {
        barBackground.alpha = 0;
    }
如果想像QQ空間或者微博那樣動態(tài)的改變透明度,只需要在scrollViewDidScroll方法中,動態(tài)去設(shè)置alpha值就行,何時開始改變、變化率全憑自定義的參數(shù)控制.
//通常還要取消滾動視圖的自適應(yīng)尺寸
self.automaticallyAdjustsScrollViewInsets = NO;
static CGFloat alpha = 0;
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
    if (scrollView == _tableView) {
    alpha =  scrollView.contentOffset.y/400;
    alpha = (alpha <= 0)?0:alpha;
    alpha = (alpha >= 1)?1:alpha;
    //設(shè)置bar的顏色
    self.navigationController.navigationBar.barTintColor = [UIColor orangeColor];
    //設(shè)置透明度
    [[[self.navigationController.navigationBar subviews]objectAtIndex:0] setAlpha:alpha];
  }
}

30、關(guān)閉滾動視圖的自動布局

self.automaticallyAdjustsScrollViewInsets = NO;
還有一種方式也可以關(guān)閉自適應(yīng),利用了edgeInset內(nèi)嵌邊距,tableView的frame依舊是全屏尺寸的,只是設(shè)置了下contentInset使得其內(nèi)容視圖的尺寸改變了,scrollIndicatorInsets是右側(cè)的滑動指示器,要跟著一起才自然。如果當前頁還有tabBar的話,只需要設(shè)置UIEdgeInsetsMake的bottom值就行
_tableView.contentInset = UIEdgeInsetsMake(64, 0, 0, 0);
還可以這么寫
self.edgesForExtendedLayout = UIRectEdgeNone;

31、拖動表視圖時,松手再判斷是否隱藏navigationbar

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{
    NSLog(@"======== %lf", velocity.y);
    if(velocity.y > 0) {
        [self.navigationController setNavigationBarHidden:YES animated:YES];
    }
    else {
        [self.navigationController setNavigationBarHidden:NO animated:YES];
    }
}
說明一下:velocity.y這個量,在上滑和下滑時,變化極?。ㄐ?shù)),但是因為方向不同,有正負之分,這就很好處理了。

32、拖動表視圖時,不松手就判斷是否隱藏navigationbar

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    CGFloat offsetY = scrollView.contentOffset.y + _tableView.contentInset.top;
    //注意:panTranslationY是scrollView的pan手勢的手指位置的y值,這個方法是個人自己想到的,可能不是太好,因為panTranslationY這個值在較小幅度上下滑動時,可能都為正或都為負,這就使得這一方式不太靈敏
    CGFloat panTranslationY = [scrollView.panGestureRecognizer translationInView:self.tableView].y;
    //這里的offsetY > 64只是為了在視圖滑過navigationBar的高度之后才開始處理,防止影響展示效果。
    if (offsetY > 64) {
        if (panTranslationY > 0) { //下滑趨勢,顯示
            [self.navigationController setNavigationBarHidden:NO animated:YES];
        }
        else {  //上滑趨勢,隱藏
            [self.navigationController setNavigationBarHidden:YES animated:YES];
        }
    }
    else {
        [self.navigationController setNavigationBarHidden:NO animated:YES];
    }
}

33、設(shè)置應(yīng)用內(nèi)的系統(tǒng)控件語言

有時候我們用系統(tǒng)的播放器的時候,完成的done這個按鈕顯得格外礙眼,怎么變成漢字呢?就用這個方法,在info.plist文件中添加下列內(nèi)容
<key>CFBundleLocalizations</key>
    <array>
        <string>zh_CN</string>
        <string>en</string>
    </array>

34、獲取開屏LaunchScreen對象

在給App加入開屏廣告時,發(fā)現(xiàn)LaunchScreen和開屏廣告銜接處需要通過一張截圖來過渡. 但是不同尺寸的屏幕上得放不同截圖,可以直接用LaunchScreen 作為截圖

//拿到LaunchScreen.StoryBoard并生成一個控制器
UIViewController *stvc = [[UIStoryboard storyboardWithName:@"LaunchScreen" bundle:[NSBundle mainBundle]] instantiateInitialViewController];

//通過控制器的.view生成imgae截圖
CGRect rect = stvc.view.bounds;
UIGraphicsBeginImageContextWithOptions(rect.size, YES, 0.0f);
CGContextRef context = UIGraphicsGetCurrentContext();
[view.layer renderInContext:context];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

//之后拿到了image就可以用作開屏廣告前的截圖了,比如騰訊廣告中就會用到
[TXAD configOpenScreenAD:image fullImg:image placementId:TAD_OpenScreenPlaceId];

35、設(shè)置UIView的某幾個角為圓角

UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(200, 200, 80, 80)];
    view2.backgroundColor = [UIColor redColor];
    [self.view addSubview:view2];
    //UIRectCornerBottomLeft -> 左下角 依此類推。
    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;

36、獲得UIButton的當前狀態(tài)

//UIButton有很多種狀態(tài),它提供了一些便捷屬性,可以直接獲取當前狀態(tài)下的文字、文字顏色、圖片等
@property(nullable, nonatomic,readonly,strong) NSString *currentTitle; 
@property(nonatomic,readonly,strong) UIColor  *currentTitleColor;        
@property(nullable, nonatomic,readonly,strong) UIColor  *currentTitleShadowColor;             
@property(nullable, nonatomic,readonly,strong) UIImage  *currentImage;
@property(nullable, nonatomic,readonly,strong) UIImage  *currentBackgroundImage;
@property(nullable, nonatomic,readonly,strong) NSAttributedString *currentAttributedTitle NS_AVAILABLE_IOS(6_0);
你也可以獲取不是當前狀態(tài)的標題、顏色和背景圖片
- (nullable NSString *)titleForState:(UIControlState)state;          // these getters only take a single state value
- (nullable UIColor *)titleColorForState:(UIControlState)state;
- (nullable UIColor *)titleShadowColorForState:(UIControlState)state;
- (nullable UIImage *)imageForState:(UIControlState)state;
- (nullable UIImage *)backgroundImageForState:(UIControlState)state;
- (nullable NSAttributedString *)attributedTitleForState:(UIControlState)state NS_AVAILABLE_IOS(6_0);

37、導(dǎo)航欄的返回按鈕只保留那個箭頭,去掉后邊的文字

[[UIBarButtonItem appearance]setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60) forBarMetrics:UIBarMetricsDefault];

38、有時候當我們在工程中導(dǎo)入第三方的庫之后,可能會遇到''The file “XXX.app” couldn’t be opened because you don’t have permission to view it.''的情況,其原因為:info文件中的字段Executable file 與 build settings欄中的Packaging中的Product Name 不一致.解決方法是

將info.plist的文件中的Executable.file中的文件修改為:$(PRODUCT_NAME)

39、將手勢穿透到下一個視圖

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];
    [[self nextResponder] touchesBegan:touches withEvent:event];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesMoved:touches withEvent:event];
    [[self nextResponder] touchesMoved:touches withEvent:event];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesEnded:touches withEvent:event];
    [[self nextResponder] touchesEnded:touches withEvent:event];

}
- (void)touchesCancelled:(NSSet *)touches withEvent:(nullable UIEvent *)event
{
    [super touchesCancelled:touches withEvent:event];
    [[self nextResponder]touchesCancelled:touches withEvent:event];
}
40、跳轉(zhuǎn)到各種系統(tǒng)的設(shè)置界面.
例如:@"無線局域網(wǎng)",@"藍牙",@"個人熱點",@"運營商",@"通知",@"睡眠",@"通用",@"調(diào)節(jié)亮度",@"墻紙",@"聲音",@"siri語音助手",@"隱私",@"電話",@"icloud",@"iTunes Strore 與 APP Store",@"safari",@"關(guān)于本機",@"軟件更新",@"輔助功能",@"日期與時間",@"鍵盤",@"存儲空間",@"語言與地區(qū)",@"VPN",@"描述文件與設(shè)備管理",@"音樂",@"備忘錄",@"照片與相機",@"還原",@"Twiter",@"Facebook"
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"App-Prefs:root=Bluetooth"]];
/*
     case 0://無線局域網(wǎng)
     jump(url: "App-prefs:root=WIFI")
     case 1: //藍牙
     jump(url: "App-Prefs:root=Bluetooth")
     case 2: //個人熱點
     jump(url: "App-prefs:root=INTERNET_TETHERING")
     case 3: //運營商
     jump(url: "App-prefs:root=Carrier")
     case 4: //通知:需要大寫后面加上ID
     jump(url: "App-prefs:root=NOTIFICATIONS_ID")
     case 5: //睡眠
     jump(url: "App-prefs:root=DO_NOT_DISTURB")
     case 6: //通用
     jump(url: "App-prefs:root=General")
     case 7: //調(diào)節(jié)亮度
     jump(url: "App-prefs:root=DISPLAY&BRIGHTNESS")
     case 8://墻紙
     jump(url: "App-prefs:root=Wallpaper")
     case 9://聲音
     jump(url: "App-prefs:root=Sounds")
     case 10://siri語音助手
     jump(url: "App-prefs:root=SIRI")
     case 11://隱私
     jump(url: "App-prefs:root=Privacy")
     case 12: //電話
     jump(url: "App-prefs:root=Phone")
     case 13:  //icloud
     jump(url: "App-prefs:root=CASTLE")
     case 14://iTunes Strore 與 APP Store
     jump(url: "App-prefs:root=STORE")
     case 15://safari
     jump(url: "App-prefs:root=SAFARI")
     case 16: //關(guān)于本機
     jump(url: "App-prefs:root=General&path=About")
     case 17://軟件更新
     jump(url: "App-prefs:root=General&path=SOFTWARE_UPDATE_LINK")
     case 18: //輔助功能
     jump(url: "App-prefs:root=General&path=ACCESSIBILITY")
     case 19: //日期與時間
     jump(url: "App-prefs:root=General&path=DATE_AND_TIME")
     case 20: //鍵盤
     jump(url: "App-prefs:root=General&path=Keyboard")
     case 21://存儲空間
     jump(url: "App-prefs:root=CASTLE&path=STORAGE_AND_BACKUP")
     case 22: //語言與地區(qū)
     jump(url: "App-prefs:root=General&path=Language_AND_Region")
     case 23://VPN
     jump(url: "App-prefs:root=General&path=VPN")
     case 24://描述文件與設(shè)備管理
     jump(url: "App-prefs:root=General&path=ManagedConfigurationList")
     case 25://音樂
     jump(url: "App-prefs:root=MUSIC")
     case 26://備忘錄
     jump(url: "App-prefs:root=NOTES")
     case 27: //照片與相機
     jump(url: "App-prefs:root=Photos")
     case 28://還原
     jump(url: "App-prefs:root=General&path=Reset")
     case 29: //Twiter
     jump(url: "App-prefs:root=TWITTER")
     case 30: //Facebook
     jump(url: "App-prefs:root=FACEBOOK")
     */
41、計算幾個月后的今天
//計算幾個月后的今天
    NSDate *date = [NSDate date];
    date = [self dateAfterMonths:date gapMonth:2];
    NSLog(@"??%@",date);
//
- (NSDate *)dateAfterMonths:(NSDate *)currentDate gapMonth:(NSInteger)gapMonthCount {
    //獲取當年的月份,當月的總天數(shù)
    NSCalendar *calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *components = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitCalendar fromDate:currentDate];
    
    NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
    [formatter setDateStyle:NSDateFormatterFullStyle];
    [formatter setDateFormat:@"yyyy-MM-dd"];
    [formatter setTimeZone:[NSTimeZone localTimeZone]];
    [formatter setTimeZone:[NSTimeZone timeZoneWithName:@"Asia/Shanghai"]];
    
    
    NSString *dateStr = @"";
    NSInteger endDay = 0;//天
    NSDate *newDate = [NSDate date];//新的年&月
    //判斷是否是下一年
    if (components.month+gapMonthCount > 12) {
        //是下一年
        dateStr = [NSString stringWithFormat:@"%zd-%zd-01",components.year+(components.month+gapMonthCount)/12,(components.month+gapMonthCount)%12];
        newDate = [formatter dateFromString:dateStr];
        //新月份的天數(shù)
        NSInteger newDays = [calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:newDate].length;
        if ([self isEndOfTheMonth:currentDate]) {//當前日期處于月末
            endDay = newDays;
        } else {
            endDay = newDays < components.day?newDays:components.day;
        }
        dateStr = [NSString stringWithFormat:@"%zd-%zd-%zd",components.year+(components.month+gapMonthCount)/12,(components.month+gapMonthCount)%12,endDay];
    } else {
        //依然是當前年份
        dateStr = [NSString stringWithFormat:@"%zd-%zd-01",components.year,components.month+gapMonthCount];
        newDate = [formatter dateFromString:dateStr];
        //新月份的天數(shù)
        NSInteger newDays = [calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:newDate].length;
        if ([self isEndOfTheMonth:currentDate]) {//當前日期處于月末
            endDay = newDays;
        } else {
            endDay = newDays < components.day?newDays:components.day;
        }
        
        dateStr = [NSString stringWithFormat:@"%zd-%zd-%zd",components.year,components.month+gapMonthCount,endDay];
    }
    
    newDate = [formatter dateFromString:dateStr];
    return newDate;
}

//判斷是否是月末
- (BOOL)isEndOfTheMonth:(NSDate *)date {
    NSCalendar *calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
    NSInteger daysInMonth = [calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date].length;
    NSDateComponents *componets = [calendar components:NSCalendarUnitDay fromDate:date];
    if (componets.day >= daysInMonth) {
        return YES;
    }
    return NO;
}

42、篩選掉文本中所有的非數(shù)字
- (void)textDidChanged: (UITextField *)textField{
    NSMutableString * modifyText = textField.text.mutableCopy;
    for (NSInteger idx = 0; idx < modifyText.length; idx++) {
        NSString * subString = [modifyText substringWithRange: NSMakeRange(idx, 1)];
        // 使用正則表達式篩選
        NSString * matchExp = @"^\\d$";
        NSPredicate * predicate = [NSPredicate predicateWithFormat: @"SELF MATCHES %@", matchExp];
        if ([predicate evaluateWithObject: subString]) {
            idx++;
        } else {
            [modifyString deleteCharactersInRange: NSMakeRange(idx, 1)];
        }
    }
}
43、為textView添加placeholderLabel
UILabel *placeHolderLabel = [[UILabel alloc] init];
    placeHolderLabel.text = @"在此輸入您要反饋的內(nèi)容哦~";
    placeHolderLabel.numberOfLines = 0;
    placeHolderLabel.textColor = [UIColor lightGrayColor];
    [placeHolderLabel sizeToFit];
    [self.textView addSubview:placeHolderLabel];//這句很重要不要忘了
    self.textView.font = [UIFont systemFontOfSize:20.f];
    placeHolderLabel.font = [UIFont systemFontOfSize:20.f];
    //KVC
    [self.textView setValue:placeHolderLabel forKey:@"_placeholderLabel"];
44、占位
45、TextView的字數(shù)限制
#define MaxNumberOfDescriptionChars  150

-(void)textViewEditChanged:(NSNotification *)obj{
    UITextView *textView = (UITextView *)obj.object;
    NSString *toBeString = textView.text;
    NSString *lang = [[UITextInputMode currentInputMode] primaryLanguage]; // 鍵盤輸入模式
    if ([lang isEqualToString:@"zh-Hans"]) { // 簡體中文輸入,包括簡體拼音,健體五筆,簡體手寫
        UITextRange *selectedRange = [textView markedTextRange];
        //獲取高亮部分
        UITextPosition *position = [textView positionFromPosition:selectedRange.start offset:0];
        // 沒有高亮選擇的字,則對已輸入的文字進行字數(shù)統(tǒng)計和限制
        if (!position) {
            if (toBeString.length > MaxNumberOfDescriptionChars) {
                textView.text = [toBeString substringToIndex:MaxNumberOfDescriptionChars];
            }
        }
        // 有高亮選擇的字符串,則暫不對文字進行統(tǒng)計和限制
        else{
        }
    }
    // 中文輸入法以外的直接對其統(tǒng)計限制即可,不考慮其他語種情況
    else{
        if (toBeString.length > MaxNumberOfDescriptionChars) {
            
            textView.text = [toBeString substringToIndex:MaxNumberOfDescriptionChars];
        }
    }
}

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
    NSString *new = [textView.text stringByReplacingCharactersInRange:range withString:text];
    self.numLabel.text = [NSString stringWithFormat:@"%zd字",(MaxNumberOfDescriptionChars - new.length)];
    if(new.length > MaxNumberOfDescriptionChars){
         self.numLabel.text = [NSString stringWithFormat:@"%zd字",0];
        if (![text isEqualToString:@""]) {
            return NO;
        }
    }
    return YES;
}
46、占位
47、Swift中 Log輸出
func printLog<T>(_ message: T, file: String = #file, method: String = #function, line:Int = #line) {
    #if DEBUG
    print("\((file as NSString).lastPathComponent)[\(line)], \(method): \(message)")
    #endif
}
48、將HTML字符串轉(zhuǎn)化為NSAttributedString富文本字符串
- (NSAttributedString *)attributedStringWithHTMLString:(NSString *)htmlString
{
    NSDictionary *options = @{ NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType,
                               NSCharacterEncodingDocumentAttribute :@(NSUTF8StringEncoding) };
   
    NSData *data = [htmlString dataUsingEncoding:NSUTF8StringEncoding];
   
    return [[NSAttributedString alloc] initWithData:data options:options documentAttributes:nil error:nil];
}
49、CABasicAnimation(CAKeyframeAnimation)key path 取值

keyPath可以使用的key

- define angle2Radian(angle) ((angle)/180.0*M_PI)

transform.rotation.x 圍繞x軸翻轉(zhuǎn) 參數(shù):角度 angle2Radian(4)

transform.rotation.y 圍繞y軸翻轉(zhuǎn) 參數(shù):同上

transform.rotation.z 圍繞z軸翻轉(zhuǎn) 參數(shù):同上

transform.rotation 默認圍繞z軸

transform.scale.x x方向縮放 參數(shù):縮放比例 1.5

transform.scale.y y方向縮放 參數(shù):同上

transform.scale.z z方向縮放 參數(shù):同上

transform.scale 所有方向縮放 參數(shù):同上

transform.translation.x x方向移動 參數(shù):x軸上的坐標 100

transform.translation.y x方向移動 參數(shù):y軸上的坐標

transform.translation.z x方向移動 參數(shù):z軸上的坐標

transform.translation 移動 參數(shù):移動到的點 (100,100)

opacity 透明度 參數(shù):透明度 0.5

backgroundColor 背景顏色 參數(shù):顏色 (id)[[UIColor redColor] CGColor]

cornerRadius 圓角 參數(shù):圓角半徑 5

borderWidth 邊框?qū)挾?參數(shù):邊框?qū)挾?5

bounds 大小 參數(shù):CGRect

contents 內(nèi)容 參數(shù):CGImage

contentsRect 可視內(nèi)容 參數(shù):CGRect 值是0~1之間的小數(shù)

hidden 是否隱藏

position

shadowColor

shadowOffset

shadowOpacity

shadowRadius
50、將項目中的PCH文件路徑轉(zhuǎn)化為相對路徑,格式如下
$(PRODUCT_NAME)/PrefixHeader.pch
或者
$(SRCROOT)/項目名/PrefixHeader.pch
51、截屏
-(void)ScreenShot{

    CGSize imageSize = [[UIScreen mainScreen] bounds].size;

    if (NULL != &UIGraphicsBeginImageContextWithOptions) {
        UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
    }

    CGContextRef context = UIGraphicsGetCurrentContext();

    for (UIWindow * window in [[UIApplication sharedApplication] windows]) {
        if (![window respondsToSelector:@selector(screen)] || [window screen] == [UIScreen mainScreen]) {
            CGContextSaveGState(context);
            CGContextTranslateCTM(context, [window center].x, [window center].y);
            CGContextConcatCTM(context, [window transform]);
            CGContextTranslateCTM(context, -[window bounds].size.width*[[window layer] anchorPoint].x, -[window bounds].size.height*[[window layer] anchorPoint].y);
            [[window layer] renderInContext:context];

            CGContextRestoreGState(context);
        }
    }

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

//    UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);//保存圖片到照片庫
    NSData *imageViewData = UIImagePNGRepresentation(image);

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];

    NSString *pictureName= [NSString stringWithFormat:@"screenShow_%d.png",3];
    NSString *savedImagePath = [documentsDirectory stringByAppendingPathComponent:pictureName];

    NSLog(@"截屏路徑打印: %@", savedImagePath);
    //保存照片到沙盒目錄
    //CGImageRelease(imageRefRect);
    [imageViewData writeToFile:savedImagePath atomically:YES];
    NSLog(@"截屏成功!");
}
52、占位
53、NSDictionaryOfVariableBindings這個宏生成一個字典,這個宏可以生成一個變量名到變量值映射的Dictionary,以后字典可以這樣寫:
NSNumber * packId=@(2);
NSNumber *userId=@(22);
NSNumber *proxyType=@(2);
NSDictionary *param=NSDictionaryOfVariableBindings(packId,userId,proxyType);
54、長按web上面的圖片進行保存
首先遵守UIGestureRecognizerDelegate和NSURLSessionDelegate協(xié)議
//在viewDidLoad給UIWebView添加手勢
    UILongPressGestureRecognizer* longPressed = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressed:)];
    longPressed.delegate = self;
    [self.webView addGestureRecognizer:longPressed];

實現(xiàn)以下方法

#pragma mark -- UIGestureRecognizerDelegate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
    return YES;
}

- (void)longPressed:(UILongPressGestureRecognizer*)recognizer{
    if (recognizer.state != UIGestureRecognizerStateBegan) {
        return;
    }
    CGPoint touchPoint = [recognizer locationInView:self.webView];
    NSString *imgURL = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).src", touchPoint.x, touchPoint.y];
    NSString *urlToSave = [self.webView stringByEvaluatingJavaScriptFromString:imgURL];
    if (urlToSave.length == 0) {
        return;
    }
    
    UIAlertController *alertVC =  [UIAlertController alertControllerWithTitle:@"大寶貝兒" message:@"你真的要保存圖片到相冊嗎?" preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"真的啊" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        [self saveImageToDiskWithUrl:urlToSave];
    }];
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"大哥,我點錯了,不好意思" style:UIAlertActionStyleDefault handler:nil];
    [alertVC addAction:okAction];
    [alertVC addAction:cancelAction];
    [self presentViewController:alertVC animated:YES completion:nil];
}

#pragma mark - private method
- (void)saveImageToDiskWithUrl:(NSString *)imageUrl{
    NSURL *url = [NSURL URLWithString:imageUrl];
    
    NSURLSessionConfiguration * configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    
    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:[NSOperationQueue new]];
    
    NSURLRequest *imgRequest = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:30.0];
    
    NSURLSessionDownloadTask  *task = [session downloadTaskWithRequest:imgRequest completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
            return ;
        }
        NSData * imageData = [NSData dataWithContentsOfURL:location];
        dispatch_async(dispatch_get_main_queue(), ^{
            
            UIImage * image = [UIImage imageWithData:imageData];
            UIImageWriteToSavedPhotosAlbum(image, self, @selector(imageSavedToPhotosAlbum:didFinishSavingWithError:contextInfo:), NULL);
        });
    }];
    [task resume];
}

#pragma mark 保存圖片后的回調(diào)
- (void)imageSavedToPhotosAlbum:(UIImage*)image didFinishSavingWithError:  (NSError*)error contextInfo:(id)contextInfo{
    NSString*message =@"嘿嘿";
    if(!error) {
        UIAlertController *alertControl = [UIAlertController alertControllerWithTitle:@"提示" message:@"成功保存到相冊" preferredStyle:UIAlertControllerStyleAlert];
        
        UIAlertAction *action = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDestructive handler:nil];
        [alertControl addAction:action];
        [self presentViewController:alertControl animated:YES completion:nil];
    }else{
        message = [error description];
        UIAlertController *alertControl = [UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *action = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleCancel handler:nil];
        [alertControl addAction:action];
        [self presentViewController:alertControl animated:YES completion:nil];
    }
}
55、簡易網(wǎng)頁控制器,可替代webview
首先導(dǎo)入頭文件#import <SafariServices/SafariServices.h>
遵守代理協(xié)議<SFSafariViewControllerDelegate>
SFSafariViewController *safari = [[SFSafariViewController alloc] initWithURL:[NSURL URLWithString:@"http://www.itdecent.cn/subscriptions#/timeline"]];
safari.delegate = self;
[self.navigationController pushViewController:safari animated:YES];
56、多種系統(tǒng)字體
for (NSString * family in [UIFont familyNames]) {
        NSLog(@"familyNames:%@", family);
        for (NSString * name in [UIFont fontNamesForFamilyName:family]) {
            NSLog(@"  name: %@",name);
        }
}

57、禁止單個頁面的屏幕滑動返回

-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    // 禁用返回手勢
    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]){
            self.navigationController.interactivePopGestureRecognizer.enabled = NO;
        }
}
- (void)viewWillDisappear:(BOOL)animated{
     [super viewWillDisappear:animated];
     if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]){
           self.navigationController.interactivePopGestureRecognizer.enabled = YES;
        }
}
58、占位
59、關(guān)于使用cocoaPods,import導(dǎo)入時第三方庫頭文件沒有提示問題的解決辦法
選擇target(就是左邊你的工程target)—— BuildSettings 
—— search Paths 下的 User Header Search Paths
雙擊后面的空白區(qū)域:點擊“+”號添加一項:并且輸入:“$(PODS_ROOT)”(沒有引號),
選擇:recursive(會在相應(yīng)的目錄遞歸搜索文件)
60、當系統(tǒng)版本大于10.3時,可以用系統(tǒng)的評分系統(tǒng)
#import <StoreKit/StoreKit.h>
[SKStoreReviewController requestReview];
61、數(shù)組的快速枚舉 (注意:快速枚舉里面不能對數(shù)組或字典進行任何修改,但是普通for循環(huán)可以)
[arr enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
 }];
[self.view.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [obj removeFromSuperview];
}];
[self.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [obj removeFromSuperview];
}];
[self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
62、push和present方法調(diào)用先后順序
push
1、調(diào)用 A 的 viewWillDisappear 方法,
2、調(diào)用 B 的 viewWillAppear 方法
3、調(diào)用 A 的 viewDidDisappear 方法
4、調(diào)用 B 的 viewDidAppear 方法

present
1、調(diào)用 A 的 viewWillDisappear 方法,
2、調(diào)用 C 的 viewWillAppear 方法
3、調(diào)用 C 的 viewDidAppear 方法
4、調(diào)用 A 的 viewDidDisappear 方法
63、占位
64、如果控制器已經(jīng)加載過,就不用再次加載,優(yōu)化性能
if (self.viewLoaded) return;
65、NS_REQUIRES_SUPER用法
場景需求:在繼承中,凡是要求子類重寫父類的方法必須先調(diào)用父類的這個方法進行初始化操作;建議:父類的方法名后面加上NS_REQUIRES_SUPER; 子類重寫這個方法就會自動警告提示要調(diào)用這個super方法,示例代碼
// 注意:父類中的方法加`NS_REQUIRES_SUPER`,子類重寫才有警告提示
- (void)prepare NS_REQUIRES_SUPER;
66、忽略警告
忽略未使用的變量
#pragma clang diagnostic push
#pragma clang diagnostic ignored "警告標識符"
//在這里寫沒有用到的聲明
#pragma clang diagnostic pop

忽略所有警告
在 Build Settings 中找到 Custom Compiler Flags,雙擊 Other Warning Flags(可以配置 Debug 和 Release 環(huán)境),填入 -Wno-unused-variable,完成后,編譯項目,項目中所有的此類型警告都沒有了。這里所填寫的內(nèi)容規(guī)則,僅僅是在第一種方法中找到的警告標識符中的 W 字母后面加上no- 就可以了。

CocoaPods 導(dǎo)入第三方庫忽略警告
通過 CocoaPods 給項目導(dǎo)入了一些第三方庫,這些庫里面或多或少會有些警告,想消除這些警告,很簡單,只需在 Podfile 中加上這一句 inhibit_all_warnings!,所有通過 CocoaPods 安裝的第三庫的警告就沒有了。
67、獲取所有的私有權(quán)限
Privacy - Media Library Usage Description 使用媒體資源庫
 Privacy - Calendars Usage Description 使用日歷
 Privacy - Motion Usage Description 使用藍牙
 Privacy - Camera Usage Description --->App需要您的同意,才能訪問運動與健身(運動使用)
 Privacy - Health Update Usage Description 使用健康更新
 Privacy - Microphone Usage Description 使用麥克風(fēng)
 Privacy - Bluetooth Peripheral Usage Description --->App需要您的同意,才能訪問藍牙
 Privacy - Health Share Usage Description 使用健康分享
 Privacy - Reminders Usage Description 使用提醒事項
 Privacy - Location Usage Description 使用位置
 Privacy - Location Always Usage Description 始終訪問位置
 Privacy - Photo Library Usage Description 訪問相冊
 Privacy - Speech Recognition Usage Description 使用語音識別
 Privacy - Location When In Use Usage Description 使用期間訪問位置
Privacy - HomeKit Usage Description 溝通和控制家庭自動化配件
Privacy - Contacts Usage Description   --> 通訊錄權(quán)限
Privacy - NSSiriUsageDescription --> Siri的權(quán)限
Privacy - Music Usage Description --> 音樂
Privacy - TV Provider Usage Description --> 電視供應(yīng)商使用權(quán)限
Privacy - Video Subscriber Account Usage Description --> 視頻用戶賬號使用權(quán)限
68、占位
69、刪除導(dǎo)航控制器棧中的某個控制器
//使用情況:假如控制器Apush到控制器B再push到控制器C,然后手勢直接從控制器C返回到控制器A,這就需要從棧中移除掉控制器B

//得到當前視圖控制器中的所有控制器 
NSMutableArray *array = [self.navigationController.viewControllers mutableCopy];
//把B從里面刪除 
[array removeObjectAtIndex:1]; 
//把刪除后的控制器數(shù)組再次賦值
[self.navigationController setViewControllers:[array copy] animated:YES];
70、和區(qū)域 點 尺寸相關(guān)
if (CGRectEqualToRect(rect1, rect2)) { 
    // 兩個區(qū)域相等 
} 
if (CGPointEqualToPoint(point1, point2)) {
     // 兩個點相等
} 
if (CGSizeEqualToSize(size1, size2)) {
     // 兩個size相等 
}
if (CGRectIntersectsRect(rect1, rect2)) {
    //兩個rect是否有交叉
}
if(CGRectContainsRect(rect1, rect2)){
    //rect1包含rect2
}
if(CGRectContainsPoint(rect, point)){
    //rect的范圍包含點point
}
if(CGRectIsEmpty(rect)){
    //rect的寬和高為0
}
CGRectGetHeight(rect)//返回rect的高度
CGRectGetWidth(rect)//返回rect的寬度
CGRectGetMaxY(rect)//返回rect最底端的y值
CGRectGetMinY(rect);//返回rect最頂端的y值
CGRectGetMaxX(rect)//返回rect最右端的x值
CGRectGetMinX(rect);//返回rect最左端的x值
CGRectGetMidY(rect)//返回rect中心點的y值
CGRectGetMidX(rect)//返回rect中心點的x值
71、UIView 及其子類的切圓角時,要保證避免出現(xiàn)離屏渲染。
UIView(不包括其子類)
view.layer.cornerRadius = 3.f;
// 以下兩行,任寫一行
view.layer.masksToBounds = NO;
view.clipToBounds = NO;
// 以下兩行,千萬不要加!
view.layer.masksToBounds = YES;
view.clipToBounds = YES;
//UIView 只要設(shè)置圖層的 cornerRadius 屬性即可,如果設(shè)置 layer.masksToBounds = YES,會造成不必要的離屏渲染。

UITextField(兩種實現(xiàn)方法)
// 天然支持設(shè)置圓角邊框
textField.borderStyle = UITextBorderStyleRoundedRect;
// 與 UIView 類似
textField.layer.cornerRadius = cornerRadius;

UITextView(與 UIView 類似)
textView.layer.cornerRadius = cornerRadius;

UILabel
// 重點在此??!設(shè)置視圖的圖層背景色,千萬不要直接設(shè)置 label.backgroundColor
label.layer.backgroundColor = [UIColor grayColor].CGColor;
label.layer.cornerRadius = cornerRadius;

UIButton(背景圖片繪制方法)
+ (UIImage *)pureColorImageWithSize:(CGSize)size color:(UIColor *)color cornRadius:(CGFloat)cornRadius {

  UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, size.width, size.height)];
  view.backgroundColor = color;
  view.layer.cornerRadius = cornerRadius;
  // 下面方法,第一個參數(shù)表示區(qū)域大小。第二個參數(shù)表示是否是非透明的。如果需要顯示半透明效果,需要傳NO,否則傳YES。第三個參數(shù)是屏幕密度
  UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, [UIScreen mainScreen].scale);
  [view.layer renderInContext:UIGraphicsGetCurrentContext()];
  UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();

  return image;
}

UIImageView
* 貝塞爾曲線切割圓角
- (UIImageView *)roundedRectImageViewWithCornerRadius:(CGFloat)cornerRadius {

    UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:cornerRadius];
    CAShapeLayer *layer = [CAShapeLayer layer];
    layer.path = bezierPath.CGPath;
    self.layer.mask = layer;
    return self;
}
72、放置多行間距相同的UILabel
//總數(shù)
    int sumCount = 10;
    //每一行的數(shù)
    int Count = 4;
    CGFloat width = (self.view.frame.size.width- 100)/Count;
    
    for (int i = 0; i < sumCount; i++) {
        
        CGFloat y = 300 + i / Count * 50;
        int loc = i % Count;
        CGFloat x = 20 + (20 + width) * loc;
        
        UILabel *lab = [[UILabel alloc]initWithFrame:CGRectMake(x, y , width, 30)];
        lab.textAlignment = NSTextAlignmentCenter;
        lab.text = [NSString stringWithFormat:@"%d",i];
        lab.layer.borderColor = [UIColor redColor].CGColor;
        lab.layer.borderWidth = 1;
        lab.layer.masksToBounds = YES;
        lab.layer.cornerRadius = 10;
        [self.view addSubview:lab];
}

還有一種方式,兩個 for 循環(huán)嵌套

for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        UIButton * btn = [UIButton buttonWithType:UIButtonTypeCustom];
        btn.backgroundColor = [UIColor groupTableViewBackgroundColor];
        [btn setTitle:[NSString stringWithFormat:@"%d", i + (3 * j) + 1] forState:UIControlStateNormal];
        [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        btn.tag = (i + (3 * j) + 1) + 100;
        btn.frame = CGRectMake(20 + i * 120, 20 + j * 70, 100, 50);
        [self.view addSubview:btn];
    }
}
73、同時重寫了get和set方法會怎么樣
同時重寫了get和set方法之后@property默認生成的@synthesize就不會起作用了
這也就意味著你的類不會自動生成出來實例變量了
你就必須要自己聲明實例變量 
@interface ViewContaoller{ Nsstring *_name }
74、占位
75、設(shè)置動畫和過渡期間應(yīng)設(shè)置忽略觸摸和其他活動(屏蔽 觸發(fā)事件)
//開始屏蔽
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
//結(jié)束屏蔽
[[UIApplication sharedApplication] endIgnoringInteractionEvents];
76、關(guān)于指針
a)    一個整型                         int a;
b)    一個指向整型數(shù)的指針                        int *a;
c)    一個指向指針的的指針,它指向的指針是指向一個整型數(shù)             int **a;
d)    一個有10 個整型數(shù)的數(shù)組                         int a[10];
e)    一個有10 個指針的數(shù)組,該指針是指向一個整型數(shù)的                 int *a[10];
f)    一個指向有10 個整型數(shù)數(shù)組的指針                                 int (*a)[10];
g)    一個指向函數(shù)的指針,該函數(shù)有一個整型參數(shù)并返回一個整型數(shù)                 int (*a)(int);
h)    一個有10 個指針的數(shù)組,該指針指向一個函數(shù),該函數(shù)有一個整型參數(shù)并返回一個整型數(shù)          int (*a[10])(int);
區(qū)別
int a = 15;
    //*p 表示獲取地址上的數(shù)據(jù)
    int *p = &a;
    printf("%d--%d",a,*p);
    //a需要一次運算就能取得數(shù)據(jù),而*p需要經(jīng)過兩次運算,多了一層間接.
    //使用*p要先通過地址獲取p本身的值,這個值是變量a的地址,在通過這個地址獲取a的數(shù)據(jù),但是使用a的話可以直接使用地址獲取到數(shù)據(jù)
    //使用指針是間接獲取數(shù)據(jù),使用變量名是直接獲取數(shù)據(jù),前者比后者的代價更高
77、void * 的作用
//    void * a = "hello";
//    void * b = 2;
//    void * c = false;
由此得出void * 和id功能相同,表示萬能指針
78、空
nil  表示對象為空   
Nil表示類為空    
NULL是C語言的,表示一個值為空   
NSNotFound表示一個整數(shù)不存在,其實表示一個整數(shù)的最大值(NSIntegerMax)
79、占位
80、系統(tǒng)約束
[self.view addSubview:self.myTest1];
    self.myTest1.translatesAutoresizingMaskIntoConstraints = NO;
    //距離父視圖上下左右個50,
    [self.myTest1.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:50].active = YES;
    [self.myTest1.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-50].active = YES;
    [self.myTest1.topAnchor constraintEqualToAnchor:self.view.topAnchor constant:50].active = YES;
    [self.myTest1.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor constant:-50].active = YES;
    //[self.myTest1.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor].active = YES;
    //[self.myTest1.heightAnchor constraintEqualToConstant:45].active = YES;
    //[self.myTest1.topAnchor constraintEqualToAnchor:self.view.topAnchor].active = YES;
    //[self.myTest1.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor].active = YES;
81、占位
82、frame和bounds區(qū)別
frame:決定一個視圖在它父視圖上的顯示區(qū)域和大小,以父視圖左上角為原點(0,0).
bounds:以自己左上角為原點(0,0),并可以設(shè)置自身尺寸大小,決定了本地坐標系統(tǒng)的位置和大小.
bounds的有以下兩個特點:
1. 它可以修改自己坐標系的原點位置,影響“子view”的顯示位置。
2. 它可以通過改變寬高,改變自身的frame,進而影響到在父視圖的顯示位置和大小。
子視圖的frame = 父視圖的bounds的意義是子視圖充滿父視圖.
83、視頻播放器
//導(dǎo)入框架
#import <AVFoundation/AVFoundation.h>
#import <AVKit/AVKit.h>

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
AVPlayerViewController *vc = [AVPlayerViewController new];
AVPlayer *player = [AVPlayer playerWithURL:[NSURL URLWithString:@""]];
    vc.player = player;
    [self presentViewController:vc animated:YES completion:nil];
    [vc.player play];
84、UIViewContentMode類型
UIViewContentModeScaleAspectFit, //這個圖片都會在view里面顯示,并且比例不變 這就是說 如果圖片和view的比例不一樣 就會有留白;
UIViewContentModeScaleAspectFill, // 這是整個view會被圖片填滿,圖片比例不變 ,這樣圖片顯示就會大于view;
UIViewContentModeRedraw這個選項是單視圖的尺寸位置發(fā)生變化的時候通過調(diào)用setNeedsDisplay方法來重新顯示。
UIViewContentModeCenter保持圖片原比例在視圖中間顯示圖片內(nèi)容,如果視圖大小小于圖片的尺寸,則圖片會超出視圖邊界
UIViewContentModeTop保持圖片原比例在視圖中間頂部顯示圖片內(nèi)容
UIViewContentModeBottom保持圖片原比例在視圖中間底部顯示圖片內(nèi)容
UIViewContentModeLeft保持圖片原比例在視圖中間左邊顯示圖片內(nèi)容
UIViewContentModeRight保持圖片原比例在視圖中間右邊顯示圖片內(nèi)容
UIViewContentModeTopLeft保持圖片原比例在視圖左上角顯示圖片內(nèi)容
UIViewContentModeTopRight保持圖片原比例在視圖右上角顯示圖片內(nèi)容
UIViewContentModeBottomLeft保持圖片原比例在視圖左下角顯示圖片內(nèi)容
UIViewContentModeBottomRight保持圖片原比例在視圖右下角顯示圖片內(nèi)容
85、在低版本Xcode上運行高版本的iOS真機設(shè)備
真機運行的支持包的位置位于:Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport
找到該文件后會看到很多支持真機運行的支持包,每個文件夾都是對應(yīng)的iPhone系統(tǒng)。將從別人那里獲取的支持包放到該文件路徑下即可
86、輸入框三種方式檢測輸入內(nèi)容變化
1>通過UIControl
[textfield addTarget:self action:@selector(textChange:) forControlEvents:UIControlEventEditingChanged];
2>通過代理方法
textfield.delegate = self;
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
3>通過通知
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(AAAAAA) name:UITextFieldTextDidChangeNotification object:nil];
87、占位
88、占位
89、漢字轉(zhuǎn)拼音
- (NSString *)firstCharactor:(NSString *)aString
{
    //轉(zhuǎn)成了可變字符串
    NSMutableString *str = [NSMutableString stringWithString:aString];
    //先轉(zhuǎn)換為帶聲調(diào)的拼音
    CFStringTransform((CFMutableStringRef)str,NULL, kCFStringTransformMandarinLatin,NO);
    //再轉(zhuǎn)換為不帶聲調(diào)的拼音
    CFStringTransform((CFMutableStringRef)str,NULL, kCFStringTransformStripDiacritics,NO);
    //轉(zhuǎn)化為大寫拼音
    NSString *pinYin = [str capitalizedString];
    //獲取并返回首字母
    return [pinYin substringToIndex:1];
}
90、常用的LLDB命令
help 列出所有命令
help <commond>列出某個命令更多細節(jié),例如help print
print打印需要查看的變量,例如print number,簡寫為p,當后面是對象時則打印對象的地址.
po(print object)可以打印對象的description方法的結(jié)果,例如po array
expression可以改變一個值(動態(tài)改變執(zhí)行內(nèi)容),簡寫e
thread backtrace:作用是將線程的堆棧打印出來,簡寫為bt,加all可打印所有thread的堆棧
call   在調(diào)試器中直接更新UI(只在不需要顯示輸出,或是方法無返回值時使用call),例如call view.backgroundColor = UIColor.blue
n 斷點指針執(zhí)行到下一步
exit/quit    推出調(diào)試器
91、一種新的封裝方式
//num 為最后一個數(shù)字
    int num = (3,5);
//sum為三個數(shù)的和
    int sum = ({
        int a = 1;
        int b = 2;
        int c = 3;
        a+b+c;
    });
用這樣的方式可以用來分裝,其作用等于創(chuàng)建一個方法,返回自己需要的對象
92、占位
93、透過UIView
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    if (!self.passthroughTouches) { // 是否可以透過view
        return [super pointInside:point withEvent:event];
    }
    for (UIView *subview in self.subviews) {
        if (subview.isHidden) {
            continue;
        }
        CGPoint subviewPoint = [self convertPoint:point toView:subview];
        if ([subview pointInside:subviewPoint withEvent:event]) {
            return YES;
        }
    }
    return NO;
}
94、class、superclass、super、self含義
class:獲取方法調(diào)用者的類名;

superclass:獲取方法調(diào)用者的父類類名;

super:編譯修飾符,不是指針,跟const類似于關(guān)鍵字的作用,指向父類的標志;

本質(zhì)還是拿到當前對象去掉用父類的方法;

self:是一個指針,有地址;
95、UIColor 獲取 RGB 值
UIColor *color = [UIColor colorWithRed:0.0 green:0.0 blue:1.0 alpha:1.0];
const CGFloat *components = CGColorGetComponents(color.CGColor);
NSLog(@"Red: %f", components[0]);
NSLog(@"Green: %f", components[1]);
NSLog(@"Blue: %f", components[2]);
NSLog(@"Alpha: %f", components[3]);
96、求兩點間的距離
static __inline__ CGFloat CGPointDistanceBetweenTwoPoints(CGPoint point1, CGPoint point2) {
    CGFloat dx = point2.x - point1.x;
    CGFloat dy = point2.y - point1.y;
    return sqrt(dx*dx + dy*dy);
}
97、獲取某個view所在的控制器
- (UIViewController *)viewController {
    UIViewController *viewController = nil;  
    UIResponder *next = self.nextResponder;
    while (next) {
        if ([next isKindOfClass:[UIViewController class]]) {
            viewController = (UIViewController *)next;      
            break;    
    }    
        next = next.nextResponder;  
  } 
    return viewController;
}
98、字符串反轉(zhuǎn)
第一種:
- (NSString *)reverseWordsInString:(NSString *)str {    
    NSMutableString *newString = [[NSMutableString alloc] initWithCapacity:str.length];
    for (NSInteger i = str.length - 1; i >= 0 ; i --) {
        unichar ch = [str characterAtIndex:i];       
        [newString appendFormat:@"%c", ch];    
    }    
     return newString;
}
 
//第二種:
- (NSString*)reverseWordsInString:(NSString*)str {    
     NSMutableString *reverString = [NSMutableString stringWithCapacity:str.length];    
     [str enumerateSubstringsInRange:NSMakeRange(0, str.length) options:NSStringEnumerationReverse | NSStringEnumerationByComposedCharacterSequences  usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) { 
          [reverString appendString:substring];                         
      }];    
     return reverString;
}
99、iOS 獲取漢字的拼音
- (NSString *)transform:(NSString *)chinese {
    //將NSString裝換成NSMutableString
    NSMutableString *pinyin = [chinese mutableCopy];
    //將漢字轉(zhuǎn)換為拼音(帶音標)
    CFStringTransform((__bridge CFMutableStringRef)pinyin, NULL, kCFStringTransformMandarinLatin, NO);
    NSLog(@"%@", pinyin);
    //去掉拼音的音標
    CFStringTransform((__bridge CFMutableStringRef)pinyin, NULL, kCFStringTransformStripCombiningMarks, NO);
    NSLog(@"%@", pinyin);
    //返回最近結(jié)果
    return pinyin;
}
100、判斷view是不是指定視圖的子視圖
BOOL isView = [textView isDescendantOfView:self.view];
101、字符串中是否含有中文
- (BOOL)checkIsChinese:(NSString *)string {
    for (int i=0; i<string.length; i++) {
        unichar ch = [string characterAtIndex:i];
        if (0x4E00 <= ch  && ch <= 0x9FA5) {
            return YES;
        }
    }
        return NO;
}
102、UITextField每四位加一個空格,實現(xiàn)代理
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    // 四位加一個空格
    if ([string isEqualToString:@""]) {
        // 刪除字符
        if ((textField.text.length - 2) % 5 == 0) {
            textField.text = [textField.text substringToIndex:textField.text.length - 1];
        }
        return YES;
    } else {
        if (textField.text.length % 5 == 0) {
            textField.text = [NSString stringWithFormat:@"%@ ", textField.text];
        }
    }
    return YES;
}
103、超出父視圖范圍的控件部分響應(yīng)事件
-(UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
    UIView* hitView = [super hitTest:point withEvent:event];
    if (!hitView) {
        CGPoint tempPoint = [_testBtn convertPoint:point fromView:self];
        if (CGRectContainsPoint(_testBtn.bounds, tempPoint)) {
            hitView = _testBtn;
        }
    }
    return hitView;
}
104、如何做到對外只讀、對內(nèi)讀寫
//.h中
@property (readonly, nonatomic, strong, nullable) NSURL *baseURL;
//.m中
@property (readwrite, nonatomic, strong) NSURL *baseURL;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,621評論 1 32
  • 1.badgeVaule氣泡提示 2.git終端命令方法> pwd查看全部 >cd>ls >之后桌面找到文件夾內(nèi)容...
    i得深刻方得S閱讀 4,966評論 1 9
  • “我好怕。” “怕啥?” “壽險,已買到3000萬?!?“貪婪?!?“唯一受益人,他?!?“卑鄙!” “乍辦?” ...
    陳茀茀閱讀 375評論 2 3
  • 如果說中國哪座城市是我一直掛念,怎么也不肯釋懷的,那便當屬桂林。對我而言,它不再是一座城市,而是我心里落盡紅塵中與...
    若是禪閱讀 603評論 2 3
  • 為奮力推進脫貧攻堅,建設(shè)幸福美麗洪壩,加強黨群關(guān)系,豐富群眾文化生活,營造良好的節(jié)日氛圍。2019年2月19日,元...
    f87639272fd8閱讀 140評論 0 0

友情鏈接更多精彩內(nèi)容