1. 程式人生 > >iOS開發2016小知識點記錄

iOS開發2016小知識點記錄


//第一種(通用)
    UIFont *font = [UIFont fontWithName:@"HelveticaNeue-Medium" size:14.0f];
    //iOS8.2開始
    [UIFont systemFontOfSize:14 weight:UIFontWeightMedium];

第一種

- (CGFloat)tableView:(UITableView*)tableView 
           heightForHeaderInSection:(NSInteger)section {
    if (section == 0) {
        return 6.0;
    }

    return 1.0;
}

- (CGFloat)tableView:(UITableView*)tableView 
           heightForFooterInSection:(NSInteger)section {
    return 5.0;
}

- (UIView*)tableView:(UITableView*)tableView 
           viewForHeaderInSection:(NSInteger)section {
    return [[UIView alloc] initWithFrame:CGRectZero];
}

- (UIView*)tableView:(UITableView*)tableView 
           viewForFooterInSection:(NSInteger)section {
    return [[UIView alloc] initWithFrame:CGRectZero];
}
第二種(返回CGFloat_MIN)
// footer 間距
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
//    return 1.0f;
    return CGFLOAT_MIN;
}

3.減少多餘的tableView空的cell

tableView.tableFooterView = [UIViewnew];



[self.navigationController.navigationBar setTitleTextAttributes:
 @{NSForegroundColorAttributeName:[UIColor redColor],
NSFontAttributeName:[UIFont fontWithName:@"mplus-1c-regular" size:21]}];
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {

    // do stuff for iOS 7 and newer
    [self.navigationController.navigationBar setBarTintColor:[UIColor yellowColor]];
}
else {

    // do stuff for older versions than iOS 7
    [self.navigationController.navigationBar setTintColor:[UIColor yellowColor]];
}


6. How to detect if vc is being popped or pushed?(如何知道導航欄是pop還是push)

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    if ([self isMovingFromParentViewController])
    {
        NSLog(@"View controller was popped");
    }
    else
    {
        NSLog(@"New view controller was pushed");
    }
}

7. 如何手動取消UIDispalaySearchController的取消搜尋狀態

#pragma mark - 點選搜尋,能夠取消搜尋狀態  
#pragma mark UISearchDisplayDelegate  
- (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller  
{  
    for (UIView *view in controller.searchBar.subviews)  
    {  
         NSLog(@"%d__|---%@",__LINE__,view);  
        for (UIView *subView in view.subviews)  
        {  
             NSLog(@"%d__|!!!%@",__LINE__,subView);  
            //  獲取"取消"按鈕  
            if([subView isKindOfClass:[UIButton class]])  
            {  
                UIButton *cancelButton = (UIButton *)subView;  
                //  獲取點選"取消"按鈕的響應事件(actionsForTarget 這個方法返回的是一個數組)  
                self.cancelSearchSELString = [[cancelButton actionsForTarget:controller.searchBar forControlEvent:UIControlEventTouchUpInside] objectAtIndex:0];  
                //  響應通知,執行方法直接用上面獲得的響應事件方法,轉換一下(這是個知識點,可以擴充套件下)  
                [[NSNotificationCenter defaultCenter] addObserver:controller.searchBar selector:NSSelectorFromString(self.cancelSearchSELString) name:@"cancelSearch" object:nil];  
            }  
        }  
    }  
}  
  
#pragma mark UISearchBarDelegate------點選搜尋按鈕  
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{  
  
    //  獲取你想搜尋的最終完整關鍵字(一般可以用來做搜尋歷史展示)    
    NSLog(@"%s__%d__|%@",__FUNCTION__,__LINE__,searchBar.text);  
    //  點選按鈕時,釋出取消搜尋狀態通知  
    [[NSNotificationCenter defaultCenter] postNotificationName:@"cancelSearch" object:nil];  
    //  釋出---響應---取消通知  
    [[NSNotificationCenter defaultCenter] removeObserver:searchBar name:@"cancelSearch" object:nil];  
}  

8.Receive Tap Gesture only on part of a view (如何只讓手勢響應指定區域)

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(clickView:)];
    tap.delegate = self;
    [self.view addGestureRecognizer:tap];
    
