iOS開發(fā)中的一些技巧

聲明:文章內(nèi)容中所有涉及的東西桶现,有一些是在網(wǎng)上查找的,有一些是個人在開發(fā)中摸索出來的喊巍,如果部分內(nèi)容涉及到了侵權問題屠缭,請及時聯(lián)系我,我會將其注明引用或刪除崭参。

1呵曹、Why doesn't UIScrollView/UITableview respond to taps on the status bar, and scroll to the top?

StackOverflow
This can occur when there are multiple instances of UIScrollView (or a subclass of UIScrollView, such as UITableView) with the scrollsToTop property set to YES on the same view, such as when a UIScrollView is added as a subview to a UIScrollView. Make sure that the scrollsToTop property of only one scroll view is set to YES. The correct UIScrollView should respond to tap events on the status bar after.
當你把一個 UIScrollView 或者 它的子類的對象(UITableView,UITextView, UICollectionView),作為子視圖添加到一個 UIScrollView 中時何暮,必須將其 scrollsToTop 設置為 NO奄喂,只保留父視圖 scrollView 的 scrollsToTop屬性為 YES,這樣才能在點擊 statusBar 時海洼,scrollView 能夠響應跨新。

2、獲取圖片類型

If you have NSData for the image file, then you can guess at the content type by looking at the first byte:

OC版本

+ (NSString *)contentTypeForImageData:(NSData *)data {
    uint8_t c;
    [data getBytes:&c length:1];
    
    switch (c) {
        case 0xFF:
            return @"image/jpeg";
        case 0x89:
            return @"image/png";
        case 0x47:
            return @"image/gif";
        case 0x49:
        case 0x4D:
            return @"image/tiff";
    }
    return nil;
}

Swift版本

/**
     根據(jù) imageData 獲取圖片的格式
     */
    fileprivate func imageType(_ imageData: Data) -> String {
        
        var c: UInt8 = 0x00
        (imageData as NSData).getBytes(&c, length: 1)
        
        switch c {
        case 0xFF:
            return "image/jpeg"
        case 0x89:
            return "image/png"
        case 0x47:
            return "image/gif"
        case 0x49,0x4D:
            return "image/tiff"
        default: return ""
        }
    }

3坏逢、給 TableView 添加系統(tǒng)自帶的 UIRefreshControl

let tableView = UITableView(frame:UIScreen.mainScreen().bounds)

let refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action: #selector(refresh),forControlEvents: .ValueChanged)
tableView.addSubview(refreshControl)

view.addSubview(tableView)

**iOS 10 ** 中域帐,UIScrollView 自帶一個 refreshControl 屬性赘被,可直接使用

4、Xcode中使用 #ifdef

(1) 首先在 Xcode 中配置宏


Xcode 配置.png

(2) 在代碼中使用

// 如上圖肖揣,創(chuàng)建了三個 target帘腹,就可以分別在各自的 target 里面,定義一個宏许饿,用來標識自已阳欲,
// 在代碼中使用的時候,能過判斷宏來取對應的數(shù)據(jù)或賦值
// 比如上面三個 target 的名字分別為 Test_Prod, Test_UAT, Test_Dev
// 其實是一個項目陋率,創(chuàng)建了多個 target球化,分別對應了 生產(chǎn)、測試和開發(fā)三個環(huán)境
// 在各自的 target 里面定義 TEST_PROD, TEST_UAT, TEST_DEV

#ifdef TEST_PROD        
    plistPath = [[NSBundle mainBundle] pathForResource:@"One_Config" ofType:@"plist"];
#elif defined TEST_UAT        
    plistPath = [[NSBundle mainBundle] pathForResource:@"Two_Config" ofType:@"plist"];
#elif defined TEST_DEV        
    plistPath = [[NSBundle mainBundle] pathForResource:@"Three_Config" ofType:@"plist"];
#else        
    plistPath = [[NSBundle mainBundle] pathForResource:@"Four_Config" ofType:@"plist"];
#endif

如何創(chuàng)建多個 target 瓦糟,在 第11條 可以找到

5筒愚、CALayer 中 position 和 anchorPoint 的關系

