开发中常见问题集锦

来源:互联网 发布:多梦疲劳知乎 编辑:程序博客网 时间:2024/04/30 17:45

这篇文章是专门用来记录开发中一些常见的BUG以及常用的零碎知识点,我会隔一段时间更新内容

1.重复调用2次loadView和viewDidLoad

最好不要在UIViewController的loadView方法中改变状态栏的可视性(比如状态栏由显示变为隐藏、或者由隐藏变为显示),因为会导致重复调用2次loadView和viewDidLoad方法

假设状态栏本来是处于显示状态的:


下面的是错误代码:

- (void)loadView {    NSLog(@"loadView");    // 隐藏状态栏    [UIApplication sharedApplication].statusBarHidden = YES;        // .... 创建UIView    self.view = [[[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds] autorelease];    self.view.backgroundColor = [UIColor grayColor];}- (void)viewDidLoad {    [super viewDidLoad];    NSLog(@"viewDidLoad");}
运行效果:


打印信息:

2013-02-26 00:51:36.152 weibo[2251:c07] loadView2013-02-26 00:51:36.153 weibo[2251:c07] loadView2013-02-26 00:51:36.153 weibo[2251:c07] viewDidLoad2013-02-26 00:51:36.154 weibo[2251:c07] viewDidLoad

虽然运行效果是对的,但是系统连续调用了2次loadView和viewDidLoad方法,导致创建了2次UIView,造成了不必要的开销。

原因分析:

状态栏由显示变为隐藏,意味着屏幕的可用高度变长了,UIViewController的UIView的高度也要重新调整,因此系统会重新调用loadView方法创建UIView,创建完毕后再次调用viewDidLoad方法。


2.按钮无法点击

如果在UIImageView中添加了一个按钮,你会发现在默认情况下这个按钮是无法被点击的,需要设置UIImageView的userInteractionEnabled为YES:

imageView.userInteractionEnabled = YES;

设置为YES后,UIImageView内部的按钮就可以被点击了

原因分析:

• 当用户点击屏幕时,会产生一个触摸事件,系统会将该事件加入到一个由UIApplication管理的事件队列中

UIApplication会从事件队列中取出最前面的事件进行分发以便处理,通常,先发送事件给应用程序的主窗口(UIWindow)

主窗口会调用hitTest:withEvent:方法在视图(UIView)层次结构中找到一个最合适的UIView来处理触摸事件

(hitTest:withEvent:其实是UIView的一个方法,UIWindow继承自UIView,因此主窗口UIWindow也是属于视图的一种)

hitTest:withEvent:方法大致处理流程是这样的:

首先调用当前视图pointInside:withEvent:方法判断触摸点是否在当前视图内:

▶ 若pointInside:withEvent:方法返回NO,说明触摸点不在当前视图内,则当前视图hitTest:withEvent:返回nil

▶ 若pointInside:withEvent:方法返回YES,说明触摸点在当前视图内,则遍历当前视图的所有子视图(subviews),调用子视图hitTest:withEvent:方法重复前面的步骤,子视图的遍历顺序是从top到bottom,即从subviews数组的末尾向前遍历,直到有子视图hitTest:withEvent:方法返回非空对象或者全部子视图遍历完毕:

▷ 若第一次有子视图hitTest:withEvent:方法返回非空对象,则当前视图hitTest:withEvent:方法就返回此对象,处理结束

▷ 若所有子视图hitTest:withEvent:方法都返回nil,则当前视图hitTest:withEvent:方法返回当前视图自身(self)

最终,这个触摸事件交给主窗口的hitTest:withEvent:方法返回的视图对象去处理

我大致画了个iOS触摸事件分发的原理图:


hitTest:withEvent:方法会忽略以下视图:

1> 隐藏(hidden=YES)的视图

2> 禁止用户操作(userInteractionEnabled=NO)的视图

3> alpha<0.01的视图

4> 如果一个子视图的区域超过父视图的区域(如果父视图的clipsToBounds属性为NO,超过父视图区域的子视图内容也会显示),那么正常情况下在父视图区域外的触摸操作不会被识别,因为父视图的pointInside:withEvent:方法会返回NO,这样就不会继续向下遍历子视图了。当然,也可以重写pointInside:withEvent:方法来处理这种

综上所述可得:如果父视图的userInteractionEnabled=NO,触摸事件不会继续往下传递给子视图,所以子视图永远无法处理触摸事件。而UIImageView在默认情况下的userInteractionEnabled就是NO。


3.@2x和-568h@2x

于iOS设备的屏幕分辨率不尽相同,有大有小,那么在不同设备中显示同一张图片,可能会造成图片被拉伸、变形,严重影响用户体验。为了让图片在不同设备中都能得到很好的显示效果,同一类图片我们一般会准备3种版本,比如iOS程序在启动时会全屏显示的Default.png图片:

(Retina即视网膜屏幕)

• Default.png(图片尺寸为320x480):显示在非Retina-3.5英寸屏幕上(iPhone3G\iPhone3GS,屏幕分辨率为320x480)

• Default@2x.png(图片尺寸为640x960):显示在Retina-3.5英寸屏幕上(iPhone4\iPhone4s,屏幕分辨为640x960)

• Default-568h@2x.png(图片尺寸为640x1136):显示在Retina-4.0英寸屏幕上(iPhone5,屏幕分辨率为640x1136)


4.启动app时全屏显示Default.png

大部分app在启动过程中全屏显示一张背景图片,比如新浪微博会显示这张:


想在iOS中实现这种效果,毫无压力,非常地简单,把需要全屏显示的图片命名为Default.png即,在iOS app启动时默认会去加载并全屏显示Default.png

也可以用其他名称来命名图片,在Info.plist配置一下即可:

配置过后,app启动时就会去加载并全屏显示lufy.png


在默认情况下,app显示Default.png时并非真正的"全屏显示",因为顶部的状态栏并没有被隐藏,比如下面的效果:

大部分情况下,我们都想隐藏状态栏,让Default.png真正全屏显示。


说到这里,可能有人马上就想到了一种办法:在AppDelegate的application:didFinishLaunchingWithOptions:方法中添加如下代码:

[UIApplication sharedApplication].statusBarHidden = YES;
我只能说你的思路是对的,但实际上达不到想要的效果,你会发现显示Default.png时状态栏还是存在的,等Default.png显示完毕后,状态栏才被隐藏。

先解释下为什么这种方法不可行,其实原因很简单:

1> Default.png是在app启动过程中加载的,并不是在app启动完毕后再加载的

2> AppDelegate的application:didFinishLaunchingWithOptions:方法是在app启动完毕后才调用的


下面说一下解决方案,在Info.plist中增加一个配置即可:


这里的YES表示在app初始化(启动)的时候就隐藏状态栏。

当然,在Default.png显示完毕后状态栏还是隐藏的。如果想重新显示状态栏,补上下面代码即可:

[UIApplication sharedApplication].statusBarHidden = NO;

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 感冒一直流鼻涕该怎么办 婴儿一个月鼻塞怎么办 1岁婴儿感冒怎么办 轻微鼻塞感冒了怎么办 50天宝宝鼻塞怎么办 50天婴儿鼻塞怎么办 50天新生儿鼻塞怎么办 40天婴儿鼻塞怎么办 孩子感冒鼻子塞怎么办 月子里感冒了怎么办 宝宝感冒鼻塞严重怎么办 婴幼儿鼻塞有痰怎么办 感冒了浑身没劲怎么办 四个月宝宝鼻塞怎么办 四个月小孩鼻塞怎么办 小儿流清水鼻涕怎么办 小孩总是流鼻子怎么办 四个月小孩咳嗽怎么办 儿童流清水鼻涕怎么办 四个月婴儿发烧怎么办 宝宝体温36度怎么办 儿童感冒后鼻塞怎么办 儿童没感冒鼻塞怎么办 宝宝鼻塞怎么办3岁 儿童刚开始感冒鼻塞怎么办 婴儿感冒打喷嚏流鼻涕怎么办 宝宝感冒鼻涕多怎么办 一个多月的宝宝鼻塞怎么办 五个月宝宝鼻塞怎么办 4个月大婴儿鼻塞怎么办 四个月婴儿鼻塞怎么办 鼻炎晚上睡觉鼻塞怎么办 感冒了一直流鼻涕怎么办 感冒了鼻塞严重怎么办 两边鼻子都塞怎么办 感冒睡觉鼻子堵怎么办 孩子鼻炎流清水怎么办 小儿鼻涕流不停怎么办 老是单侧流鼻涕怎么办 有鼻炎光流鼻涕怎么办 一只鼻塞流鼻涕怎么办