//    [self.picker addTarget:self action:@selector(changeDate:) forControlEvents:UIControlEventValueChanged];
}


// 該方法讓只點擊上方mask的時候才能響應手勢,攔截手勢響應的區域,只有上方才有效
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    CGPoint touchPoint = [touch locationInView:self.view];
    // touchPoint的點是否在self.contentView區域以內,是的話就取反,不接受手勢,不是的話就響應手勢,關閉介面
    BOOL isContainsPoint = CGRectContainsPoint(self.backView.frame, touchPoint);
    return !isContainsPoint;
}


9.UIImage的渲染模式 imageWithRenderingMode

UIImage新增了一個只讀屬性:renderingMode,對應的還有一個新增方法:imageWithRenderingMode:,它使用UIImageRenderingMode列舉值來設定圖片的renderingMode屬性。該列舉中包含下列值:

UIImageRenderingModeAutomatic  // 根據圖片的使用環境和所處的繪圖上下文自動調整渲染模式。  

UIImageRenderingModeAlwaysOriginal   // 始終繪製圖片原始狀態,不使用Tint Color。  

UIImageRenderingModeAlwaysTemplate   // 始終根據Tint Color繪製圖片,忽略圖片的顏色資訊

注意:咱們本身的切圖是綠色無汙染的

[barItem setImage:[UIImage imageNamed:obj[kImageKey]]];
        [barItem setSelectedImage:[UIImage imageNamed:obj[kSelectedImageKey]]];
普通做法: 顏色被修改了 系統的預設貌似都是藍色
[barItem setImage:[[UIImage imageNamed:obj[kImageKey]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]];
        [barItem setSelectedImage:[[UIImage imageNamed:obj[kSelectedImageKey]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]];
修改渲染屬性:使用的是圖片原始的顏色

10.How to change UILabel Text Margin (如何更改UILabel內部文字的邊距)

繼承UILabel,重寫他的方法設定邊距
- (void)drawTextInRect:(CGRect)rect {
    UIEdgeInsets insets = {0, 5, 0, 5};
    [super drawTextInRect:UIEdgeInsetsInsetRect(rect, insets)];
}


11.當tableView右側有index引索的時候,如何修改引索View的背景顏色

- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {    

  for(UIView *view in [tv subviews])
  {
    if([[[view class] description] isEqualToString:@"UITableViewIndex"])
    {

      [view setBackgroundColor:[UIColor whiteColor]];
      [view setFont:[UIFont systemFontOfSize:14]];
    }
  }

  //rest of cellForRow handling...

}


12.iOS 6 和 7中UITableViewCell的獲取方法

SDK 6.1
<UITableViewCell>
   | <UITableViewCellContentView>
   |    | <UILabel>
UITableViewCell *clickedCell = (UITableViewCell *)[[sender superview] superview];
    NSIndexPath *clickedButtonPath = [book_table indexPathForCell:clickedCell];
    NSLog(@"index=%@",clickedButtonPath);

SDK 7
<UITableViewCell>
   | <UITableViewCellScrollView>
   |    | <UITableViewCellContentView>
   |    |    | <UILabel>
UITableViewCell *clickedCell = (UITableViewCell *)[[[sender superview] superview]superview];
    NSIndexPath *clickedButtonPath = [book_table indexPathForCell:clickedCell];
    NSLog(@"index=%ld",(long)clickedButtonPath.item);

13.幾個常用的C計算函式

ceil(x)返回不小於x的最小整數值(然後轉換為double型)。

floor(x)返回不大於x的最大整數值。

round(x)返回x的四捨五入整數值。



14.例如視訊播放等需求,單擊手勢和雙擊手勢衝突,如何只響應雙擊的時候不響應單擊

// 單擊的 Recognizer
                    singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
                    singleTap.numberOfTapsRequired = 1; // 單擊
                    singleTap.numberOfTouchesRequired = 1;
                    [self addGestureRecognizer:singleTap];
                    // 雙擊的 Recognizer
                    UITapGestureRecognizer* doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)];
                    doubleTap.numberOfTapsRequired = 2; // 雙擊
                    [singleTap requireGestureRecognizerToFail:doubleTap];//如果雙擊成立,則取消單擊手勢(雙擊的時候不回走單擊事件)
                    [self addGestureRecognizer:doubleTap];


