iOS 工作遇到问题记录

1、UITableView的scrollDelegate问题

下午遇到一个奇怪的问题,之前都没有注意过,由于A VC中要实现tableView和其他View位置的联动,
所以实现了tableView的delegate中的scrollViewDidScroll方法,结果在点击商品push 商品详情VC B 的时候,问题出现了。

问题表现:
在调用[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 问题很奇怪,希望大家不再被同样的问题困扰

2、UIView的exclusiveTouch属性

通过设置[selfsetExclusiveTouch:YES];可以达到同一界面上多个控件接受事件时的排他性,从而避免一些问题。

3、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.

// 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.

4、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调用任何方法基本上都是安全的。

 5、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

6、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此方法,请君“且用且珍惜”。

7、UITextField当实现了textFieldDidBeginEditing方法以后, Clearbtn不响应,原因是最简单的view覆盖导致事件被拦截了

  如果必须实现delegate,则可以使用设置rightView的方式

  这个问题我最后解决了,说来都不好意思,被别的View盖住了,so出了问题还是得先思考一下是不是自己的问题。

  查这个问题得过程中,我找到一个很好用的GDB调试方法,直接在GDB中输入以下命令即可打印当前App的view层级。

po [[UIWindow keyWindow] recursiveDescription] 

  我知道网上有个收费的工具叫Reveal,可以更炫的查看view层级,好消息是xCode6 Debug自带了可查看view层级的功能。底层的实现机制也是一样,个人偏执的觉得还是命令行打印的更清晰,特别是view层级很多的时候。

8、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之前还是先判断一下比较靠谱。

9、UIImagePickerController黑屏问题

  使用UIImagePickerController完成拍照选取时,发现在iOS8上黑屏,其他设备都正常。查了半天才发现原来测试在系统设置中把App的Camera权限关闭了,测试也没有注意到这点。我们一直以为这是iOS 8beta版本的bug,找了半天才发现原来原因很简单。话说回来既然iOS7之后用户可以控制Camera的权限,那么我们的App能不能做的更好,更友好呢,于是查了一下资料发现AVFoundation库提供了检测Camera授权状态的API,所以就有了下面这个函数。

+ (void)takePhotoFromViewController:(UIViewController<UIImagePickerControllerDelegate, UINavigationControllerDelegate>*)controller
{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { if ([[AVCaptureDevice class] respondsToSelector:@selector(authorizationStatusForMediaType:)]) {
AVAuthorizationStatus authorizationStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if (authorizationStatus == AVAuthorizationStatusRestricted
|| authorizationStatus == AVAuthorizationStatusDenied) { // 没有权限
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil
message:@"Please enabled Camera Access (in Settings > Privacy > Camera)!"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alertView show];
return;
}
} UIImagePickerController *pickerController = [[UIImagePickerController alloc] init];
pickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
pickerController.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
pickerController.cameraFlashMode = UIImagePickerControllerCameraFlashModeAuto;
pickerController.cameraDevice = UIImagePickerControllerCameraDeviceRear;
pickerController.delegate = controller; [controller presentViewController:pickerController animated:YES completion:nil];
}
else {
// throw exception
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Warning"
message:@"The Device not support Camera"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
}

takePhoto

  代码中显示检测系统是否支持拍照,然后在检测App是否有拍照的权限,最后才是进入拍照界面,防止模拟器调试拍照时Crash,或者真机调试权限关闭时出现的拍照界面一直黑屏的情况。

10、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了。

注:记录iOS开发中遇到的奇葩的问题,随时更新。

  如果觉得本文帮到了你,请推荐给身边的朋友

  转载请著名出处,有什么问题欢迎留言

iOS 工作遇到问题记录的更多相关文章

  1. IOS客户端Coding项目记录导航

    IOS客户端Coding项目记录(一) a:UITextField设置出现清除按键 b:绘画一条下划线  表格一些设置 c:可以定义表头跟底部视图(代码接上面) d:隐藏本页的导航栏 e:UIEdge ...

  2. iOS工作小技巧及填坑记录

    以下是本人在iOS开发工作中使用的一些小技巧,记录一下. 1.使用XXX.pch文件便捷开发+加速Build 在IOS开发的项目中有一个XX_Prefix.pch XX_Prefix.pch:扩展名. ...

  3. 一年iOS工作经验,如何一举拿下百度、美团、快手等Offer面经(附面试题)

    前言: 先简单说说我最近的面试经历吧.面试的公司很多,大部分最后都能得到令人满意的结果,我将这些体会记录下来,面了这么多公司,如果不留下什么,那岂不是太浪费了.对于我来说,这也是一次自我检查,在这次面 ...

  4. 『IOS』 遇到问题记录(长期更新)

    遇到的很多问题,解决后都是自己记着,以为不会忘记,之后却会想不起来了. 所以把今后解决的问题记录在这. 一. 在二级页面设置了CAlayer的代理,在返回一级页面报错: EXC_BAD_ACCESS( ...

  5. 第一个APP上架IOS审核相关的记录

    以前一直没做过APP开发,第一版是用WAP版做的,采用了light7框架制作,没有UI设计. 升级到第二版之后,使用了HBUILDER的方式开发,https://dcloud.io/ 官方在这里. 目 ...

  6. iOS开发架构学习记录

    闲着没事看了一些iOS开发架构的视频,简单的介绍了几个常用的架构设计,现将它记录如下,以后有时间再专门写这方面的内容,大家可以看看,感兴趣的就进一步学习. 一.架构基础 1.架构设计的目的 进一步解耦 ...

  7. iOS 属性修饰符记录 --不定时更新

    重新审视了一下OC在属性修饰符,特意记录一下来.以后不定时更新 > retain:只有在非ARC下才会有效,所有如果在ARC下使用了retain修饰也白搭 如以下的data属性用retain修饰 ...

  8. IOS开发者账号申请记录

    1. 准备好一个企业邮箱 .企业营业执照复印件.一张可以支付的VISA或者MasterCard 2. 2016/01/13 注册appid https://developer.apple.com/pr ...

  9. iOS工作笔记(十三)

    1.automaticallyAdjustsScrollViewInsets的使用 这是UIViewController的属性,设置为YES就是根据status bar,navigation bar, ...

随机推荐

  1. python中的模块

    用python其实好久了,但是一直没有特别系统的学习过,当年迅速上手,也写了好多代码了,零零散散也学了很多知识点.到了把它们串起来的时候了.尝试记录一下系统整理的知识点,先从“模块”说起. 为什么需要 ...

  2. 关闭Outlook时最小化 dll

    用Outlook时最让我感觉不爽的就是不小心点了关闭按钮就会把Outlook关闭. 我们用软件的时候都希望软件有一个关闭时最小化功能,更希望Outlook也有这个功能 但让我很失望的是把设置里看了一个 ...

  3. TCP的三次握手和四次挥手

    置顶文章:<纯CSS打造银色MacBook Air(完整版)> 上一篇:<两个简单的Loading> 作者主页:myvin 博主QQ:851399101(点击QQ和博主发起临时 ...

  4. 小白学习mysql之存储过程的优劣分析以及接入控制

    存储过程的优劣 存储过程是一组实现特定功能的SQL语句集合,存储过程一经编译便存储在了服务器上,可以通过调用存储过程的名字以及传入相应的参数来使用存储过程.要高层次的掌握存储过程,不能觉得依葫芦画瓢, ...

  5. c# r3 inline hook

    前言 老婆喜欢在QQ游戏玩拖拉机,且安装了一个记牌器小软件,打开的时候弹出几个IE页面加载很多广告,于是叫我去掉广告.想想可以用OD进行nop填充,也可以写api hook替换shellexecute ...

  6. 微信支付开发-Senparc.Weixin.MP详解

    年底了,反而工作更忙了,我从15年11月开始写<1024伐木累>系列小说和爆笑对白,得到了很多身边的技术好友的支持,现在爆笑对白已经有越来越多的朋友一起帮着写段子,整理,包括小说内容的编辑 ...

  7. 让C#开发更简单,抽象增删改

    相信经常做一些MS,CRM 项目的童鞋非常有体会,大部分时间都是在复制和粘贴,大部分项目框架都是建一个三层,首先是DAL建一些增删改查,然后呢是BLL业务层再建一些增删改查,然后UI层再调用增删改查, ...

  8. ASP.NET MVC系列 框架搭建(一)之仓储层的搭建

    大神勿喷,小神默默学. 会了就是不值一提的东西,不会就是绝对的高大上. 最后上传源码.希望能给读者带来一些新的认识及知识. 还没上过头条..各位大神,请点支持一下小弟. 陆续更新.更新到你会为止!! ...

  9. nginx的笔记

    nginx 的安装 下载地址: http://nginx.org/download/nginx-1.4.2.tar.gz 安装准备: nginx依赖于pcre库,要先安装pcre yum instal ...

  10. css的小三角实现的方式

    先上一个简单的例子哈: 此时的方向向下. 如果想方向向上的话用:border-top:0;border-bottom:4px solid; 1. width:0 height:0 border宽度,颜 ...