UIImagePickerController 保存文件路径 iOS/iPhone
Posted
技术标签:
【中文标题】UIImagePickerController 保存文件路径 iOS/iPhone【英文标题】:UIImagePickerController saving file path iOS/iPhone 【发布时间】:2012-07-16 11:56:45 【问题描述】:使用下面的代码我试图只保存视频文件路径(不想运行它或打开媒体播放器视图)。
问题是当我点击选择器控制器中的视频缩略图时,它会自动在媒体播放器视图中打开视频。虽然我只想保存它的路径,然后我想在用户按下播放按钮时使用它。
让我再解释一下,我有 2 个视图,在 MainView 我有 2 个按钮,1 个按钮 OPEN 用于打开 UIImagePickerController
并选择视频,1 个按钮 PLAY 用于播放相同的选定视频。我在这里要做的是,当用户点击打开按钮UIImagePickerController
时应该打开并且用户应该能够选择视频,当用户点击视频缩略图时UIImagePickerController
应该被关闭并且MainView
(其中打开和播放按钮都是)应该打开的。然后如果用户想播放电影,他会点击播放按钮并观看电影。
但是在这段代码中,当我点击UIImagePickerController
中的电影缩略图时,它会导航到媒体查看器。
- (IBAction)openPicker:(id)sender
mediaPickerController = [[UIImagePickerController alloc] init];
NSArray *types = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerQualityTypeHigh];
mediaPickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
mediaPickerController.delegate = self;
mediaPickerController.mediaTypes = types;
mediaPickerController.videoQuality = UIImagePickerControllerQualityTypeHigh;
mediaPickerController.delegate = nil;
[self presentModalViewController:mediaPickerController animated:YES];
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
videoPath = [info objectForKey:UIImagePickerControllerMediaURL];
NSLog(@"videoPath: %@", videoPath);
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
【问题讨论】:
【参考方案1】:有两种方法...
将 allowsEditing 设置为 NO。这不应该显示媒体查看器,但由于我不是每天都使用 UIImagePickerController,所以我不能 100% 确定,你需要对其进行测试。但是即使可以,如果视频超过 10 分钟,编辑界面仍然存在,因为视频必须修剪(查看 UIImagePickerController 的文档)。但正如我写的那样,测试它,因为我不使用它可能会出错。
查看ALAssetsLibrary。通过本课程(和朋友),您可以在几分钟内编写自定义选择器。然后你可以做任何你想做的事情。但是这种方法有一个小问题 - 用户必须同意您的应用程序可以访问位置信息,这对用户来说是相当误导的。那是因为资产可以包含位置信息。当用户禁用对您的应用程序的位置信息的访问时,您的自定义选择器将不起作用。
更新,评论中要求的一些代码。
获取群组列表(此代码获取所有群组并过滤掉没有视频的群组):
if ( ! __assetsLibrary )
__assetsLibrary = [[ALAssetsLibrary alloc] init];
[__assetsLibrary enumerateGroupsWithTypes:__assetsGroupType
usingBlock:^( ALAssetsGroup *group, BOOL *stop )
/*
* If group is nil => end of iteration, no more groups will arrive.
*/
if ( group )
/*
* We do only want groups with videos, so, set filter to allVideos. Following
* numberOfAssets method respects filter settings, so, only number of videos
* is returned.
*/
[group setAssetsFilter:[ALAssetsFilter allVideos]];
if ( [group numberOfAssets] > 0 )
TMDCONDLOG( DEBUG_PICKER, @"Asset group added: %@", [group valueForProperty:ALAssetsGroupPropertyName ]);
[__assetsGroups addObject:group];
else
TMDCONDLOG( DEBUG_PICKER, @"Skipping %@, no videos inside", [group valueForProperty:ALAssetsGroupPropertyName] );
else
// group is nil, no more groups will arrive, reload table
TMDCONDLOG( DEBUG_PICKER, @"Asset groups count: %d", (int)[__assetsGroups count]);
dispatch_async( dispatch_get_main_queue(), ^
[self reloadDataFinished];
);
failureBlock:^( NSError *error)
TMDCONDLOG( DEBUG_PICKER, @"Failed: %@", error );
dispatch_async(dispatch_get_main_queue(), ^
[self reloadDataFinished];
[self showAccessFailedError];
);
];
这里有一些代码可以枚举ALAssetsGroup
:
[__assetsGroup enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stopEnumeratingAssets )
TMDCONDLOG( DEBUG_ASSETS, @"Asset: %@ Index: %d", result, ( int ) index );
if ( result )
[__assets addObject:result];
/*
* Enumeration ends? If yes, reload table.
*/
if ( ! result || index == NSNotFound )
*stopEnumeratingAssets = YES;
TMDCONDLOG( DEBUG_ASSETS, @"Going to reload table view" );
[self performSelectorOnMainThread:@selector(reloadTableData) withObject:nil waitUntilDone:NO];
];
这是一个如何获取组的资产数量、海报图片等的示例:
__groupAssetsCountLabel.text = [NSString stringWithFormat:@"(%d)", (int) [__assetsGroup numberOfAssets]];
__groupTitleLabel.text = ( NSString * )[__assetsGroup valueForProperty:ALAssetsGroupPropertyName];
__groupImageView.image = [UIImage imageWithCGImage:[__assetsGroup posterImage]];
在您的自定义UITableViewCell
中为您的群组使用它。下面是一个如何获取资产缩略图和持续时间的示例:
dispatch_async( dispatch_get_main_queue(), ^
__assetView.image = [UIImage imageWithCGImage:[__asset thumbnail]];
);
id property = [__asset valueForProperty:ALAssetPropertyDuration];
if ( ! [property isEqual:ALErrorInvalidProperty] )
NSInteger duration = ( ( NSNumber * )property ).integerValue;
__durationLabel.text = [NSString stringWithFormat:@"%d:%02d", ( int ) ( duration / 60 ), ( int ) ( duration % 60 ) ];
else
__durationLabel.text = nil;
您可以在自定义 UITableViewCell
中使用此代码连续显示 4 个资产,以模拟 Apple 的选取器 UI。
宏观例子...
#define TMLOG( __xx, ... ) NSLog( @"%s(%d): " __xx, __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__ )
#ifdef DEBUG
#define TMDLOG( __xx, ... ) TMLOG( __xx, ##__VA_ARGS__ )
#else
#define TMDLOG( __xx, ... ) ((void)0)
#endif
#ifdef DEBUG
#define TMDCONDLOG( __cond, __xx, ... ) \
if ( ( __cond ) ) \
TMDLOG( __xx, ##__VA_ARGS__ ); \
\
((void)0)
#else
#define TMDCONDLOG( __cond, __xx, ... ) ((void)0)
#endif
【讨论】:
谢谢,我试过第一个选项,它不起作用。第二个选项将不起作用。因为选择器不会在位置信息场景中工作。 会起作用,但你需要向用户解释。我们在许多应用程序中都有自定义选择器,到目前为止没有问题。如果您告诉他们启用它,他们就会这样做。当您的应用程序第一次访问资产库时,ios 会自动弹出警报视图,询问他们是否同意。别担心... 我无法制作自定义选择器,您有任何示例代码/教程吗?这样我才能度过难关 添加了一些示例代码。现在轮到您获取它并实施您的自定义选择器了。 谢谢@Robert,什么是 DEBUG_PICKER 和 TMDCONDLOG【参考方案2】:添加到你的
openPicker: method.
mediaPickerController.mediaTypes =
[[NSArray alloc] initWithObjects: (NSString *) kUTTypeMovie, nil];
更新
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo
[picker dismissModalViewControllerAnimated:YES];
【讨论】:
它仍然导航到媒体查看器,而我想关闭 UIImagePickerController 并返回主视图 对不起朋友,没有解决办法:( 其实它的 UIImagePickerController 的功能就是当我们尝试选择文件时,它会自动打开所需的查看器。 什么意思?你有解决办法吗? 不,还没有解决方案。我正在深入研究 UIImagePickerController以上是关于UIImagePickerController 保存文件路径 iOS/iPhone的主要内容,如果未能解决你的问题,请参考以下文章
UIImagePickerController、自定义 UIButton 和 AutoLayout
OCMock 模拟 UIImagePickerController