UIImageView - BNR

  继续上节UINavigationController - BNR

  打开BNRDetailViewController.xib文件,向view中添加UIImageView对象,选中该对象,通过Attributes Inspector -> View -> Mode -> Aspect Fit,调整UIImageView对象的contentMode属性。

  同时,添加UIToolBar拖到view的底部。选中UIToolBar的Item,通过Attributes Inspector -> Bar Button Item -> System Item -> Camera,将其改为相机图标。此相机按钮需要一个target和action。如下所示:

  在BNRDetailViewController.m的类扩展中与UIImageView建立outlet连接,如下:

  选择相机按钮,Control-Drag到BNRDetailViewController.m,创建takePicture:方法,如下:

  同时,将UIToolBar建立一个outlet,取名为toolBar。


 

  当我们创建了一个UIImagePickerController对象时,必须设置它的sourceType属性和给它分配一个delegate。

sourceType常量告诉UIImagePicker对象从哪里获取照片。其有三个可选的值,1)UIImagePickerControllerSourceTypeCamera,拍摄一张新的照片,使用该常量前,需要将isSourceTypeAvailable:方法发送给UIImagePickerController,检验该设备是否有相机功能;2)UIImagePickerControllerSourceTypePhotoLibrary,将选择一个照片集,从该照片集中选择照片;3)UIImagePickerControllerSourceTypeSavedPhotoAlbum,将从最近拍摄的照片中获取。

  在BNRDetailViewController.m中,添加协议:

@interface BNRDetailViewController () <UINavigationControllerDelegate, UIImagePickerControllerDelegate>

  在BNRDetailViewController.m中,修改takePicture:方法如下:

 1 - (IBAction)takePicture:(id)sender {
 2     UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
 3     if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
 4         imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
 5     } else {
 6         imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
 7     }
 8     imagePicker.delegate = self;
 9     [self presentViewController:imagePicker animated:YES completion:nil];
10 }

  UIImagePickerController对象已模态方式呈现。一个模态视图控制器将占据整个屏幕直到结束操作。

  当用户已经选好一张照片时,imagePickerController:didFinishPickingMediaWithInfo:方法给被自动发送给UIImagePicker的委托对象。

1 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
2     // 从info字典中获取选择的image
3     UIImage *image = info[UIImagePickerControllerOriginalImage];
4     self.imageVeiw.image = image;
5     // 退出UIImagePickerController
6     [self dismissViewControllerAnimated:YES completion:nil];
7 }

 

  将照片存入disk中,当需要它们的时候才放到RAM中。

  创建一个新的NSObject的子类BNRImageStore,其将持有用户使用的照片,其为单例模式。因为图像一般都比较大,将它们与其它数据分离开比较少。

  打开BNRImageStore.h,添加如下方法:

#import <UIKit/UIKit.h>  //此处将Foundation/Foundation.h修改为UIKit/UIKit.h

@interface BNRImageStore : NSObject

+ (instancetype)sharedImage;

- (void)setImage:(UIImage *)image forKey:(NSString *)key;
- (UIImage *)imageForKey:(NSString *)key;
- (void)deleteImageForKey:(NSString *)key;

@end

  打开BNRImageStore.m文件,添加类扩展,并声明一个变量,如下:

1 @interface BNRImageStore ()
2 
3 @property (nonatomic, strong) NSMutableArray *dictionary;  // 存放图片
4 
5 @end

  再添加下面的代码:

 1 + (instancetype)sharedImage {
 2     static BNRImageStore *shareStore = nil;
 3     if (!shareStore) {
 4         shareStore = [[BNRImageStore alloc] initPrivate];
 5     }
 6     return shareStore;
 7 }
 8 
 9 - (instancetype)init {
10     @throw [NSException exceptionWithName:@"Singleton"
11                                    reason:@"Use+[BNRImageStore sharedStore]"
12                                  userInfo:nil];
13     return nil;
14 }
15 
16     // Designated initializer
17 - (instancetype)initPrivate {
18     self = [super init];
19     if (self) {
20         _dictionary = [[NSMutableDictionary alloc] init];
21     }
22     return self;
23 }

  实现在头文件中声明的三个实例方法:

 1 - (void)setImage:(UIImage *)image forKey:(NSString *)key {
 2     self.dictionary[key] = image;
 3 }
 4 
 5 - (UIImage *)imageForKey:(NSString *)key {
 6     return self.dictionary[key];
 7 }
 8 
 9 - (void)deleteImageForKey:(NSString *)key {
10     if (!key) {
11         return;
12     }
13     [self.dictionary removeObjectForKey:key];
14 }

  当你需要一个模型对象时,需要创建一个继承自NSObject的新类,并且给予它恰当的实例变量。

 

  在BNRItem.h中,添加一个实例变量用来存放图片的键值,如下:

1 @property (nonatomic, copy) NSString *itemKey;  // 存放BNRImageStore中图像的键值

  同时打开BNRItem.m文件,导入BNRImageStore头文件,如下:

1 #import "BNRImageStore.h"

  我们将使用通用唯一标识码(Universally Unique Identifier,UUIDs)作为key值。在Objective-C中,用NSUUID类来代表UUID。修改BNRItem.m中的initWithItemName:valueInDollars:serialNumber:方法如下:

 1     // designated initializer
 2 - (instancetype)initWithItemName:(NSString *)name
 3                   valueInDollars:(int)value
 4                     serialNumber:(NSString *)sNumber
 5 {
 6     // Call the superclass's designated initializer
 7     self = [super init];
 8 
 9     // Did the superclass's designated initializer succeed?
10     if (self) {
11         // Give the instance variables initial values
12         _itemName = name;
13         _serialNumber = sNumber;
14         _valueInDollars = value;
15         // Set _dateCreated to the current date and time
16         _dateCreated = [[NSDate alloc] init];
17         
18         NSUUID *uuid = [[NSUUID alloc] init];
19         NSString *key = [uuid UUIDString];
20         _itemKey = key;
21     }
22     
23     // Return the address of the newly initialized object
24     return self;
25 }

  修改BNRDetailViewController.m中的imagePickerController:didFinishPickingMediaWithInfo:方法如下:

1 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
2     // 从info字典中获取选择的image
3     UIImage *image = info[UIImagePickerControllerOriginalImage];
4     [[BNRImageStore sharedImage] setImage:image forKey:self.item.itemKey];
5     
6     self.imageVeiw.image = image;
7     // 退出UIImagePickerController
8     [self dismissViewControllerAnimated:YES completion:nil];
9 }

当用户每次获取到图片的时候,就会将其存入image store中。BNRImageStore和BNRItem类都知道图像的key,因此能通过两者来获取图片。

  打开BNRItemStore.m,导入BNRImageStore的头文件,如下:

#import "BNRImageStore.h"

  当删除一个item的时候,需要从image store 中删除其图像,修改removeItem:方法如下:

1 - (void)removeItem:(BNRItem *)item {
2     NSString *key = item.itemKey;
3     [[BNRImageStore sharedImage] deleteImageForKey:key];
4     [self.privateItems removeObjectIdenticalTo:item];
5 }

  当图片第一次被创建的时候,它将存在于内存中特定的地址中。下一次程序启动的时候,图片在内存中的地址将会发生改变,因此不能通过指针来获取图片。

 

  打开,BNRDetailViewController.m,在类扩展中添加UITextFieldDelegate协议,然后修改textFieldShouldReturn:方法,这样当输入结束时,点击return按钮可隐藏键盘。代码如下:

1 - (BOOL)textFieldShouldReturn:(UITextField *)textField {
2     [textField resignFirstResponder];
3     return YES;
4 }

  

  为了让用户点击屏幕上的任何地方都能隐藏键盘,首先,打开BNRDetailViewController.xib,选中view视图,打开Attributes Inspector,将其class改为UIControl。

  按住view,Control-drag到BNRDetailViewController.m文件的实现处,按下图构造一个action:

  修改刚添加的action代码如下:

1 - (IBAction)backgroundTapped:(id)sender {
2     [self.view endEditing:YES];
3 }

程序代码如下:http://pan.baidu.com/s/1c00muxa


 

  UIImagePickerController对象有一个mediaType属性,其为字符串数组,包含标识符,来说明可以选择哪种类型的media。默认只包含kUTTypeImage,可向其添加kUTTypeMovie,使UIImagePickerController能够选择视频。修改BNRDetailViewController.m的takePicture:方法,

 1 - (IBAction)takePicture:(id)sender {
 2     UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
 3     NSArray *availableType = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
 4     imagePicker.mediaTypes = availableType;
 5     
 6     if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
 7         imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
 8     } else {
 9         imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
10     }
11     imagePicker.delegate = self;
12     [self presentViewController:imagePicker animated:YES completion:nil];
13 }

真机测试结果如下:

次时在模拟器上测试会遇到会遇到NSInvalidArgumentException错误。只能在真机上测试。

如何免费设置真机调试,请参考下述连接的文章:http://www.bubuko.com/infodetail-1061938.html

在真机上运行时,若出现Security的警告,则在iPhone的设置里面:Settings -> General -> Profiles,选择DEVELOPER APP下的开发者账号,之后选择Trust即可。

posted @ 2015-10-19 10:10  pestle  阅读(373)  评论(0编辑  收藏  举报