如何在自己的應(yīng)用程序中進(jìn)行長(zhǎng)截屏?

不知道各位在開(kāi)發(fā)過(guò)程中是否碰到過(guò)此類(lèi)的需求,產(chǎn)品要求開(kāi)發(fā)人員將長(zhǎng)長(zhǎng)的文章或者是瀏覽的內(nèi)容進(jìn)行截屏然后將截圖所獲得的圖片分享出去或者上傳到服務(wù)器。

筆者遇到了這樣一個(gè)需求,要求開(kāi)發(fā)人員將配置好的商品發(fā)送出去的同時(shí)截圖上傳至服務(wù)器。然后以此作為一個(gè)記錄,便于日后方便取用??戳瞬⒑?jiǎn)單寫(xiě)了一個(gè)測(cè)試demo試了一下。

// 長(zhǎng)截圖 類(lèi)型可以是 tableView或者scrollView 等可以滾動(dòng)的視圖 根據(jù)需要自己改

- (void)saveLongImage:(UITableView *)table {

UIImage* image = nil;

// 下面方法,第一個(gè)參數(shù)表示區(qū)域大小。第二個(gè)參數(shù)表示是否是非透明的。如果需要顯示半透明效果,需要傳NO,否則傳YES。第三個(gè)參數(shù)就是屏幕密度了,調(diào)整清晰度。

UIGraphicsBeginImageContextWithOptions(table.contentSize, YES, [UIScreen mainScreen].scale);

CGPoint savedContentOffset = table.contentOffset;

CGRect savedFrame = table.frame;

table.contentOffset = CGPointZero;

table.frame = CGRectMake(0, 0, table.contentSize.width, table.contentSize.height);

[table.layer renderInContext: UIGraphicsGetCurrentContext()];

image = UIGraphicsGetImageFromCurrentImageContext();

table.contentOffset = savedContentOffset;

table.frame = savedFrame;

UIGraphicsEndImageContext();

if (image != nil) {

//保存圖片到相冊(cè)

UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), NULL);

}

}

重點(diǎn)是獲取所要截屏的長(zhǎng)度和寬度大小。即使獲取屏幕上控件的高度加在一起。獲取將要裁剪的尺寸。那么如果截圖成功了。如何將圖片保存呢?

// 保存后回調(diào)方法

- (void)image: (UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {

NSString *msg = nil ;

if(error != NULL){

msg = @"保存圖片失敗" ;

}else{

msg = @"保存圖片成功,可到相冊(cè)查看" ;

}

UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:@"確定" preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];

UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:nil];

[alertController addAction:cancelAction];

[alertController addAction:okAction];

[self presentViewController:alertController animated:YES completion:nil];

}

微信可以檢測(cè)到用戶(hù)截屏行為(Home + Power),并在稍后點(diǎn)擊附加功能按鈕時(shí)詢(xún)問(wèn)用戶(hù)是否要發(fā)送剛才截屏的圖片,這個(gè)用戶(hù)體驗(yàn)非常好。于是乎, 我也想著實(shí)現(xiàn)這個(gè)功能。

在iOS7之前,?如果用戶(hù)截屏,系統(tǒng)會(huì)自動(dòng)取消屏幕上的所有 touch 事件,(使用touchesCancelled:withEvent: 這個(gè)方法)那么我們就可以檢測(cè)這個(gè)方法的調(diào)用,然后加載本地最新圖片再加以判斷來(lái)實(shí)現(xiàn)我們的目的。但在 iOS 7 之后,截屏不再會(huì)取消屏幕的 touch 事件,所以導(dǎo)致了 Snapchat 和 Facebook Poke 之類(lèi)的應(yīng)用在 iOS 7 剛發(fā)布時(shí)依賴(lài)于系統(tǒng)這個(gè)行為的功能受到影響。

如果不采取任何新措施, 我們可以讓?xiě)?yīng)用啟動(dòng)后在后臺(tái)循環(huán)檢測(cè)相冊(cè)內(nèi)最新一張照片,看它的是否符合截屏的特征。這種方法可行,但這是個(gè)笨方法,需要用戶(hù)允許你的程序訪問(wèn)相冊(cè)才可以,并且一直在后臺(tái)循環(huán)會(huì)消耗更多的系統(tǒng)資源。

當(dāng)然, 蘋(píng)果封閉了一些東西, 肯定也會(huì)給你開(kāi)放其他東西, 不會(huì)讓你走上絕路的。

iOS7提供一個(gè)嶄新的推送方法:

UIApplicationUserDidTakeScreenshotNotification

。只要像往常一樣訂閱即可知道什么時(shí)候截圖了。

注意:UIApplicationUserDidTakeScreenshotNotification

