一、UITableView的scrollDelegate問題html
下午遇到一個奇怪的問題,以前都沒有注意過,因爲A VC中要實現tableView和其餘View位置的聯動,
因此實現了tableView的delegate中的scrollViewDidScroll方法,結果在點擊商品push 商品詳情VC B 的時候,問題出現了。json
問題表現:
在調用[self.navigationController pushViewController:productDetailVC animated:YES];
時發現VC A中的tableView老是會滾動到頂部(contentOffset被修改了)安全
看了半天也沒發現問題,後面在scrollViewDidScroll的位置加了一個斷點,發如今navigationController在Push VC B的過程當中,系統會調用一次VC A中tableView的scrollViewDidScroll方法,關鍵是這時調用中傳入的contentOffset是有問題的(0,-contentInset.y),因此致使了VC A中的tableView會自動返回頭部網絡
解決方法:在VC A的viewWillDisappear的時候設置tableView的delegate爲nil,同時在viewWillAppear中再把tableView的delegate設置回來,這個問題就被解決掉了。
all in all 問題很奇怪,但願你們再也不被一樣的問題困擾app
二、UIView的exclusiveTouch屬性async
經過設置[selfsetExclusiveTouch:YES];能夠達到同一界面上多個控件接受事件時的排他性,從而避免一些問題。函數
三、UIScrollView和UITableView嵌套時點擊statusBar,scrollView不反回頭部的問題工具
蘋果在UIScrollView頭文件的註釋能夠清楚的解決咱們的困惑測試
// When the user taps the status bar, the scroll view beneath the touch which is closest to the status bar will be scrolled to top, but only if its `scrollsToTop` property is YES, its delegate does not return NO from `shouldScrollViewScrollToTop`, and it is not already at the top.this
// On iPhone, we execute this gesture only if there's one on-screen scroll view with `scrollsToTop` == YES. If more than one is found, none will be scrolled.
@property(nonatomic) BOOL scrollsToTop; // default is YES.
四、JSON Kit數據轉換問題
json是很經常使用的網絡數據包格式,客戶端和服務端之間常用json來傳輸數據。對於一些字典類型的數據,若是某項數據爲空,則會傳'<null>',使用JsonKit轉換之後會生出相應的[NSNull null]對象,而這種對象對於iOS來講並非十分安全的,例如約定好商品的某一項字段爲string類型,結果JSON Kit轉換爲[NSNull null],這個時候若是不加判斷就當作是NSString處理就會存在問題。因此對於這種數據類型直接轉換爲nil會更加安全,轉換方法以下:
#define PASS_NULL_TO_NIL(instance) (([instance isKindOfClass:[NSNull class]]) ? nil : instance)
針對nil調用任何方法基本上都是安全的。
五、iOS 7中系統自定義VC右滑返回特性不生效
iOS 7開始系統新增了UINavigationController中VC層級右滑返回上一級的特性,該特性默認是打開的。可是在項目中有一個自定義VC中該特性無效,排查半天定位到問題以下:
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"navigation_bar_back.png"] style:UIBarButtonItemStylePlain target:self action:@selector(backAction:)];
初一看這段代碼沒有任何問題,只是簡單的自定義返回按鈕。可是問題就處在這裏,只要自定義了leftItem右滑返回上一層級就會實效。
由於我這個VC中UI比較複雜,ScrollView,tableView各類嵌套,所以一開始還懷疑是否是手勢衝突致使的,後來發現右滑返回屬性壓根就和咱們能接觸的手勢無關。將上述代碼修改成以下代碼,問題就解決了。
if (IS_IOS_6) { self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"navigation_bar_back.png"] style:UIBarButtonItemStylePlain target:self action:@selector(backAction:)]; }
只針對iOS 7以前的系統自定義返回按鈕,iOS 7及之後直接使用系統的返回圖標「<」。
咱們也能夠直接獲取這個手勢「interactivePopGestureRecognizer」,作一些定製操做。
更詳細的信息能夠參考:http://www.cnblogs.com/lexingyu/p/3432444.html
六、UITableViewCell選中保持問題
UITableView中cell的選中態在調用ReloadData之後沒法保持,爲了作到選中態一直有效,我試着在cellForRowAtIndexPath中恢復選中態,代碼以下:
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellIdentifier = @"myAccountMenuCellIdentifier"; UITableView *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } ... // 恢復選中態 if (_currentSelectedIndexPath && indexPath.row == _currentSelectedIndexPath.row && indexPath.section == _currentSelectedIndexPath.section) { [cell setSelected:YES animated:NO]; } else { [cell setSelected:NO animated:NO]; } return cell; }
發現根本不起做用,還嘗試着重載了自定義cell的
- (void)setSelected:(BOOL)selected animated:(BOOL)animated; - (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated;
也是毫無進展,最後終於經過重載reloadData,代碼以下:
- (void)reInvokeCurrentMenuItem { [self selectRowAtIndexPath:_currentSelectedIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone]; [self tableView:self didSelectRowAtIndexPath:_currentSelectedIndexPath]; }
即在每次reload之後都通作一次selectRowAtIndexPath的操做來恢復選中。問題雖然解決了可是這種方法也有潛在風險,好比reload的過程當中數據源發生變化,可能以前選中的cell的indexPath已經改變,輕則選中不正確的cell,嚴重的話若是刷新之後cell個數減小,傳入一個過大的indexPath就會形成崩潰。
so此方法,請君「且用且珍惜」。
七、UITextField當實現了textFieldDidBeginEditing方法之後, Clearbtn不響應,緣由是最簡單的view覆蓋致使事件被攔截了
若是必須實現delegate,則可使用設置rightView的方式
這個問題我最後解決了,說來都很差意思,被別的View蓋住了,so出了問題仍是得先思考一下是否是本身的問題。
查這個問題得過程當中,我找到一個很好用的GDB調試方法,直接在GDB中輸入如下命令便可打印當前App的view層級。
po [[UIWindow keyWindow] recursiveDescription]
我知道網上有個收費的工具叫Reveal,能夠更炫的查看view層級,好消息是xCode6 Debug自帶了可查看view層級的功能。底層的實現機制也是同樣,我的偏執的以爲仍是命令行打印的更清晰,特別是view層級不少的時候。
八、Block爲空是調用會Crush
昨天碰到一個crash問題,查了一下發現是Block是nil,而後我調用了該Block,程序crash。開始懷疑是否是個人block是在dispatch_async致使的crash,後面測試發現,只要block爲nil,調用這個block都會crash。
簡單示例以下:
// 定義一個block類型 typedef void (^CompleteBlock) (); // 聲明一個CompleteBlock類型的變量 CompleteBlock cblock = nil; cblock(); // 調用會crash dispatch_async(dispatch_get_main_queue(), ^{ cblock(); // 調用也會crash });
定義一個nil的block,不管怎麼調用都會crash,不知道蘋果爲何沒有作保護,總之之後調用block以前仍是先判斷一下比較靠譜。
九、UIImagePickerController黑屏問題
使用UIImagePickerController完成拍照選取時,發如今iOS8上黑屏,其餘設備都正常。查了半天才發現原來測試在系統設置中把App的Camera權限關閉了,測試也沒有注意到這點。咱們一直覺得這是iOS 8beta版本的bug,找了半天才發現原來緣由很簡單。話說回來既然iOS7以後用戶能夠控制Camera的權限,那麼咱們的App能不能作的更好,更友好呢,因而查了一下資料發現AVFoundation庫提供了檢測Camera受權狀態的API,因此就有了下面這個函數。
代碼中顯示檢測系統是否支持拍照,而後在檢測App是否有拍照的權限,最後纔是進入拍照界面,防止模擬器調試拍照時Crash,或者真機調試權限關閉時出現的拍照界面一直黑屏的狀況。
十、xCode Archive出來的包在本地Organizer中看到的App沒有圖標的問題
xcassets的出現大大方便了咱們提供App中對應的icon等,使咱們不再用操心icon的各類繁瑣命名了,諸如Icon-57.png等。以前也碰到過由於未提供完整的icon致使App被拒的問題,如今這些問題基本上不存在。
昨天在Archive包之後看到本地Organizer中顯示的iPad竟然沒有圖標,再三檢查xcassets,發現全部icon都有,不該該有問題啊。後來查找資料發現這多是xCode的一個bug,本地顯示沒有圖標,可是裝到設備上一級提交到AppStore再下載下來都是有圖標的,不影響審覈和使用,純粹是顯示問題。
如何解決這個問題,檢查App中得xxx-info.plist文件中,添加Icon file屬性,並填上非retian和Retian屏幕對應的icon文件名稱(文件必須存在,且命名以下),以下圖所示:
再次Archive便可發現,本地的Organizerz中的App有icon了。