废话不说,先上需求:
用户手动截屏(home加锁屏键),app在打开聊天模块时能够提示用户是不是要发送刚才截屏的那张图片(类型微信和qq)。
iOS7之后,我大概想到的思路有两种:
- 1.注册UIApplicationUserDidTakeScreenshotNotification通知,发生截屏后,从相册中取最新一张图片,把图片路径存储下来,在聊天发消息事件触发时显示出来;
- 2.注册UIApplicationUserDidTakeScreenshotNotification通知,发生截屏后模拟用户截取当前屏幕,获取UIImage,保存起来,在聊天发消息事件触发时显示出来。
区别就是一个是从相册获取保存路径,一个是自己模拟截屏,保存UIImage。第二种网上很多例子,我就不写了,下面讲下第一种的实现,有几个要注意的,分享给大家。
流程:
1.appdelegate注册
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(takeScreenShot:) name:UIApplicationUserDidTakeScreenshotNotification object:nil];//截屏通知
2.实现takeScreenShot:
[assetsLib enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
if (group) {
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
[group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
if (result) {
NSURL *url = result.defaultRepresentation.url;
[commonObj.screenShotDic setObject:url forKey:@"shot"];//全局单例
*stop = YES;
}}];
*stop = YES;
}} failureBlock:^(NSError *error) {
}];
3展示
if ([commonObj.screenShotDic objectForKey:@"screenShot"]) {
NSURL * imgUrl = [commonObj.screenShotDic objectForKey:@"shot"];
if (imgUrl) {
[shotV showMenuOnView:mainTV atPoint:CGPointZero withImageUrl:imgUrl];
}
}
大概流程是这样,但是这里有个问题就是截屏后执行takeScreenShot方法时,截屏的图片还没有保存在相册,这样你获取到的最新一张图片就不是刚才截屏的那一张,因此改造。
1,在appdelegate增加一个通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(photoAblumChanged:) name:ALAssetsLibraryChangedNotification object:assetsLib];//相册变化通知
2,photoAblumChanged 和 takeScreenShot
- (void)takeScreenShot:(NSNotification *)notice{
//取相册最新一张照片
ALAuthorizationStatus kStatus = [ALAssetsLibrary authorizationStatus];
if (kStatus == ALAuthorizationStatusAuthorized) {
isScreenShot = YES; //成员变量
}
}
- (void)photoAblumChanged:(NSNotification *)notice{
if (!isScreenShot) {
return;
}
isScreenShot = NO;
[assetsLib enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
if (group) {
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
[group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
if (result) {
NSURL *url = result.defaultRepresentation.url;
[commonObj.screenShotDic setObject:url forKey:@"shot"];
*stop = YES;
}
}];
*stop = YES;
}
} failureBlock:^(NSError *error) {
}];
}
这样就解决了截屏后获取图片不对的情况,但是ALAssetsLibraryChangedNotification有点小坑,就是在初始化时需要写上这个不然会不执行通知方法
isScreenShot = NO;
assetsLib = [[ALAssetsLibrary alloc] init];
[assetsLib writeImageToSavedPhotosAlbum:nil metadata:nil completionBlock:^(NSURL *assetURL, NSError *error) { }];//防止相册变化通知不工作
完结。