@interface ViewController () <UIImagePickerControllerDelegate>
@property (nonatomic, strong) UIButton *button;
@property (nonatomic, strong) UIImageView *imageView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.button];
[self.view addSubview:self.imageView];
}
- (void)toImagePickerController {
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
ipc.delegate = self;
ipc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:ipc animated:true completion:nil];
}
}
- (UIButton *)button {
CGRect screen = [[UIScreen mainScreen] bounds];
if (!_button) {
_button = [[UIButton alloc] initWithFrame: CGRectMake(0, 0, 46, 30)];
[_button setTitle:@"圖片" forState:UIControlStateNormal];
[_button setBackgroundColor:[UIColor redColor]];
_button.center = CGPointMake(screen.size.width/2, screen.size.height-100);
[_button addTarget:self action:@selector(toImagePickerController) forControlEvents:UIControlEventTouchUpInside];
}
return _button;
}
#pragma mark -- 1. UIImagePickerDelegate --
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
self.imageView.image = info[UIImagePickerControllerOriginalImage];
[picker dismissViewControllerAnimated:true completion:nil];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissViewControllerAnimated:true completion:nil];
}
- (UIImageView *)imageView {
if (!_imageView) {
_imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height/2)];
_imageView.backgroundColor = [UIColor blueColor];
}
return _imageView;
}
@end
迭代2:添加可以使用攝像頭照一張照片以顯示出來的功能,兩個不同的Button通過使用tag屬性,傳入toImagePickerController:
方法根據它們的tag來確定功能
@interface ViewController () <UIImagePickerControllerDelegate>
@property (nonatomic, strong) UIButton *button;
@property (nonatomic, strong) UIImageView *imageView;
@property (nonatomic, strong) UIButton *takePhotoButton;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.button];
[self.view addSubview:self.imageView];
[self.view addSubview:self.takePhotoButton];
}
- (void)toImagePickerController: (id)sender {
NSInteger tag = ((UIButton *)sender).tag;
if (tag == 1) {
[self pickMediaFromSource:UIImagePickerControllerSourceTypePhotoLibrary];
} else if (tag == 2) {
[self pickMediaFromSource:UIImagePickerControllerSourceTypeCamera];
}
}
- (void)pickMediaFromSource: (UIImagePickerControllerSourceType)sourceType {
NSArray *mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:sourceType];
if ([UIImagePickerController isSourceTypeAvailable:sourceType] && [mediaTypes count] > 0) {
UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
ipc.delegate = self;
ipc.sourceType = sourceType;
ipc.mediaTypes = mediaTypes;
[self presentViewController:ipc animated:true completion:nil];
} else {
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"error accessing source." message:@"Unsupported media source." preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:okAction];
[self presentViewController:alertController animated:true completion:nil];
}
}
#pragma mark -- 1. UIImagePickerDelegate --
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
self.imageView.image = info[UIImagePickerControllerOriginalImage];
[picker dismissViewControllerAnimated:true completion:nil];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissViewControllerAnimated:true completion:nil];
}
#pragma mark -- 2. imageView getter --
- (UIImageView *)imageView {
if (!_imageView) {
_imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height/2)];
_imageView.backgroundColor = [UIColor blueColor];
}
return _imageView;
}
#pragma mark -- 3. button getter --
- (UIButton *)button {
CGRect screen = [[UIScreen mainScreen] bounds];
if (!_button) {
_button = [[UIButton alloc] initWithFrame: CGRectMake(0, 0, 46, 30)];
[_button setTitle:@"圖片" forState:UIControlStateNormal];
[_button setBackgroundColor:[UIColor redColor]];
_button.center = CGPointMake(screen.size.width/2, screen.size.height-100);
_button.tag = 1;
[_button addTarget:self action:@selector(toImagePickerController:) forControlEvents:UIControlEventTouchUpInside];
}
return _button;
}
#pragma mark -- 4. takePhotoButton --
- (UIButton *)takePhotoButton {
CGRect screen = [[UIScreen mainScreen] bounds];
if (!_takePhotoButton) {
_takePhotoButton = [[UIButton alloc] initWithFrame: CGRectMake(0, 0, 46, 30)];
[_takePhotoButton setTitle:@"照相" forState:UIControlStateNormal];
[_takePhotoButton setBackgroundColor:[UIColor blueColor]];
_takePhotoButton.center = CGPointMake(screen.size.width/2, screen.size.height-50);
_takePhotoButton.tag = 2;
[_takePhotoButton addTarget:self action:@selector(toImagePickerController:) forControlEvents:UIControlEventTouchUpInside];
}
return _takePhotoButton;
}
@end
核心代碼:
NSArray *mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:sourceType];
if ([UIImagePickerController isSourceTypeAvailable:sourceType] && [mediaTypes count] > 0) {
UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
ipc.delegate = self;
ipc.sourceType = sourceType;
ipc.mediaTypes = mediaTypes;
[self presentViewController:ipc animated:true completion:nil];
}
- 第一行的mediaTypes數組獲取了當前設備可用的所有媒體類型。
- 把mediaTypes數組賦值給ipc.mediaTypes,如果當前設備可用相機,那么會省去設置ipc.cameraDevice。兼容了有相機和無相機的設備調用此方法的情況。
- sourceType中的兩個方法易混淆,SavedPhotoAlbum用于無相機的設備
</br>
常見問題:
This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSPhotoLibraryUsageDescription key with a string value explaining to the user how the app uses this data.
這些都涉及隱私,需要訪問相冊和使用相機都需要先詢問用戶使用允許這么做,在info.plist文件里添加相關參數即可
-
訪問相冊
-
訪問相機