iOS开发中遇到过的坑

前言

做iOS开发这么长时间以来,遇到过不少难题,也踩过不少坑,本来没想过要写这篇文章,但是鉴于以下三点,笔者决定对遇到过的并且还能回忆起来的问题做个记录

  • 每次问题解决后,满满的成就感,但是当下一次再遇到时,又是一脸懵逼。这个问题我好像见过,但就是不记得怎么解决😏,记录下来方便以后查阅
  • 每次面试的时候,面试官总会问我,你在开发中遇到过哪些问题,怎么解决的?问题嘛,挺多的,但是你要我叙述嘛,我......我......我居然一时想不起来,迷之尴尬😂(面试官当时想法:一看就是个没工作经验伪造简历的),冤枉啊😱
  • 为遇到同样问题的开发者提供一个参考

那些遇到过的问题与踩过的坑

1.手机录音或通话时,app界面整体下移

当你的iphone在录音或者通话时,打开app你会发现,整个界面都下移了20像素,这个问题对于scrollView、tableView等可以垂直滚动的视图可能没有太大影响,但是对于那些不能滚动的视图,就有可能底部被遮盖20像素

笔者在网上查阅了资料,也试过多种方法,这个问题依然存在,最后笔者不得不使用大绝招来解决,何为大绝招?很简单,位置尺寸写死。项目中导航控制器是自定义的,在自定义的类中添加如下代码就OK了

2.点击导航栏下方也会触发导航栏按钮的点击事件

如图所示,每次想选中右上角的图片,结果总是触发“取消”事件,明明没有点到导航栏上面去,问题的原因不清楚,解决方法创建一个UINavigationBar的分类,重写hitTest方法

如果触摸点不在它上面,就不让它接收用户交互,然后使用系统的事件处理方法去处理

3.输入中文时限制字符长度

限制字母、数字、符号等其他非中文字符的长度大家应该都知道咋整,但如果是中文输入法,这就比较蛋疼了。举个例子,限制长度为5,输入“我爱写代码”,当已经输入“我爱写”两字,然后输入“代码”时就会出现如下情况

根本写不进去啊,这是为什么呢?因为输入的拼音也被计算在了字符串长度之内,导致输入“da”以后就不能继续输入了,可通过下面的办法解决

4.修改导航栏颜色

这个问题对有经验的开发者来说不是问题,但是当年笔者刚入行时,确实被这个问题折腾了好久。比如想设置导航栏的颜色为蓝色

self.navigationController.navigationBar.backgroundColor = [UIColor blueColor];

运行,然后......🤔这特么是蓝色?笔者确定自己不是色盲

后来才知道,设置导航栏的背景色,需要设置barTintColor而不是backgroundColor

self.navigationController.navigationBar.barTintColor = [UIColor blueColor];
5.界面莫名其妙下移

这个问题跟上面的问题一样,都是比较基础的问题,有经验的人都知道如何解决,但是笔者曾经也被折磨过

为什么下面textView的内容不是从最上面开始的,而且还不能滚上去,当初真的被这种情况折腾的死去活来的,改frame,改约束,都没效果。后来才知道,当有导航控制器时,系统会默认将第一个添加的scrollView或其子类视图的内容下移64个像素,下面的textView是先添加的,所以其内容被下移了,而上面的却没有,解决方法是在控制器里加上下面这句代码

self.automaticallyAdjustsScrollViewInsets = NO;
6.GCD组函数

笔者在开发中遇到过这样一个功能,某个界面列表上面是企业,下面是联系人,而且获取企业列表与联系人列表的接口不是同一个,必须等企业跟联系人列表数据都获取完毕后才能刷新,于是就用到了GCD组函数

然而问题来了,[[IBOSServer shared]...]这玩意儿是封装好的,并且是个异步函数,大家应该都知道,异步函数不会阻塞线程,不用等里面的内容执行完就返回了,这就导致数据还没拿到,就开始执行notify里面的代码了。后来笔者发现,原来GCD组函数还有一种用法,完美解决问题

7.UISearchController

iOS8才出来的,用来替换UISearchBar + UISearchDisplayController的组合方式,项目中有用到搜索功能,于是笔者就尝试着用了一下UISearchController,将搜索框添加到了tableView的tableHeaderView上。然而当点击搜索框准备搜索时,神奇的事情发生了

😳搜索框居然飞到九霄云外去了,好难过,这不是我要的那种结果,结果.....
怎么解决呢?在控制器里加上下面这句代码就OK了,至于为什么,呵呵😑,不知道

self.definesPresentationContext = YES;
8.自定义相机照片截取

这个问题说难不难,说简单也不简单,笔者当时确实花了很长一段时间才弄清楚,但是当问题解决后,感觉这特么也不复杂啊,之前怎么就没整明白呢

问题是这样的,在使用自定义相机拍完照后,需要对图片的指定区域(蓝色方框内的区域)进行截取然后上传,这里存在两个问题

  • 拍摄时你所看到的区域,跟实际拍出来的区域是不一样的

上图就是实际拍出来的图片,明显比拍摄时看到的图片要长,不过宽度是一样的

  • 照片的坐标系与我们平时开发所使用的坐标系是不一样的
    开发中所使用的视图坐标系是以左上角为原点的,横向为x轴,纵向为y轴,而拍摄出来的照片是以右上角为原点的,横向为y轴,纵向为x轴