func test() {
    
    // position 坐標是 anchorPoint 在父 layer 上的位置
    // anchorPoint (0,0) 代表左上角,(1,1) 代表右下角菩浙,默認是 (0.5,0.5) (iOS 和 Mac OS 系統(tǒng)中原點位置是不一樣的巢掺,下面有解釋)
    // position 默認是 (layer.width * 0.5,layer.height * 0.5)
    
    
    let redView = UIView(frame: CGRect(x: 50, y: 50, width: 200, height: 200))
    redView.backgroundColor = UIColor.red
    
    
    let yellowLayer = CALayer()
    yellowLayer.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
    yellowLayer.backgroundColor = UIColor.yellow.cgColor
    
    print("before position = \(yellowLayer.position)")
    
    print("before anchorPoint = \(yellowLayer.anchorPoint)")
    
    redView.layer.addSublayer(yellowLayer)
    
    // anchorPoint 不變,position 變
    yellowLayer.position = CGPoint(x: 0, y: 0)
    
    
    // anchorPoint 變劲蜻,position 不變
    //yellowLayer.anchorPoint = CGPoint(x: 0, y: 0)    
    yellowLayer.anchorPoint = CGPoint(x: 0, y: 0)
    
    
    print("after position = \(yellowLayer.position)")
    
    print("after anchorPoint = \(yellowLayer.anchorPoint)")
    
    
    view.addSubview(redView);
}

在 iOS 系統(tǒng)中陆淀,Layer 的 anchorPoint 所在的坐標系的原點為左上角,在 OS 系統(tǒng)中先嬉,原點是左下角轧苫,可在 CoreAnimationGuide 中查看

Unit Coordinate Systems.png

Snip20180604_2.png

6、隱藏導航欄返回按鈕上的文字疫蔓,只保留箭頭含懊;自定義返回箭頭圖片

方法一:(親測有效)

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

方法二:

Try 
self.navigationItem.backBarButtonItem.hidden = YES; 
or
self.navigationItem.backBarButtonItem = nil;
or
self.navigationItem.hidesBackButton = YES;
Place one of these either in viewWillAppear:, viewWillLoad or viewDidAppear: of the class you want to get rid of the back button in.

設置返回箭頭圖片

// 設置返回 icon
UIImage *backButtonIcon = [UIImage imageNamed:@"BackItem"];
self.navigationController.navigationBar.backIndicatorImage = backButtonIcon;
self.navigationController.navigationBar.backIndicatorTransitionMaskImage = backButtonIcon;

7、URL編碼內(nèi)容衅胀、還原內(nèi)容

在進行網(wǎng)絡請求時岔乔,如果 URL 里面有中文,就需要進行編碼滚躯,然后再去使用

編碼時注意選擇對應的 NSCharacterSet 雏门,否則編碼出來的東西可能會出現(xiàn)不一致的情況

// 使用這個編碼時注意要用 URLQueryAllowedCharacterSet ,否則出來的內(nèi)容哀九,與接收到的有一些不一致
NSString *encodedContents2 = [contents stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    
NSLog(@"encodedContents2 = %@",encodedContents2);
    
// 使用這個方法剿配,編碼出來的內(nèi)容和接收到的一致,但是這個 API 已經(jīng)被 deprecated
NSString *encodedContents3 = [contents stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    
NSLog(@"encodedContents3 = %@",encodedContents3);

如果接收到的 URL 里面是編碼過的內(nèi)容阅束,可以通過 string 的屬性直接獲取原始內(nèi)容

NSString *contents = originalContents.stringByRemovingPercentEncoding;

8呼胚、UITableView 在 Group style 下設置 header/footer 高度

(1)如果要去掉第一個cell 上面的空白的話,需要給 tableView 設置一個 tableHeaderView息裸,把這個 view 的高度調(diào)成一個非常小的數(shù)

self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, SCREEN_WIDTH, 10.0f)];

(2)設置 header/footer 的高度
有兩種方法:
方法一:直接設置 tableView 的屬性

self.tableView.sectionFooterHeight = 10;
self.tableView.sectionHeaderHeight = 0;

方法二:在代理里面設置
這個時候需要注意蝇更,如果要設置 0 的話沪编,直接 return 0 是沒有效果的,也是需要返回一個很小的數(shù)年扩,這種方法也可以去除第一個 cell 上面的空白
注意: 如果只要 header 的高度的話蚁廓,一定要把 footer 設置成 0.000001 ,以免誤以為設置的 header 的高度沒起作用

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

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return 0.01;
}

9厨幻、自定義了 leftBarButtonItem 之后相嵌,邊緣手勢失效

self.navigationController.interactivePopGestureRecognizer.delegate = (id)self;