15.獲取視訊首幀縮圖

**4、獲取視訊縮圖**
獲取首幀視訊截圖的方法如下:
```objc
        AVAssetImageGenerator  *imageGen = [[AVAssetImageGenerator alloc] initWithAsset:self.source];
        if (imageGen) {
            imageGen.appliesPreferredTrackTransform = YES;
            CMTime actualTime;
            CGImageRef cgImage = [imageGen copyCGImageAtTime:CMTimeMakeWithSeconds(0, 30) actualTime:&actualTime error:NULL];
            if (cgImage) {
                UIImage *image = [UIImage imageWithCGImage:cgImage];
                CGImageRelease(cgImage);
                return image;
            }
        }

16.如何給Xcode增加個模擬器

第一種:掛個VPN直接download simulators  下載你需要的型號 第二種:直接下載個包,然後進入/Library/Developer/CoreSimulator/Profiles/Runtimes路徑 解壓,解壓不了就直接sudo unzip 包名字 ,解壓出來之後重啟電腦 在Add simulators裡面新增新增的模擬器

17.理解下removeFromSuperView到底是什麼鬼??!!

removeFromSuperview就是一個檢視節點刪除的操作,執行這個方法,就等於在樹形結構中找到該節點,從樹型數

據結構中刪除該節點及其子節點,而並非只是刪除該節點自己。同時,另一個操作就是把該物件從響應者鏈中移除。

執行removeFromSuperview方法,只是該檢視不在螢幕中顯示,並沒有將該檢視從記憶體中移除。所以我們如果需要

使用該檢視,不需要再次建立,而是直接addSubview就可以了。

但是如果你執行這句程式碼之後,再執行obj = nil,那麼直接就把他釋放了,看Deme

View1和View2對比,View1remove之後直接置nil,view2不置nil

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.view1 = [[UIView alloc] initWithFrame:CGRectMake(0, 80, 100, 100)];
    self.view1.backgroundColor = [UIColor blueColor];
    [self.view addSubview:self.view1];
    self.view2 = [[UIView alloc] initWithFrame:CGRectMake(0, 220, 100, 100)];
    self.view2.backgroundColor = [UIColor yellowColor];
    [self.view addSubview:self.view2];
    
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(click:)];
    [self.view addGestureRecognizer:tap];
}

- (void)click:(UITapGestureRecognizer *)tap
{
    if (!self.isHidden)
    {
        [self.view1 removeFromSuperview];
        [self.view2 removeFromSuperview];
        if (self.view1) {
            self.view1 = nil;
        }
    }
    else
    {
        [[UIApplication sharedApplication].keyWindow addSubview:self.view1];
        [[UIApplication sharedApplication].keyWindow addSubview:self.view2];
    }
    self.isHidden = !self.isHidden;
}

View1消失了,View2還在

18.習慣Xib佈局的,UIButton一定要修改其屬性

如圖預設的系統狀態下選擇的背景Image是藍色的
我經常忘記修改 第一種我們可以在ViewDidLoad的時候:
[UIButton buttonWithType:UIButtonTypeSystem]; 

第二種我們可以在inspector第一欄裡面修改為Custom,預設是System的

19.代替巨集的全域性靜態只讀常量

static 和 const 來宣告一個只讀靜態變數 const 是編譯期間的,會檢測報錯 巨集是編譯之前替代的,不會報錯,能定義函式,const不能,大量的巨集每次替代會很耗時,apple不推薦用巨集,我們還是用static const NSString * name = @“MKJ”來宣告靜態的全域性只讀常量
// 開發中常用static修飾全域性變數,只改變作用域

// 為什麼要改變全域性變數作用域,防止重複宣告全域性變數。

// 開發中宣告的全域性變數,有些不希望外界改動,只允許讀取。

// 比如一個基本資料型別不希望別人改動

// 宣告一個靜態的全域性只讀常量
static const int a = 20;

// staic和const聯合的作用:宣告一個靜態的全域性只讀常量

// iOS中staic和const常用使用場景,是用來代替巨集,把一個經常使用的字串常量,定義成靜態全域性只讀變數.

// 開發中經常拿到key修改值,因此用const修飾key,表示key只讀,不允許修改。
static  NSString * const key = @"name";

// 如果 const修飾 *key1,表示*key1只讀,key1還是能改變。

static  NSString const *key1 = @"name";


20.四捨五入 進位 摸位的計算函式

四捨五入
float numberToRound;
    int result;

    numberToRound = 5.61;
    result = (int)roundf(numberToRound);
    NSLog(@"roundf(%.2f) = %d", numberToRound, result);
    //輸出 roundf(5.61) = 6


    numberToRound = 5.41;

    result = (int)roundf(numberToRound);

    NSLog(@"roundf(%.2f) = %d", numberToRound, result);

    //輸出 roundf(5.41) = 5

進位
 float numberToRound;
    int result;

    numberToRound = 5.61;
    result = (int)ceilf(numberToRound);

    NSLog(@"ceilf(%.2f) = %d", numberToRound, result);

    //輸出 ceilf(5.61) = 6



    numberToRound = 5.41;

    result = (int)ceilf(numberToRound);

    NSLog(@"ceilf(%.2f) = %d", numberToRound, result);

    //輸出 ceilf(5.41) = 6

摸位
float numberToRound;
    int result;

    numberToRound = 5.61;
    result = (int)floorf(numberToRound);

    NSLog(@"floorf(%.2f) = %d", numberToRound, result);

    //輸出 floorf(5.61) = 5



    numberToRound = 5.41;

    result = (int)floorf(numberToRound);

    NSLog(@"floorf(%.2f) = %d", numberToRound, result);

    //輸出 floorf(5.41) = 5


21.如何修改UISearchBar Cancel title & textAttribute

[self.searchController.searchBar setValue:@"我擦" forKey:@"_cancelButtonText"];
    [[UIBarButtonItem appearanceWhenContainedIn:[UISearchBar class], nil] setTitleTextAttributes:@{NSFontAttributeName : [UIFont boldSystemFontOfSize:14],NSForegroundColorAttributeName : RGBA(51, 51, 51, 1)} forState:UIControlStateNormal];

22.iOS 8上下字型的不同方法區分

cell.textLabel.font = [TWTFontWeight systemFontOfSize:15 forWeight:Medium];

+(UIFont*)systemFontOfSize:(CGFloat)size forWeight:(NSString*)weight
{
    NSDictionary * fontWeightMap1 = @{
                                         @"UltraLight":@"HelveticaNeue-UltraLight",
                                         @"Thin":@"HelveticaNeue-Thin",
                                         @"Light":@"HelveticaNeue-Light",
                                         @"Regular":@"HelveticaNeue",
                                         @"Medium":@"HelveticaNeue-Medium",
                                         @"Semibold":@"Helvetica-Bold",
                                         @"Bold":@"HelveticaNeue-Bold",
                                         @"Heavy":@"HelveticaNeue-CondensedBold",
                                         @"Black":@"HelveticaNeue-CondensedBlack"
                                    };
    

    
    if (size<1)
    {
        size = 14;
    }
    CGFloat value =[[[UIDevice currentDevice] systemVersion] floatValue];
    if (value>8.1)
    {
        NSDictionary * fontWeightMap2 = @{
                                          @"UltraLight":@(UIFontWeightUltraLight),
                                          @"Thin":@(UIFontWeightThin),
                                          @"Light":@(UIFontWeightLight),
                                          @"Regular":@(UIFontWeightRegular),
                                          @"Medium":@(UIFontWeightMedium),
                                          @"Semibold":@(UIFontWeightSemibold),
                                          @"Bold":@(UIFontWeightBold),
                                          @"Heavy":@(UIFontWeightHeavy),
                                          @"Black":@(UIFontWeightBlack),
                                          };
        CGFloat weightName = [[fontWeightMap2 valueForKey:weight]floatValue];
        return [UIFont systemFontOfSize:size weight:weightName];
    }
    else
    {
        NSString* weightName = [fontWeightMap1 valueForKey:weight];
        return [UIFont fontWithName:weightName size:size];
    }
}


23.iOS應用跳轉到App Store的兩種方式


// 這個方法是用SK框架開啟直接下載頁面  要匯入#import <StoreKit/StoreKit.h>
                SKStoreProductViewController *storeProductViewContorller = [[SKStoreProductViewController alloc] init];
                //設定代理請求為當前控制器本身
                storeProductViewContorller.delegate = self;
                //載入一個新的檢視展示
                [storeProductViewContorller loadProductWithParameters:
                 //appId唯一的
                 @{SKStoreProductParameterITunesItemIdentifier : @"1048352304"} completionBlock:^(BOOL result, NSError *error) {
                     //block回撥
                     if(error){
                         NSLog(@"error %@ with userInfo %@",error,[error userInfo]);
                     }else{
                         //模態彈出appstore
                         [self presentViewController:storeProductViewContorller animated:YES completion:^{
                             
                         }
                          ];
                     }
                 }];
                // 直接開啟方法
                [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://itunes.apple.com/app/tao-wai-tao-fa-xian-guo-wai/id1048352304?l=zh&mt=8"]];

24.Mac系統下面刪除.svn檔案,然後重新checkOut

MAC系統下,.svn檔案是隱藏的。

如果專案是非export匯出的,那麼專案中會有很多的.svn檔案。

如果專案的體積非常龐大,我們如何快速的批量刪除.svn檔案呢?下面是操作方法:

開啟終端,cd ...命令進入到.svn所在的資料夾。

輸入:find . -type d -name ".svn"|xargs rm -rf

回車,這樣.svn檔案已經全部刪除了。

25.截圖效果

- (UIImage *)snapshot:(UIView *)view

{

    UIGraphicsBeginImageContextWithOptions(view.bounds.size,YES,0);

    [view drawHierarchyInRect:view.bounds afterScreenUpdates:YES];

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return image;

}

26.如何刪除.git檔案,避免重複包含

Xcode預設是受git管理的,你可以新建一個專案,然後ls -a檢視,能看到一個.git的檔案,如果一般操作,push到github倉庫,那問題不大,但是如果你外面再包一層folder,然後你在根資料夾下進行git init add commit remote push一系列操作,你會看到你的github資料夾是灰色的,資料上說就是不能重複包含,外層有管理,內層又有管理,這樣是不可取的,所以我的做法是建立的時候刪除Xcode自帶生成的.git檔案
find . -name ".git" | xargs rm -Rf
然後再一套連招,就可以正常push到github了

27.如何判斷字串有中文

- (BOOL)containChineseWord:(NSString *)string
{
    for (NSInteger index = 0; index < string.length; index++)
    {
        unichar indexChar = [string characterAtIndex:index];
        if (indexChar > 0xE0)
        {
            return YES;
        }
    }
    return NO;
}

28.如何讓TestField輸入只有英文,中文和字元

+ (BOOL)isValidatePassword:(NSString *)password
{
    // 合法字元
    NSString *psw = @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~`[email protected]#$%^&*()_-+={}[]|;:,<>.?/";
    // 取反
    NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:psw] invertedSet];
    // 取反字元分割組合
    NSString *filtered = [[password componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
    // 分割不到,相同,代表合法 返回YES,分割到了,不同,代表不合法字元存在,返回NO
    return [password isEqualToString:filtered];
}


29.如何修改例如聊天氣泡Image的顏色

- (UIImage *)jsq_imageMaskedWithColor:(UIColor *)maskColor
{
    NSParameterAssert(maskColor != nil);
    
    CGRect imageRect = CGRectMake(0.0f, 0.0f, self.size.width, self.size.height);
    UIImage *newImage = nil;
    
    UIGraphicsBeginImageContextWithOptions(imageRect.size, NO, self.scale);
    {
        CGContextRef context = UIGraphicsGetCurrentContext();
        
        CGContextScaleCTM(context, 1.0f, -1.0f);
        CGContextTranslateCTM(context, 0.0f, -(imageRect.size.height));
        
        CGContextClipToMask(context, imageRect, self.CGImage);
        CGContextSetFillColorWithColor(context, maskColor.CGColor);
        CGContextFillRect(context, imageRect);
        
        newImage = UIGraphicsGetImageFromCurrentImageContext();
    }
    UIGraphicsEndImageContext();
    
    return newImage;
}