前言(轉(zhuǎn))
做iOS開發(fā)這么長時(shí)間以來,遇到過不少難題,也踩過不少坑,本來沒想過要寫這篇文章,但是鑒于以下三點(diǎn),筆者決定對(duì)遇到過的并且還能回憶起來的問題做個(gè)記錄。
每次問題解決后,滿滿的成就感,但是當(dāng)下一次再遇到時(shí),又是一臉懵逼。這個(gè)問題我好像見過,但就是不記得怎么解決,記錄下來方便以后查閱。
每次面試的時(shí)候,面試官總會(huì)問我,你在開發(fā)中遇到過哪些問題,怎么解決的?問題嘛,挺多的,但是你要我敘述嘛,我......我......我居然一時(shí)想不起來,迷之尷尬????(面試官當(dāng)時(shí)想法:一看就是個(gè)沒工作經(jīng)驗(yàn)偽造簡歷的),冤枉啊。
為遇到同樣問題的開發(fā)者提供一個(gè)參考
那些遇到過的問題與踩過的坑
1.手機(jī)錄音或通話時(shí),app界面整體下移
當(dāng)你的iphone在錄音或者通話時(shí),打開app你會(huì)發(fā)現(xiàn),整個(gè)界面都下移了20像素,這個(gè)問題對(duì)于scrollView、tableView等可以垂直滾動(dòng)的視圖可能沒有太大影響,但是對(duì)于那些不能滾動(dòng)的視圖,就有可能底部被遮蓋20像素
筆者在網(wǎng)上查閱了資料,也試過多種方法,這個(gè)問題依然存在,最后筆者不得不使用大絕招來解決,何為大絕招?很簡單,位置尺寸寫死。項(xiàng)目中導(dǎo)航控制器是自定義的,在自定義的類中添加如下代碼就OK了

2.點(diǎn)擊導(dǎo)航欄下方也會(huì)觸發(fā)導(dǎo)航欄按鈕的點(diǎn)擊事件
如圖所示,每次想選中右上角的圖片,結(jié)果總是觸發(fā)“取消”事件,明明沒有點(diǎn)到導(dǎo)航欄上面去,問題的原因不清楚,解決方法創(chuàng)建一個(gè)UINavigationBar的分類,重寫hitTest方法

如果觸摸點(diǎn)不在它上面,就不讓它接收用戶交互,然后使用系統(tǒng)的事件處理方法去處理
3.輸入中文時(shí)限制字符長度
限制字母、數(shù)字、符號(hào)等其他非中文字符的長度大家應(yīng)該都知道咋整,但如果是中文輸入法,這就比較蛋疼了。舉個(gè)例子,限制長度為5,輸入“我愛寫代碼”,當(dāng)已經(jīng)輸入“我愛寫”兩字,然后輸入“代碼”時(shí)就會(huì)出現(xiàn)如下情況

根本寫不進(jìn)去啊,這是為什么呢?因?yàn)檩斎氲钠匆粢脖挥?jì)算在了字符串長度之內(nèi),導(dǎo)致輸入“da”以后就不能繼續(xù)輸入了,可通過下面的辦法解決

4.修改導(dǎo)航欄顏色
這個(gè)問題對(duì)有經(jīng)驗(yàn)的開發(fā)者來說不是問題,但是當(dāng)年筆者剛?cè)胄袝r(shí),確實(shí)被這個(gè)問題折騰了好久。比如想設(shè)置導(dǎo)航欄的顏色為藍(lán)色
self.navigationController.navigationBar.backgroundColor = [UIColor blueColor];
運(yùn)行,然后......????這特么是藍(lán)色?筆者確定自己不是色盲

后來才知道,設(shè)置導(dǎo)航欄的背景色,需要設(shè)置barTintColor而不是backgroundColor
self.navigationController.navigationBar.barTintColor = [UIColor blueColor];
5.界面莫名其妙下移
這個(gè)問題跟上面的問題一樣,都是比較基礎(chǔ)的問題,有經(jīng)驗(yàn)的人都知道如何解決,但是筆者曾經(jīng)也被折磨過

為什么下面textView的內(nèi)容不是從最上面開始的,而且還不能滾上去,當(dāng)初真的被這種情況折騰的死去活來的,改frame,改約束,都沒效果。后來才知道,當(dāng)有導(dǎo)航控制器時(shí),系統(tǒng)會(huì)默認(rèn)將第一個(gè)添加的scrollView或其子類視圖的內(nèi)容下移64個(gè)像素,下面的textView是先添加的,所以其內(nèi)容被下移了,而上面的卻沒有,解決方法是在控制器里加上下面這句代碼
self.automaticallyAdjustsScrollViewInsets = NO;
6.GCD組函數(shù)
筆者在開發(fā)中遇到過這樣一個(gè)功能,某個(gè)界面列表上面是企業(yè),下面是聯(lián)系人,而且獲取企業(yè)列表與聯(lián)系人列表的接口不是同一個(gè),必須等企業(yè)跟聯(lián)系人列表數(shù)據(jù)都獲取完畢后才能刷新,于是就用到了GCD組函數(shù)