10、如何讓邊緣手勢失效

在iOS7以后况脆,如果是用NavgationController推出來的界面饭宾,這個界面都有邊緣手勢側滑效果,想讓界面不響應這個邊緣手勢只需要一行代碼:(一但調(diào)用格了,所有地方都會失效)

//關閉邊緣手勢,這個值默認是YES
self.navigationController.interactivePopGestureRecognizer.enabled = NO;

11看铆、在一個項目里面創(chuàng)建多個 Target

(1) 在原來的 Target 上面右鍵,Duplicate

1.png

(2) Xcode 會創(chuàng)建一個新的 Target 以及與它相對應的 xxx-info.plist 文件

1.png

(3)修改新的 Target 的名字和它對應 info.plist 文件的名字

3.png

(4)在新的 Target 的 BuildSetting 中配置對應的 info.plist文件路徑盛末,可以寫完整路徑:$(SRCROOT)/TargetTest-Two-Info.plist

$(SRCROOT): 定位到工程所在的目錄弹惦,與 TargetTest.xcodeproj 同一等級的目錄下

4.png

12、關于導航欄半透明的設置

extendedLayoutIncludesOpaqueBars:這個屬性表示悄但,是否將 controller 的 rootView(即 self.view) 擴展到不透明的 bar 下面棠隐,默認為 NO;
navigationBar 默認是半透明的(translucent = YES)算墨,
self.edgesForExtendedLayout 默認是 UIRectEdgeAll

所以默認情況下宵荒,controllerrootView 會被擴展到半透明的 navigationBar 下面,即 self.view 的大小和屏幕大小一樣;

默認情況

當我們將 navigationBar.translucent 設置為 NO 時(不透明)净嘀,由于 extendedLayoutIncludesOpaqueBars 默認為 NO,不擴展到不透明的 bar 下面侠讯,所以這個時候挖藏,controller 的 rootView 頂部是從 navigationBar 的底部開始的;

導航欄不透明

如果將 extendedLayoutIncludesOpaqueBars 設置為 YES厢漩,那么 rootView 還是會被擴展膜眠,大小與屏幕大小一樣

導航欄不透明
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市溜嗜,隨后出現(xiàn)的幾起案子宵膨,更是在濱河造成了極大的恐慌,老刑警劉巖炸宵,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辟躏,死亡現(xiàn)場離奇詭異,居然都是意外死亡土全,警方通過查閱死者的電腦和手機捎琐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進店門会涎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人瑞凑,你說我怎么就攤上這事末秃。” “怎么了籽御?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵练慕,是天一觀的道長。 經(jīng)常有香客問我技掏,道長铃将,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任零截,我火速辦了婚禮麸塞,結果婚禮上,老公的妹妹穿的比我還像新娘涧衙。我一直安慰自己哪工,他們只是感情好,可當我...
    茶點故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布弧哎。 她就那樣靜靜地躺著雁比,像睡著了一般。 火紅的嫁衣襯著肌膚如雪撤嫩。 梳的紋絲不亂的頭發(fā)上偎捎,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天,我揣著相機與錄音序攘,去河邊找鬼茴她。 笑死,一個胖子當著我的面吹牛程奠,可吹牛的內(nèi)容都是我干的丈牢。 我是一名探鬼主播,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼瞄沙,長吁一口氣:“原來是場噩夢啊……” “哼己沛!你這毒婦竟也來了?” 一聲冷哼從身側響起距境,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤申尼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后垫桂,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體师幕,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年伪货,在試婚紗的時候發(fā)現(xiàn)自己被綠了们衙。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钾怔。...
    茶點故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蒙挑,靈堂內(nèi)的尸體忽然破棺而出宗侦,到底是詐尸還是另有隱情,我是刑警寧澤忆蚀,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布矾利,位于F島的核電站,受9級特大地震影響馋袜,放射性物質(zhì)發(fā)生泄漏男旗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一欣鳖、第九天 我趴在偏房一處隱蔽的房頂上張望察皇。 院中可真熱鬧,春花似錦泽台、人聲如沸什荣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽稻爬。三九已至,卻和暖如春蜕依,著一層夾襖步出監(jiān)牢的瞬間桅锄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工样眠, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留友瘤,地道東北人。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓檐束,卻偏偏與公主長得像商佑,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子厢塘,可洞房花燭夜當晚...
    茶點故事閱讀 45,440評論 2 359

推薦閱讀更多精彩內(nèi)容