viewWillAppear:视图即将可见时调用。默认状况下不执行任何操做css
viewDidAppear:视图已彻底过渡到屏幕上时调用java
viewWillDisappear:视图被驳回时调用,覆盖或以其余方式隐藏。默认状况下不执行任何操做ios
viewDidDisappear:视图被驳回后调用,覆盖或以其余方式隐藏。默认状况下不执行任何操做loadView; .这是当他们没有正在使用nib视图页面,子类将会建立本身的自定义视图层。毫不能直接调用。web
viewDidLoad:在视图加载后被调用,若是是在代码中建立的视图加载器,他将会在loadView方法后被调用,若是是从nib视图页面输出,他将会在视图设置好后后被调用。面试
「initWithNibName: bundle:」载入nib档案来初始化「loadView」载入视图「viewDidLoad」在载入视图至内存后会呼叫的方法「viewDidUnload」在视图从内存中释放后会呼叫的方法 (当内存太低,释放一些不须要的视图时调用)算法
「viewWillAppear」当收到视图在视窗将可见时的通知会呼叫的方法编程
「viewDidAppear」当收到视图在视窗已可见时的通知会呼叫的方法数组
「viewWillDisappear」当收到视图将去除、被覆盖或隐藏于视窗时的通知会呼叫的方法浏览器
「viewDidDisappear」当收到视图已去除、被覆盖或隐藏于视窗时的通知会呼叫的方法缓存
「didReceiveMemoryWarning」收到系统传来的内存警告通知后会执行的方法
「shouldAutorotateToInterfaceOrientation」是否支持不一样方向的旋转视图
「willAnimateRotationToInterfaceOrientation」在进行旋转视图前的会执行的方法(用于调整旋转视图之用)
代码的执行顺序
一、 alloc 建立对象,分配空间
二、init (initWithNibName) 初始化对象,初始化数据
三、loadView 从nib载入视图 ,一般这一步不须要去干涉。除非你没有使用xib文件建立视图
四、viewDidLoad 载入完成,能够进行自定义数据以及动态建立其余控件
五、viewWillAppear 视图将出如今屏幕以前,立刻这个视图就会被展示在屏幕上了
六、viewDidAppear 视图已在屏幕上渲染完成当一个视图被移除屏幕而且销毁的时候的执行顺序,这个顺序差很少和上面的相反
一、viewWillDisappear 视图将被从屏幕上移除以前执行
二、viewDidDisappear 视图已经被从屏幕上移除,用户看不到这个视图了
三、dealloc 视图被销毁,此处须要对你在init和viewDidLoad中建立的对象进行释放
- 先添加所需子控件 - 再接收模型数据根据模型数据设置子控件数据和位置 - 简而言之, 本身的事情本身作, 把不须要暴露出去的封装起来
程序启动分为两类:1.有storyboard 2.没有storyboard 有storyboard状况下: 1.main函数 2.UIApplicationMain * 建立UIApplication对象 * 建立UIApplication的delegate对象 3.根据Info.plist得到Main.storyboard的文件名,加载Main.storyboard(有storyboard) * 建立UIWindow * 建立和设置UIWindow的rootViewController * 显示窗口 没有storyboard状况下: 1.main函数 2.UIApplicationMain * 建立UIApplication对象 * 建立UIApplication的delegate对象 3.delegate对象开始处理(监听)系统事件(没有storyboard) * 程序启动完毕的时候, 就会调用代理的application:didFinishLaunchingWithOptions:方法 * 在application:didFinishLaunchingWithOptions:中建立UIWindow * 建立和设置UIWindow的rootViewController * 显示窗口
iOS中不存在缓存池满的状况,由于一般咱们ios中开发,对象都是在须要的时候才会建立,有种经常使用的说话叫作懒加载,还有在UITableView中通常只会建立刚开始出如今屏幕中的cell,以后都是从缓存池里取,不会在建立新对象。缓存池里最多也就一两个对象,缓存池满的这种状况通常在开发java中比较常见,java中通常把最近最少使用的对象先释放。
继承结构,属于内部的子控件结构
UIButton为:UIButton > UIControl > UIView > UIResponder > NSObject
UITableView为:UITableView > UIScrollView > UIView > UIResponder > NSObject
通常状况下能够设置在viewDidLoad中,但在autolayout下,系统会在viewDidAppear以前根据subview的constraint从新计算scrollview的contentsize。 这就是为何,在viewdidload里面手动设置了contentsize没用。由于在后面,会再从新计算一次,前面手动设置的值会被覆盖掉。
解决办法就是:
去除autolayout选项,本身手动设置contentsize
若是要使用autolayout,要么本身设置完subview的constraint,而后让系统自动根据constraint计算出contentsize。要么就在viewDidAppear里面本身手动设置contentsize。
UIView: 属于UIkit.framework框架,负责渲染矩形区域的内容,为矩形区域添加动画,响应区域的触摸事件,布局和管理一个或多个子视图
UIWindow:属于UIKit.framework框架,是一种特殊的UIView,一般在一个程序中只会有一个UIWindow,但能够手动建立多个UIWindow,同时加到程序里面。UIWindow在程序中主要起到三个做用:
做为容器,包含app所要显示的全部视图
传递触摸消息到程序中view和其余对象
与UIViewController协同工做,方便完成设备方向旋转的支持
CAlayer:属于QuartzCore.framework,是用来绘制内容的,对内容进行动画处理依赖与UIView来进行显示,不能处理用户事件。
UIView和CALayer是相互依赖的,UIView依赖CALayer提供内容,CALayer依赖UIView的容器显示绘制内容。
frame指的是:该view在父view坐标系统中的位置和大小(参照点是父亲的坐标系统)
bounds指的是:该view在自己坐标系统中的位置和大小(参照点是自己坐标系统)
属性传值:A页面设置属性 NSString *paramString,在跳转B页面的时候初始化paramString。 //A页面.h文件 @property (nonatomic, copy)NSString *paramString; //A页面.m文件 NextViewController *nextVC = [[NextViewController alloc] init]; nextVC.paramString = @"参数传质"; [self presentViewController:nextVC animated:YES completion:nil]; 委托delegate传值:在B页面定义delegate,而且设置delegate属性,在A页面实现delegate协议 通知notification传值:在B页面中发送通知,在A页面注册观察者而且在不用的时候移除观察者。 //B页面发送通知 [[NSNotificationCenter defaultCenter] postNotificationName:@"ChangeNameNotification" object:self userInfo:@{@"name":self.nameTextField.text}]; [self dismissViewControllerAnimated:YES completion:nil]; //A页面注册观察者 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(ChangeNameNotification:) name:@"ChangeNameNotification" object:nil]; } //观察到通知时候的处理方法 -(void)ChangeNameNotification:(NSNotification*)notification{ NSDictionary *nameDictionary = [notification userInfo]; self.nameLabel.text = [nameDictionary objectForKey:@"name"]; } //通知不使用的时候移除观察者 [[NSNotificationCenter defaultCenter] removeObserver:self]; block传值:在B页面定义一个block类型的变量,在B页面跳转A的时候调用这个block。在A页面跳转到B页面的时候对B页面的block赋值。 //B页面定义block,并设置block类型的变量 typedef void (^ablock)(NSString *str); @property (nonatomic, copy) ablock block; //B页面跳转到A页面调用这个block self.block(self.nameTextField.text); [self dismissViewControllerAnimated:YES completion:nil]; //A页面跳转到B页面的时候对B页面的block赋值,这样在B页面跳转的时候就会回调这个block函数 [self presentViewController:second animated:YES completion:nil]; second.block = ^(NSString *str){ self.nameLabel.text = str; }; kvo传值:在A页面设置B页面的变量second,而且对这个变量进行观察 - (void)addObserver:(NSObject * _Nonnull)anObserver forKeyPath:(NSString * _Nonnull)keyPath options:(NSKeyValueObservingOptions)options context:(void * _Nullable)context 并在A页面实现 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context方法。 在B页面对变量keyPath进行设置,在A页面都会观察的到。 @property (nonatomic, strong) SecondViewController *second; //在A视图跳转到B视图的地方添加以下代码 self.second = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil]; [self.second addObserver:self forKeyPath:@"userName" options:NSKeyValueObservingOptionNew context:nil]; [self presentViewController:self.second animated:YES completion:nil]; //实现这个观察对象的方法 -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context //在B页面对userName进行设置,在A页面均可以间听到 单例模式传值:经过全局的方式保存 对于通知代理面试常问, 代理和通知分别在什么状况下使用? 区别? 各自优势?
首先判断控制器是否有视图,若是没有就调用loadView方法建立:经过storyboard或者代码;
随后调用viewDidLoad,能够进行下一步的初始化操做;只会被调用一次;
在视图显示以前调用viewWillAppear;该函数能够屡次调用;
视图viewDidAppear
在视图显示以前调用viewWillDisappear;该函数能够屡次调用;如须要);
在布局变化先后,调用viewWill/DidLayoutSubviews处理相关信息;
视图生命周期图
事件响应链。包括点击事件,画面刷新事件等。在视图栈内从上至下,或者从下之上传播. 能够说点事件的分发,传递以及处理。具体能够去看下touch事件这块。
首先解释响应者链的概念
UIResponder类,是UIKIT中一个用于处理事件响应的基类。窗口上的全部事件触发,都由该类响应(即事件处理入口)。因此,窗口上的View及控制器都是派生于该类的,例如UIView、UIViewController等。
调用UIResponder类提供的方法或属性,咱们就能够捕捉到窗口上的全部响应事件,并进行处理。
响应者链条是由多个响应者对象链接起来的链条,其中响应者对象是能处理事件的对象,全部的View和ViewController都是响应者对象,利用响应者链条能让多个控件处理同一个触摸事件.
事件传递机制
若是当前view不能处理当前事件,那么事件将会沿着响应者链(Responder Chain)进行传递,知道遇到能处理该事件的响应者(Responsder Object)。
- 接收事件的initial view若是不能处理该事件而且她不是顶层的View,则事件会往它的父View进行传递。 - initial view的父View获取事件后若是仍不能处理,则继续往上传递,循环这个过程。若是顶层的View仍是不能处理这个事件的话,则会将事件传递给它们的ViewController, - 若是ViewController也不能处理,则传递给Window(UIWindow),此时Window不能处理的话就将事件传递UIApplication,最后若是连Application也不能处理,则废弃该事件
viewDidLoad在view从nib文件初始化时调用,
loadView在controller的view为nil时调用。
此方法在编程实现view时调用, view控制器默认会注册memory warning notification,当viewcontroller的任何view没有用的时候,viewDidUnload会被调用,在这里实现将retain的view release,若是是retain的IBOutlet view属性则不要在这里release,IBOutlet会负责release。
查看UITableView头文件,会找到NSMutableArray visiableCells,和NSMutableArrayreusableTableCells两个结构。
visiableCells内保存当前显示的cells,reusableTableCells保存可重用的cells。
TableView显示之初,reusableTableCells为空,那么
[tableView dequeueReusableCellWithIdentifier:CellIdentifier]返回nil。
开始的cell都是经过 [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] 来建立,并且cellForRowAtIndexPath只是调用最大显示cell数的次数。 好比:有100条数据,iPhone一屏最多显示10个cell。
程序最开始显示TableView的状况是:
用[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]建立10次cell,并给cell指定一样的重用标识(固然,能够为不一样显示类型的cell指定不一样的标识)。而且10个cell所有都加入到visiableCells数组,reusableTableCells为空。
向下拖动tableView,当cell1彻底移出屏幕,而且cell11(它也是alloc出来的,缘由同上)彻底显示出来的时候。cell11加入到visiableCells,cell1移出visiableCells,cell1加入到reusableTableCells。
接着向下拖动tableView,由于reusableTableCells中已经有值,因此,当须要显示新的cell, cellForRowAtIndexPath再次被调用的时候,[tableView dequeueReusableCellWithIdentifier:CellIdentifier],返回cell1。 cell1加入到visiableCells,cell1 移出reusableTableCells;cell2移出 visiableCells,cell2加入到reusableTableCells。以后再须要显示的Cell就可 以正常重用了.
注意:配置Cell的时候必定要注意,对取出的重用的cell作从新赋值,不要遗留老数据。
实际上针对性地优化一下就能够解决tableView滑动的时候卡顿的问题:
使用不透明视图。不透明的视图能够提升渲染的速度。能够将cell及其子视图的opaque属性设为YES(默认值)。
不要重复建立没必要要的cell。UITableView只须要一屏幕的UITableViewCell对象便可。所以在cell不可见时,能够将其缓存起来,而在须要时继续使用它便可。注意:cell被重用时,须要调用setNeedsDisplayInRect:或setNeedsDisplay方法重绘cell。
减小动画效果的使用,最好不要使用insertRowsAtIndexPaths:withRowAnimation:方法,而是直接调用reloadData方法。
减小视图的数目。Cell包含了textLabel、detailTextLabel和imageView等view,而你还能够自定义一些视图放在它的contentView里,建立它会消耗较多资源,而且也影响渲染的性能。
cell包含图片,且数目较多,使用自定义的cell速度会比使用默认的要快。继承UITableViewCell,重写drawRect方法:- (void)drawRect:(CGRect)rect { if (image) { [image drawAtPoint:imagePoint]; self.image = nil; } else { [placeHolder drawAtPoint:imagePoint]; } [text drawInRect:textRect withFont:font lineBreakMode:UILineBreakModeTailTruncation]; }
不过这样一来,你会发现选中一行后,这个cell就变蓝了,其中的内容就被挡住了。最简单的方法就是将cell的selectionStyle属性设为UITableViewCellSelectionStyleNone,这样就不会被高亮了。
-不须要与用户交互时,使用CALayer,将内容绘制到layer上,而后对cell的contentView.layer调用addSublayer:方法。这个例子中,layer并不会显著影响性能,但若是layer透明,或者有圆角、变形等效果,就会影响到绘制速度了。解决办法可参见后面的预渲染图像。
不要作多余的绘制工做。在实现drawRect:的时候,它的rect参数就是须要绘制的区域,这个区域以外的不须要进行绘制。
预渲染图像。你会发现即便作到了上述几点,当新的图像出现时,仍然会有短暂的停顿现象。解决的办法就是在图形上下文中画,导出成UIImage对象,而后再绘制到屏幕。(头像圆角,或者其余变形的时候,用图形上下文能提升性能。)异步绘制
不要阻塞主线程。tableview在更新数据时,整个界面卡住不动,彻底不响应用户请求。常见的是网络请求,等待时间长待数秒。
解决方案:使用多线程,让子线程去执行这些函数或方法。
注意:当下载线程数超过2时,会显著影响主线程的性能。因此在不须要响应用户请求时,下载线程数能够增长到5,不建议再加了,以加快下载速度。若是用户正在交互,应把线程数量控制在2个之内。
提早计算并缓存好高度,由于heightforrowatindexpath调用很是频繁
选择正确的数据结构:学会选择对业务场景最合适的数组结构是写出高效代码的基础。好比,数组: 有序的一组值。使用索引来查询很快,使用值查询很慢,插入/删除很慢。字典: 存储键值对,用键来查找比较快。集合: 无序的一组值,用值来查找很快,插入/删除很快。
思路同网易新闻相似,用自定义的继承自UITableViewCell的类,在initWithFrame的构造方法中, 初始化自定义的继承自UICollectionView的类
以tableView的上拉刷新为例:
为了进行无缝阅读, 经过tableView的代理方法, willDisplayCell判断是不是最后一行,
若是是最后一行, 在显示最后一行的同时, 判断当前是否存在上拉刷新
若是当前没有上拉刷新, 就进行加载数据, 启动小菊花转啊转。
以tableView的下拉刷新为例:
判断当前的上拉刷新视图是否动画
若是没有动画, 就不是上拉刷新
而后下拉刷新加载数据
加载完毕数据关闭刷新
若是但愿每条数据显示自身的行高, 必须设置两个属性, 1.预估行高, 2.自定义行高
设置预估行高 tableView.estimatedRowHeight = 200
设置定义行高 tableView.rowHeight = UITableViewAutomaticDimension
若是要让自定义行高有效, 必须让容器视图有一个自下而上的约束
iOS开发中webview和native code的配合上的一些经验和技巧。
webview与运维成本低,更新几乎不依赖App的版本;但在交互和性能上与跟native code有很大差距。
native code与之对应。
HTML5确实给web带入了一个新时代。这个时代是什么,web app。也就是说,只有脱离native的这个前提,在浏览器的环境下,HTML5的意义才能显现,而咱们讨论iOS App的时候,HTML5显然没什么意义。
无论是用webview仍是native code,两个原则:
用户体验不打折
运维成本低
为何不提开发成本。由于作web开发和iOS开发根本就是两回事。固然,web开发发展了这么多年,对于某些功能实现是要比native app快。但多数状况,同一个功能,对于iOS开发者和web开发者,用各自擅长的方式开发成本都最低,因此说某个功能开发成本低,每每是一个伪命题。
刚刚说了,webview的优点在于更新不依赖版本,那么在一款App中,只有会频繁更新的界面考虑webview才有意义。那么哪些界面会频繁更新,这就要因App而异了。
首页。首页资源可谓必争之地,内容一天一换是正常现象,一天几换也不稀奇。而若是仅仅是内容的更换,非要上个webview就显得有些激进了。而事实上首页的变化千奇百怪,逢年过节变个脸,特殊状况挂个公告,偶尔还要特批强推一把某个业务,等等。此前,我在设计App首页的时候,把首页配置设计的很是复杂。App端要处理n种状况,n各参数,server端要记住n种规则,直到一天,我崩溃了,把首页彻底换成webview,才豁然开朗。
活动页。作互联网都知道,活动,是一个最多见的运营手段。特色是,周期短,功能少,但基本不能复用。这些特色都标识了活动不适合作native,要用webview实现。即便有人告诉你说,个人活动是一个长期活动并且形式不变,也不要相信他。由于在第二期,第三期,第四期他会分别加上一些很是诡异,却有很合理的小变动,而这些变动是你在那个版本根本没法实现的。
试水的新功能。这种界面,每每设计不成熟,须要在运行过程当中不断收集用户反馈,更新升级,甚至决定去留。因此,只有webview才能hold住如此不稳定的功能。切记在一个功能尚未肯定以前,不要大张旗鼓单位开发native code,要知道,你写的这些代码,三天后就要改一遍,并且要发布上线。
富文本内容。这个不用多说了吧,按照HTML的经常使用标签作一个webtext可不是小工程。并且富文本的变化太多了,一点没法匹配,都会致使整个界面巨丑。
OK,上边说了我认为最该使用webview的4个界面,分别带有不一样的特色,但webview的交互是个短板,所以webview在一个App中,只能做为界面,不容许在界面中出现动做。而一个webview的界面如何跟native code结合起来呢,个人答案是,超连接。在webview上点击超连接,会调用webview delegate的shouldload方法,自这里拦截请求,进行处理。因为webview的连接都是URL,所以我建议,把整个App的界面都用URL管理起来。
长相问题,webview很难长成native的view。方案:长不成也要装成。在一些状况下,禁用webview滚动,使用滚动框架(iScroll不错)去实现。webview上下留出200pixel的空白背景,y从-200开始。不然你们知道,webview上下会有阴影的背景,不藏起来会很丑。等等,还有不少其余的方法去假装webview,是要视情景而用。
cell中嵌套webview,在oc中调用js获取web的高度, CGFloat height = [[self.webView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight"] floatValue];在经过webViewDidFinishLoad里面更新行高。
我对UIScrollView的理解是frame就是他的contentSize,bounds就是他的可视范围,经过改变bounds从而达到让用户误觉得在滚动,如下是一个简单的UIScrollView实现
第二个问题我的理解是解决手势冲突,对本身添加的手势进行捕获和响应
// 让UIScrollView遵照UIGestureRecognizerDelegate协议,实现这个方法,在这里方法里对添加的手势进行处理就能够解决冲突
animateWithDuration:这就等于建立一个定时器 animations:这是建立定时器须要实现的SEL completion:是定时器结束之后的一个回调block
imgData = UIImageJPEGRepresentation(image, 0.6f)
[tableView deselectRowAtIndexPath:indexPath animated:TRUE]; // 重点是这2句代码实现的功能 [tableView beginUpdates]; [tableView endUpdates];
自定义一个UIView的子类
//提供一个成员属性,接收下载进度值 @property (nonatomic, assign) CGFloat progress;
重写成员属性progress的setter
//每次改变成员属性progress的值,就会调用它的setter -(void)setProgress:(CGFloat)progress { _progress = progress; //当下载进度改变时,手动调用重绘方法 [self setNeedsDisplay]; }
重写
-(void)drawRect:(CGRect)rect(核心) -(void)drawRect:(CGRect)rect { //设置圆弧的半径 CGFloat radius = rect.size.width * 0.5; //设置圆弧的圆心 CGPoint center = CGPointMake(radius, radius); //设置圆弧的开始的角度(弧度制) CGFloat startAngle = - M_PI_2; //设置圆弧的终止角度 CGFloat endAngle = - M_PI_2 + 2 * M_PI * self.progress; //使用UIBezierPath类绘制圆弧 UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius - 5 startAngle:startAngle endAngle:endAngle clockwise:YES]; //将绘制的圆弧渲染到图层上(即显示出来) [path stroke]; }
经过UIImageView显示动画效果,其实是把动态的图拆成了一组静态的图,放到数组中,播放的时候依次从数组中取出。若是播放的图片比较少占得内存比较小或者比较经常使用(好比工具条上一直显示的动态小图标),能够选择用imageNamed:方式获取图片,可是经过这种方式加到内存中,使用结束,不会本身释放,屡次播放动画会形成内存溢出问题。所以,对于大图或常常更换的图,在取图片的时候能够选择imageWithContentsOfFile:方式获取图片,优化内存。
使用UIWebView显示图片须要注意显示图片的尺寸与UIWebView尺寸的设置,若是只是为了显示动态图片,能够禁止UIWebView滚动。在显示动态图片的时候,即便是动图的背景处为透明,默认显示出来是白色背景,这个时候须要手动设置UIWebView的透明才能达到显示动图背景透明的效果。
- XIB:在编译前就提供了可视化界面,能够直接拖控件,也能够直接给控件添加约束,更直观一些,并且类文件中就少了建立控件的代码,确实简化很多,一般每一个XIB对应一个类。 - Storyboard:在编译前提供了可视化界面,可拖控件,可加约束,在开发时比较直观,并且一个storyboard能够有不少的界面,每一个界面对应一个类文件,经过storybard,能够直观地看出整个App的结构。 - XIB:需求变更时,须要修改XIB很大,有时候甚至须要从新添加约束,致使开发周期变长。XIB载入相比纯代码天然要慢一些。对于比较复杂逻辑控制不一样状态下显示不一样内容时,使用XIB是比较困难的。当多人团队或者多团队开发时,若是XIB文件被发动,极易致使冲突,并且解决冲突相对要困难不少。 - Storyboard:需求变更时,须要修改storyboard上对应的界面的约束,与XIB同样可能要从新添加约束,或者添加约束会形成大量的冲突,尤为是多团队开发。对于复杂逻辑控制不一样显示内容时,比较困难。当多人团队或者多团队开发时,你们会同时修改一个storyboard,致使大量冲突,解决起来至关困难。
当程序访问了控制器的View属性时会先判断控制器的View是否存在,若是存在就直接返回已经存在的View; 若是不存在,就会先调用loadView这个方法;若是控制器的loadView方法实现了,就会按照loadView方法加载自定义的View; 若是控制器的loadView方法没有实现就会判断storyboard是否存在; 若是storyboard存在就会按照storyboard加载控制器的View;若是storyboard不存在,就会建立一个空视图返回。
1.执行Main 2.执行UIApplicationMain函数. 3.建立UIApplication对象,并设置UIApplicationMain对象的代理. UIApplication的第三个参数就是UIApplication的名称,若是指定为nil,它会默认为UIApplication. UIApplication的第四个参数为UIApplication的代理. 4.开启一个主运行循环.保证应用程序不退出. 5.加载info.plist.加载配置文件.判断一下info.plist文件当中有没有Main storyboard file base name里面有没有指定storyboard文件,若是有就去加载info.plist文件,若是没有,那么应用程序加载完毕.
在产生一个事件时,系统会将该事件加入到一个由UIApplication管理的事件队列中, UIApplication会从事件队列中取出最前面的事件,将它传递给先发送事件给应用程序的主窗口. 主窗口会调用hitTest方法寻找最适合的视图控件,找到后就会调用视图控件的touches方法来作具体的事情. 当调用touches方法,它的默认作法, 就会将事件顺着响应者链条往上传递, 传递给上一个响应者,接着就会调用上一个响应者的touches方法
A target-action:当两个对象之间有⽐较紧密的关系时,如视图控制器与其下的某个视图。
B delegate:当某个对象收到多个事件,并要求同一个对象来处理全部事件时。委托机制必须依赖于某个协议定义的⽅法来发送消息。
C NSNotification:当须要多个对象或两个无关对象处理同一个事件时。 D Block:适⽤于回调只发⽣生一次的简单任务。 参考答案:B
imgView.layer.cornerRadius = 10; // 这一行代码是很消耗性能的 imgView.clipsToBounds = YES;
- (UIImage *)hyb_imageWithCornerRadius:(CGFloat)radius { CGRect rect = (CGRect){0.f, 0.f, self.size}; UIGraphicsBeginImageContextWithOptions(self.size, NO, UIScreen.mainScreen.scale); CGContextAddPath(UIGraphicsGetCurrentContext(), [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius].CGPath); CGContextClip(UIGraphicsGetCurrentContext()); [self drawInRect:rect]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; }
而后调用时就直接传一个圆角来处理:
imgView.image = [[UIImage imageNamed:@"test"] hyb_imageWithCornerRadius:4];
这么作就是on-screen-rendering了,经过模拟器->debug->Color Off-screen-rendering看到没有离屏渲染了!(黄色的小圆角没有显示了,说明这个不是离屏渲染了)
- (void)drawRect:(CGRect)rect { CGRect bounds = self.bounds; [[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:8.0] addClip]; [self.image drawInRect:bounds]; }
这个问题有不少种方式,并且不一样的使用场景也不同的。好比说: • 第一种:若是是点击某个按钮后,才会刷新它的值,其它不用修改,那么不用引用任何按钮,直接在回调时,就已经将接收响应的按钮给传过来了,直接经过它修改便可。 • 第二种:点击某个按钮后,全部与之同类型的按钮都要修改值,那么能够经过在建立按钮时将按钮存入到数组中,在须要的时候遍历查找。
controller layout触发的时候,开发者有机会去从新layout本身的各个subview。
横竖屏切换的时候,系统会响应一些函数,其中 viewWillLayoutSubviews 和 viewDidLayoutSubviews。
- (void)viewWillLayoutSubviews { [self _shouldRotateToOrientation:(UIDeviceOrientation)[UIApplication sharedApplication].statusBarOrientation]; } -(void)_shouldRotateToOrientation:(UIDeviceOrientation)orientation { if (orientation == UIDeviceOrientationPortrait ||orientation == UIDeviceOrientationPortraitUpsideDown) { // 竖屏 } else { // 横屏 } } 经过上述一个函数就知道横竖屏切换的接口了。 注意:viewWillLayoutSubviews只能用在ViewController里面,在view里面没有响应。
答:首先咱们从代码来看,数据源如何关联上的,实际上是在数据源关联的代理方法里实现的。 所以咱们并不关心如何去关联他,他怎么关联上,方法只是让我返回根据本身的须要去设置如相关的数据源。 所以,我以为能够设置多个数据源啊,可是有个问题是,你这是想干吗呢?想让列表如何显示,不一样的数据源分区块显示?
CocoaTouch框架中用到了大量委托,其中UITableViewDelegate就是委托机制的典型应用,是一个典型的使用委托来实现适配器模式,其中UITableViewDelegate协议是目标,tableview是适配器,实现UITableViewDelegate协议,并将自身设置为talbeview的delegate的对象,是被适配器,通常状况下该对象是UITableViewController。 UITableVIew的Data Source方法有- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
答:iPhone OS 应用程序的基础 Cocoa Touch 框架重用了许多 Mac 系统的成熟模式,可是它更多地专一于触摸的接口和优化。
UIKit 为您提供了在 iPhone OS 上实现图形,事件驱动程序的基本工具,其创建在和 Mac OS X 中同样的 Foundation 框架上,包括文件处理,网络,字符串操做等。
Cocoa Touch 具备和 iPhone 用户接口一致的特殊设计。有了 UIKit,您可使用 iPhone OS 上的独特的图形接口控件,按钮,以及全屏视图的功能,您还可使用加速仪和多点触摸手势来控制您的应用。
各色俱全的框架 除了UIKit 外,Cocoa Touch 包含了建立世界一流 iPhone 应用程序须要的全部框架,从三维图形,到专业音效,甚至提供设备访问 API 以控制摄像头,或经过 GPS 获知当前位置。
Cocoa Touch 既包含只须要几行代码就能够完成所有任务的强大的 Objective-C 框架,也在须要时提供基础的 C 语言 API 来直接访问系统。这些框架包括:
Core Animation:经过 Core Animation,您就能够经过一个基于组合独立图层的简单的编程模型来建立丰富的用户体验。
Core Audio:Core Audio 是播放,处理和录制音频的专业技术,可以轻松为您的应用程序添增强大的音频功能。
Core Data:提供了一个面向对象的数据管理解决方案,它易于使用和理解,甚至可处理任何应用或大或小的数据模型。
功能列表:框架分类
下面是 Cocoa Touch 中一小部分可用的框架:
音频和视频:Core Audio ,OpenAL ,Media Library ,AV Foundation
数据管理 :Core Data ,SQLite
图形和动画 :Core Animation ,OpenGL ES ,Quartz 2D
网络:Bonjour ,WebKit ,BSD Sockets
用户应用:Address Book ,Core Location ,Map Kit ,Store Kit
File’s Owner 是全部 nib 文件中的每一个图标,它表示从磁盘加载 nib 文件的对象;
First Responder 就是用户当前正在与之交互的对象;
View 显示用户界面;完成用户交互;是 UIView 类或其子类。
-[AppDelegate application:willFinishLaunchingWithOptions:] -[AppDelegate application:didFinishLaunchingWithOptions:] -[AppDelegate applicationDidBecomeActive:]
退到后台:
-[AppDelegate applicationWillResignActive:] -[AppDelegate applicationDidEnterBackground:]
回到前台:
-[AppDelegate applicationWillEnterForeground:] -[AppDelegate applicationDidBecomeActive:]
ViewController之间,
加载页面:
-[mainViewController viewDidLoad] -[mainViewController viewWillAppear:] -[mainViewController viewWillLayoutSubviews] -[mainViewController viewDidLayoutSubviews] -[mainViewController viewDidAppear:]
退出当前页面:
-[mainViewController viewWillDisappear:] -[mainViewController viewDidDisappear:]
返回以前页面:
-[mainViewController viewWillAppear:] -[mainViewController viewWillLayoutSubviews] -[mainViewController viewDidLayoutSubviews] -[mainViewController viewDidAppear:]
CoreText
• 随意修改文本的样式
• 图文混排(纯C语言) • 国外:Niumb Core Image(滤镜处理) * 能调节图片的各类属性(对比度, 色温, 色差等)
block, target-action ,代理,属性
-(void)touchesBegan:(NSSet)touchedwithEvent:(UIEvent)event;
-(void)touchesMoved:(NSSet)touched withEvent:(UIEvent)event;
-(void)touchesEnded:(NSSet)touchedwithEvent:(UIEvent)event;
-(void)touchesCanceled:(NSSet)touchedwithEvent:(UIEvent)event;
文章若有问题,请留言,我将及时更正。