然而問題來了,[[IBOSServer shared]...]這玩意兒是封裝好的,并且是個(gè)異步函數(shù),大家應(yīng)該都知道,異步函數(shù)不會(huì)阻塞線程,不用等里面的內(nèi)容執(zhí)行完就返回了,這就導(dǎo)致數(shù)據(jù)還沒拿到,就開始執(zhí)行notify里面的代碼了。后來筆者發(fā)現(xiàn),原來GCD組函數(shù)還有一種用法,完美解決問題

7.UISearchController
iOS8才出來的,用來替換UISearchBar + UISearchDisplayController的組合方式,項(xiàng)目中有用到搜索功能,于是筆者就嘗試著用了一下UISearchController,將搜索框添加到了tableView的tableHeaderView上。然而當(dāng)點(diǎn)擊搜索框準(zhǔn)備搜索時(shí),神奇的事情發(fā)生了

搜索框居然飛到九霄云外去了,好難過,這不是我要的那種結(jié)果,結(jié)果.....
怎么解決呢?在控制器里加上下面這句代碼就OK了,至于為什么,呵呵????,不知道
self.definesPresentationContext = YES;
8.自定義相機(jī)照片截取
這個(gè)問題說難不難,說簡單也不簡單,筆者當(dāng)時(shí)確實(shí)花了很長一段時(shí)間才弄清楚,但是當(dāng)問題解決后,感覺這特么也不復(fù)雜啊,之前怎么就沒整明白呢

問題是這樣的,在使用自定義相機(jī)拍完照后,需要對(duì)圖片的指定區(qū)域(藍(lán)色方框內(nèi)的區(qū)域)進(jìn)行截取然后上傳,這里存在兩個(gè)問題
拍攝時(shí)你所看到的區(qū)域,跟實(shí)際拍出來的區(qū)域是不一樣的

上圖就是實(shí)際拍出來的圖片,明顯比拍攝時(shí)看到的圖片要長,不過寬度是一樣的
照片的坐標(biāo)系與我們平時(shí)開發(fā)所使用的坐標(biāo)系是不一樣的
開發(fā)中所使用的視圖坐標(biāo)系是以左上角為原點(diǎn)的,橫向?yàn)閤軸,縱向?yàn)閥軸,而拍攝出來的照片是以右上角為原點(diǎn)的,橫向?yàn)閥軸,縱向?yàn)閤軸
我們先來看一幅圖

由于拍攝時(shí)所看到視圖寬高比與實(shí)際拍攝出來的圖片的寬高比并不一致,所以導(dǎo)致圖片經(jīng)過等比例縮放到寬度一樣時(shí),高度有一部分超出了我們的可視范圍,首先,我們要計(jì)算出超出部分的高度
//_cameraView為相機(jī)視圖,即拍攝時(shí)看到圖片的區(qū)域
CGFloat scale = image.size.width / _cameraView.width;//計(jì)算出縮放的比例
CGFloat showImageH = image.size.height / scale;//縮放后圖片的高度
CGFloat offsetY = (showImageH - _cameraView.height) * 0.5;//上下超出的部分是相等的,所以*0.5得出上面超過的部分
超出部分的高度計(jì)算完后,我們就要來計(jì)算藍(lán)色方框(_circleView,_cameraView的子控件)的坐標(biāo)了
x:(offsetY+_circleView.y) * scale,別忘了乘以縮放比例
y:_circleView.x * scale,因?yàn)閏ircleView在父控件中水平居中,所以_circleView在父控件中的x值乘以縮放比就是在圖片坐標(biāo)系中的y值
width:_circleView.height scale
height:_circleView.width scale
然后根據(jù)計(jì)算好的frame截取圖片就ok了
CGRect rect = CGRectMake(x, y, width,height);
CGImageRef tailorImageRef = CGImageCreateWithImageInRect(photo.CGImage, rect);
UIImage *tailorImage = [UIImage imageWithCGImage:tailorImageRef];
結(jié)束語
遇到過的坑,遠(yuǎn)遠(yuǎn)不止上面這些,不過有些不記得了,以后遇到了再補(bǔ)上吧!