好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

iOS开发中常见问题集锦

iOS开发中常见问题集锦

开发中常见问题集锦

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

1. 重复调用2次 loadView和viewDidLoad

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

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


下面的是错误代码:

  1  - ( void  )loadView {
   2       NSLog( @"  loadView  "  );
   3        //   隐藏状态栏 
  4       [UIApplication sharedApplication].statusBarHidden =  YES;
   5       
  6        //   .... 创建UIView 
  7       self.view =  [[[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds] autorelease];
   8       self.view.backgroundColor =  [UIColor grayColor];
   9    }
  10   
 11   - ( void  )viewDidLoad {
  12        [super viewDidLoad];
  13       NSLog( @"  viewDidLoad  "  );
  14   }

运行效果:


打印信息:

 1   2013 - 02 - 26   00 : 51 : 36.152  weibo[ 2251  :c07] loadView  
  2   2013 - 02 - 26   00 : 51 : 36.153  weibo[ 2251  :c07] loadView  
  3   2013 - 02 - 26   00 : 51 : 36.153  weibo[ 2251  :c07] viewDidLoad  
  4   2013 - 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; 

 

 

分类:  iOS开发基础

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于iOS开发中常见问题集锦的详细内容...

  阅读:42次