將會(huì)在截圖完成之后顯示

?,F(xiàn)在在截圖截取之前無(wú)法得到通知。

一。注冊(cè)通知:

//注冊(cè)通知[[NSNotificationCenter defaultCenter]addObserver:selfselector:@selector(userDidTakeScreenshot:)name:UIApplicationUserDidTakeScreenshotNotificationobject:nil];

二。監(jiān)聽(tīng)截屏:

執(zhí)行操作, 也就是實(shí)現(xiàn)上面通知對(duì)應(yīng)的響應(yīng)函數(shù) ?--?userDidTakeScreenshot

//截屏響應(yīng)- (void)userDidTakeScreenshot:(NSNotification*)notification{NSLog(@"檢測(cè)到截屏");//人為截屏, 模擬用戶(hù)截屏行為, 獲取所截圖片UIImage*image_ = [selfimageWithScreenshot];//添加顯示UIImageView*imgvPhoto = [[UIImageViewalloc]initWithImage:image_];? ? imgvPhoto.frame =CGRectMake(self.window.frame.size.width/2,self.window.frame.size.height/2,self.window.frame.size.width/2,self.window.frame.size.height/2);//添加邊框CALayer* layer = [imgvPhoto layer];? ? layer.borderColor = [? ? [UIColorwhiteColor]CGColor];? ? layer.borderWidth =5.0f;//添加四個(gè)邊陰影imgvPhoto.layer.shadowColor = [UIColorblackColor].CGColor;? ? imgvPhoto.layer.shadowOffset =CGSizeMake(0,0);? ? imgvPhoto.layer.shadowOpacity =0.5;? ? imgvPhoto.layer.shadowRadius =10.0;//添加兩個(gè)邊陰影imgvPhoto.layer.shadowColor = [UIColorblackColor].CGColor;? ? imgvPhoto.layer.shadowOffset =CGSizeMake(4,4);? ? imgvPhoto.layer.shadowOpacity =0.5;? ? imgvPhoto.layer.shadowRadius =2.0;? ? [self.window addSubview:imgvPhoto];}

我這里的?userDidTakeScreenshot 總共做了3件事

1.打印檢測(cè)到截屏

2.獲取截屏圖片。調(diào)用[self imageWithScreenshot];這里的imageWithScreenshot是人為截屏, 模擬用戶(hù)截屏操作, 獲取截屏圖片。

3.顯示截屏圖片, 以屏幕1/4大小顯示在右下角, 并且加上白色邊框和陰影效果突出顯示。

三。獲取截屏圖片

/**

*? 截取當(dāng)前屏幕

*

*? @return NSData *

*/- (NSData*)dataWithScreenshotInPNGFormat{CGSizeimageSize =CGSizeZero;UIInterfaceOrientationorientation = [UIApplicationsharedApplication].statusBarOrientation;if(UIInterfaceOrientationIsPortrait(orientation))imageSize = [UIScreenmainScreen].bounds.size;elseimageSize =CGSizeMake([UIScreenmainScreen].bounds.size.height, [UIScreenmainScreen].bounds.size.width);UIGraphicsBeginImageContextWithOptions(imageSize,NO,0);CGContextRefcontext =UIGraphicsGetCurrentContext();for(UIWindow*windowin[[UIApplicationsharedApplication] windows]){CGContextSaveGState(context);CGContextTranslateCTM(context, window.center.x, window.center.y);CGContextConcatCTM(context, window.transform);CGContextTranslateCTM(context, -window.bounds.size.width * window.layer.anchorPoint.x, -window.bounds.size.height * window.layer.anchorPoint.y);if(orientation ==UIInterfaceOrientationLandscapeLeft){CGContextRotateCTM(context, M_PI_2);CGContextTranslateCTM(context,0, -imageSize.width);}elseif(orientation ==UIInterfaceOrientationLandscapeRight){CGContextRotateCTM(context, -M_PI_2);CGContextTranslateCTM(context, -imageSize.height,0);}elseif(orientation ==UIInterfaceOrientationPortraitUpsideDown) {CGContextRotateCTM(context, M_PI);CGContextTranslateCTM(context, -imageSize.width, -imageSize.height);}if([window respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]){[window drawViewHierarchyInRect:window.bounds afterScreenUpdates:YES];}else{[window.layer renderInContext:context];}CGContextRestoreGState(context);}UIImage*image =UIGraphicsGetImageFromCurrentImageContext();UIGraphicsEndImageContext();returnUIImagePNGRepresentation(image);}/**

*? 返回截取到的圖片

*

*? @return UIImage *

*/- (UIImage*)imageWithScreenshot{NSData*imageData = [selfdataWithScreenshotInPNGFormat];return[UIImageimageWithData:imageData];}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容