我们先来看一幅图

由于拍摄时所看到视图宽高比与实际拍摄出来的图片的宽高比并不一致,所以导致图片经过等比例缩放到宽度一样时,高度有一部分超出了我们的可视范围,首先,我们要计算出超出部分的高度

//_cameraView为相机视图,即拍摄时看到图片的区域
CGFloat scale = image.size.width / _cameraView.width;//计算出缩放的比例
CGFloat showImageH = image.size.height / scale;//缩放后图片的高度
CGFloat offsetY = (showImageH - _cameraView.height) * 0.5;//上下超出的部分是相等的,所以*0.5得出上面超过的部分

超出部分的高度计算完后,我们就要来计算蓝色方框(_circleView,_cameraView的子控件)的坐标了

x:(offsetY+_circleView.y) * scale,别忘了乘以缩放比例
y:_circleView.x * scale,因为circleView在父控件中水平居中,所以_circleView在父控件中的x值乘以缩放比就是在图片坐标系中的y值
width:_circleView.height * scale
height:_circleView.width * scale

然后根据计算好的frame截取图片就ok了

CGRect rect = CGRectMake(x, y, width,height);
CGImageRef tailorImageRef = CGImageCreateWithImageInRect(photo.CGImage, rect);
UIImage *tailorImage = [UIImage imageWithCGImage:tailorImageRef];
9.修改cell侧滑按钮的颜色

想实现cell的侧滑功能很简单,实现tableView的代理方法就行了 ,但是系统提供的侧滑按钮的颜色貌似只有两种,一个红色一个灰色,那如果想修改为下图的蓝色呢?

当我们侧滑cell的时候,cell的状态会发生改变,就会触发cell的TransitionToState方法,那么我们在这个方法里就可以修改按钮的颜色了

如图所示,在这个方法里打印cell的subView会看到4个子视图,其中UITableViewCellDeleteConfirmationView就是侧滑按钮的父视图,然后循环遍历它的子视图,就能找到我们要修改颜色的按钮了

- (void)didTransitionToState:(UITableViewCellStateMask)state {
    for (UIView *subview in self.subviews) {
        if ([subview isKindOfClass:NSClassFromString(@"UITableViewCellDeleteConfirmationView")]) {
            for (UIButton *btn in subview.subviews) {
                NSString *title = [btn titleForState:UIControlStateNormal];
                if ([title isEqualToString:@"编辑"]) {
                    btn.backgroundColor = [UIColor colorWithRed:0.192 green:0.667 blue:0.969 alpha:1.000];
                }
            }
        }
    }
}
10.添加圆角的三种方式
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
imageView.image = [UIImage imageNamed:@"timg.jpeg"];

1.设置layer的cornerRadius

imageView.layer.cornerRadius = 100;
imageView.layer.masksToBounds = YES;

2.使用图形上下文绘制

UIGraphicsBeginImageContextWithOptions(imageView.frame.size, NO, [UIScreen mainScreen].scale);
[[UIBezierPath bezierPathWithRoundedRect:imageView.bounds cornerRadius:100] addClip];
//[imageView.layer renderInContext:UIGraphicsGetCurrentContext()];
[imageView drawRect:imageView.bounds];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
imageView.image = image;

3.设置layer的mask

UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:imageView.bounds cornerRadius:100];
CAShapeLayer *layer = [[CAShapeLayer alloc] init];
layer.path = path.CGPath;
imageView.layer.mask = layer;

使用bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii方法可以选择性的设置圆角

11.自定义UITextView的弹出菜单

只需要自定义UITextView,重写canPerformAction:withSender:方法即可

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    if (action == @selector(copy:)) {
        return YES;
    } else if (action == @selector(selectAll:)) {
        return YES;
    }
    return NO;
}

根据action来判断,需要出现在菜单上的返回yes,不需要的返回no

cut:剪切
copy:复制
paste:粘贴
selectAll:全选

12.图片压缩

方式一

UIImagePNGRepresentation(image);
UIImageJPEGRepresentation(image, 1); //第二个参数为压缩系数,取值范围为0-1

方式二:

//scale为缩放比例
CGSize size = CGSizeMake(image.size.width / scale, image.size.height / scale);
UIGraphicsBeginImageContext(size);
[image drawInRect:CGRectMake(0, 0, size.width, size.height)];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

结束语

遇到过的问题,远远不止上面这些,不过有些不记得了,以后遇到了再补上吧!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,614评论 4 59
  • 前言 由于最近两个多月,笔者正和小伙伴们忙于对公司新项目的开发,笔者主要负责项目整体架构的搭建以及功能模块的分工。...
    CoderMikeHe阅读 26,803评论 74 272
  • 时:或一日,下午。 地:或一地。 人: 老者——约六十左右,气色很好,但有点跛。 男子——约十岁,黑发,双眼有神。...
    怀双阅读 499评论 3 9
  • 牛奶可乐经济学 这本书从经济学的角度来思考这个社会,你会发现,一切皆是因为利益 马云内部讲话 讲述了阿里巴巴从创业...
    百里求一阅读 175评论 0 1
  • 今天我们不必讨论男人和女人之类话题,只是想通过朋友的角度谈谈我身边不一样状态的女性朋友。 现在这个...
    青海李云云阅读 383评论 0 0