iOS初学历程

委托和文本输入

2019-07-30  本文已影响0人  水无月之痕

UIResponder: UIKit框架中的一个抽象类,其子类:UIView、UIViewController、UIApplication
UIResponder定义一系列方法,用于接收和处理用户事件(触摸、运动-摇晃设备、功能-控制编辑文本播放)。其子类会覆盖相应的方法,实现自己的事件响应代码。
触摸事件显然应该由被触摸的视图负责处理。系统也将触摸事件直接发送给被触摸的视图。
其他类型的事件则由第一响应者负责处理,UIWindow有一个FristReponder对象就会成为第一响应者。例如,当用户点击UITextfield对象时,UITextfield对象就会成为第一响应者。UIWindow会将firstResponder指向该对象,之后,如果应用接收到运动事件和功能控制事件,都会发送给UITextfield对象。
 当某个UITextField对象或UITextView对象成为第一响应者时,屏幕会弹出键盘。除了用户点击之外,还可以在代码中向UITextField对象发送becomeFirstResponder消息,使其成为第一响应者。相反,如果要关闭键盘,则可以向UITextField对象发送resignFirstResponder消息,且要求该对象放弃第一响应者状态。一旦第一响应者不是UITextField对象,键盘就会消失。
实际上,大部分视图都不需要成为第一响应者。例如UISlider对象,该对象只处理触摸事件(用户拖曳滑块),而不会接受其他类型的事件,因此它不需要成为第一响应者。

textField.returnKeyType=UIReturnKeyDone;//只是将键盘返回按钮--》换行按钮,只修改了外表,后续要增加额外代码

UITextField对象中另外几个有用的属性

目标动作是UIKit中常用的设计模式之一,目标动作的工作方式为:当某个特定的事件发生时(例如按下按钮),发生事件的一方会向指定的目标对象发送一个之前设定好的动作消息。 
在目标动作中,针对不同的事件,需要创建不同的动作消息。UIButton对象的事件比较简单,通常只需要处理点击事件;相反,像UITextField这类事件复杂的对象,Apple使用委托设计模式。UITextField对象具有一个委托属性,通过为UITextField对象设置委托,UITextField对象会在发生事件时向委托发送相应的消息,由委托处理该事件。
在委托方法中,通常应该将对象自身作为第一个参数。多个对象可能具有相同的委托,当委托收到消息时,需要根据该参数判断发送该消息的对象。例如,如果某个视图控制器中包含多个UITextField对象,它们的委托都是该视图控制器,那么视图控制器就需要根据textField参数获取相应的UITextField对象并执行不同的操作。
凡是支持委托的对象,其背后都有一个相应的协议,声明可以向该对象的委托对象发送的消息。委托对象需要根据这个协议为其“感兴趣”的事件实现相应的方法。如果一个类实现了某个协议中规定的方法,就称这个类遵守(conform)该协议。

//使用@protocol指令开头,后跟协议的名称。尖括号里的NSObject是指NSObject协议
//其作用是声明UITextFieldDelegate包含NSObject协议的全部方法。
//接着声明新协议特有的方法,最后使用@end指令结束。
//协议所声明的方法可以是必需的(required)或是可选的(optional)。
//协议方法默认都是必需的。使用@optional指令,可以将写在该指令之后的方法全部声明为可选的。
[美] Christian Keur; [美] Aaron Hillegass; [美] Joe Conway. 《iOS编程(第四版)》 (Kindle Locations 2002-2003). 
@protocolUITextFieldDelegate<NSObject>  
@optional
@end

发送方在发送可选方法前,会先向其委托发送另一个名为respondsToSelector:的消息。所有ObjectiveC对象都从NSObject继承了respondsToSelector:方法,该方法能在运行时检查对象是否实现了指定的方法。@selector()指令可以将选择器(selector)转换成数值,以便将其作为参数进行传递。
如果某个协议方法是必需的,那么发送方可以直接向其委托对象发送相应的消息,不用检查委托对象是否实现了该方法。这意味着,如果委托对象没有实现相应的方法,应用就会抛出未知选择器(unrecognizedselector)异常,导致应用崩溃。  
为了防止发生此类问题,编译器会检查某个类是否实现了相关协议的必需方法。要让编译器能够执行此类检查,必须将相应的类声明为遵守指定的协议。

iOS SDK中很多类都具有委托,而几乎所有的委托都是弱引用属性。这是为了避免对象及其委托之间产生强引用循环

ios设备内嵌了许多功能强大的传感器,例如加速传感器,磁场传感器和三轴陀螺仪等。应用可以通过这些感应器了解设备的速度、方向和角度,并实现有用的功能。

读者可以想象自己坐在一辆飞驰的车中,这时向车窗外望去,会发现远处景物的倒退速度比近处的要慢很多。这是大脑对空间和速度差异产生的一种错觉,称为视差。在iOS7中,视差效果随处可见,例如,在主屏幕中,如果稍微倾斜设备,可以发现主屏幕中的图标会随着倾斜方向相对于壁纸移动;在iOS系统其他部分和应用中,包括红色的通知标识、音量调节指示器和警告视图等,都带有一定程度的视差效果。应用可以用UIInterpolatingMotionEffect类实现相同的效果。

调试断点:自己实现的两个方法呈黑色,系统库实现的方法呈灰色。


调试区域

有内存地址意味着在执行到断点的那行代码之前,程序已经创建并初始化了该对象。self下方的第一个条目是self的父类。

调试工具条

设置异常断点
还可以让调试器为导致应用崩溃或引发异常的那行代码自动设置断点。  
为此,需要为调试器增加一个针对所有异常的断点。打开断点导航面板,单击面板底部的“+”按钮,选择AddExceptionBreakpoint…(添加异常断点)


image.png
//main函数中的,UIApplicationMain会创建一个UIApplication对象。
//每个iOS应用有且只有一个UIApplication对象,作用:维护runLoop。
//一旦程序创建了某个UIApplication对象,该对象的运行循环就会一直循环下去,main()的执行也会因此阻塞。
//UIApplicationMain函数还会创建某个指定类的对象,并将其设置为UIApplication对象的delegate。
//。该对象的类是由UIApplicationMain函数的最后一个实参指定的,该实参的类型是NSString对象,代表的是某个类的类名。
//在应用启动运行循环并开始接收事件前,UIApplication对象会向其委托发送一个特定的消息,使应用能有机会完成相应的初始化工作。
//这个消息的名称是application:didFinishLaunchingWithOptions:。
int main(int argc,char* argv[])  
{  
@autoreleasepool{   
return UIApplicationMain(argc,argv,nil,NSStringFromClass([AppDelegate class]));    
    } 
}
上一篇下一篇

猜你喜欢

热点阅读