UIImageView对象会根据其contentMode属性显示一张指定的图片。contentMode属性的作用是确定图片在frame内的显示位置和缩放模式。contentMode的默认值是UIViewContentModeScaleToFill。当contentMode的值是UIViewContentModeScaleToFill时,UIImageView对象会在显示图片时缩放图片的大小,使其能够填满整个视图空间,但是可能会改变图片的宽高比。如果使用其默认值,UIImageView对象为了能在正方形的区域中显示由相机拍摄的大尺寸照片,就要改变照片的宽高比。为了获得最佳显示效果,要修改UIImageView对象的contentMode,要求其根据宽高比缩小照片。
在AspectFit模式下,UIImageView对象会在显示图片时按宽高比缩放图片,使其能够填满整个视图。相机按钮,使用UIToolBar,使用camera图标。UIToolbar对象的工作方式和UINavigationBar非常相似,同样可以加入UIBarButtonItem对象。区别是UINavigationBar只能在左右两端分别放置一个UIBarButtonItem对象,而UIToolbar对象可以有一组UIBarButtonItem对象。只要屏幕能够容纳,UIToolbar对象自身并没有限制可以存放的UIBarButtonItem对象个数。
设置sourceType属性时必须使用特定的常量,这些常量表示UIImagePickerController对象获取照片的“源”。目前有以下三种可以使用的常量。
1•UIImagePickerControllerSourceTypeCamera:用于用户拍摄一张新照片。
2•UIImagePickerControllerSourceTypePhotoLibrary:用于显示界面,让用户选择相册,然后从选中的相册中选择一张照片。 3•UIImagePickerControllerSourceTypeSavedPhotosAlbum:用于让用户从最近拍摄的照片里选择一张照片。
对于没有相机的设备,第一种选取类型
UIImagePickerControllerSourceTypeCamera是无效的。所以在使用第一种变量前,需要向UIImagePickerController类发送isSourceTypeAvailable:消息,检查设备是否支持相机。发送该消息时,需要传入待检查的选取类型常量。
除了sourceType属性,还需要为UIImagePickerController对象设置委托,也就是delegate属性。当用户从UIImagePickerController对象中选择了一张照片后,委托会收到imagePickerController:didFinishPickingMediaWithInfo:消息(如果用户取消了选择,则委托会收到imagePickerControllerDidCancel:消息)
UIImagePickerController对象的委托通常应该设置为需要获取照片的对象(UIImagePickerController是UINavigationController的子类,所以UIImagePickerController的委托也要遵守UINavigationControllerDelegate协议)
模态的形式
为UIImagePickerController对象设置了源类型和委托之后,就可以在屏幕中显示该对象。和之前显示的UIViewController子类对象不同,该对象必须以模态的(modal)形式显示。以模态的形式显示的视图控制器,其视图会占据整个屏幕,直到关闭。
要以模态的形式显示某个视图控制器,需要向窗口当前显示的UIViewController对象发送presentViewController:animated:completion:,并为第一个参数传入需要显示的视图控制器。同时,如果为第二个参数animated:传入YES,相应的视图控制器的视图会从屏幕底部滑入(第17章会深入介绍模态视图控制器与第三个参数)。
保存照片
在BNRDetailViewController.m中实现imagePickerController:didFinishPickingMediaWithInfo:,将选择的照片放入之前创建的UIImageView对象中,然后关闭UIImagePickerController对象
NSDictionary
字典对象中的指针不是有序排列的,需要通过键(key)来存取指针,不能使用索引。键其实也是对象,而且最常用的是NSString对象。在其他语言中,这里的字典对象称为哈希图(hashmap)或哈希表(hashtable)。
NSDictionary非常有用,其中最常见的用法是可变数据结构(flexible datastructures)和 查询表(lookup tables)。
可变数据结构
使用NSDictionary与NSObject子类Person的区别是,Person要求事先明确定义好“人”的各项属性,并且之后无法添加新的属性,也无法删除或修改现有属性。相反,如果使用NSDictionary,“人”的数据就只是一系列键值对,操作起来非常简单,例如,为某个人添加“地址”时,只需要为@“address”键设置表示地址的字符串就可以了。
当然,并不是所有的模型对象都可以通过NSDictionary来描述。大部分模型对象具有严格的定义和特定的数据处理方式,不适合采用简单的键值对管理数据。相反,如果模型对象根据不同的配置选项具有不同的数据结构,就应该使用NSDictionary。
查询表
当读者需要编写包含大量ifelse或switch语句的代码时,通常应该考虑替换为NSDictionary。NSDictionary可以事先在两组对象之间建立一对一的映射关系。例如,上述代码中的ifelse语句可以替换为一个NSDictionary对象:
//使用NSDictionary查询表的另一个优点:不需要在方法中硬编码所有数据(角色类型);
//相反,可以将数据保存在文件系统或远程服务器中,甚至可以由用户动态添加或修改。
NSMutableDictionary*lookup=[[NSMutableDictionaryalloc]init];
[lookupsetObject:knightforKey:@“Warrior”];
[lookupsetObject:wizardforKey:@“Mage”];
[lookupsetObject:rogueforKey:@“Thief”];
(void) changeCharacterClass:(id)sender
{
character.characterClass=[lookupobjectForKey:textField.text];
}
使用字典对象时,键不能重复。在将某个键值对加入字典对象时,如果字典对象已经保存了拥有相同的键的值,那么旧的值会被替换掉。如果要用一个键来保存多个对象,则可以先将这些对象存入数组对象,然后将这个数组对象作为值存入字典对象。
NSArray的简洁语法并注意与NSDictionary的区别:NSArray是通过“@[]”创建的,NSDictionary则是通过“@{}”创建的。
//使用简洁语法创建NSDictionary对象时,
//每一个键值对之间需要使用逗号“,”隔开,而键与值之间则使用冒号“:”隔开
NSDictionary*dictionary=@{@“key”:object,@“anotherKey”:anotherObject};
键与唯一标识
用CocoaTouch提供的一种机制,这种机制可以生成唯一标识(UUID,也称为GUID)。每一个NSUUID类的对象都表示一个唯一的UUID。UUID是基于当前时间、计数器(counter)和硬件标识(通常为无线网卡的MAC地址)等数据计算生成的。如果使用字符串表示UUID
//创建一个NSUUID对象,然后获取其NSString类型的值
NSUUID*uuid=[[NSUUIDalloc]init];
NSString*key=[uuidUUIDString];
_itemKey=key;
实现委托方法textFieldShouldReturn:,使用户能通过按下“换行”键来取消UITextField对象的第一响应状态而关闭键盘。
如何在用户按下视图时发送指定的消息。
Controller对象的视图从UIView对象改为UIControl对象,使其能够处理触摸事件。选中xib中的顶层视图。打开标识检视面板,将Class文本框中的UIView修改为UIControl。
因为UIControl能够处理多种类型的事件,所以必须为要触发的动作消息设置合适的事件类型。
网友评论