iOS實(shí)現(xiàn)簡(jiǎn)單長(zhǎng)截圖
本文實(shí)例為大家分享了iOS實(shí)現(xiàn)簡(jiǎn)易的長(zhǎng)截圖的具體代碼,供大家參考,具體內(nèi)容如下
長(zhǎng)截圖的實(shí)現(xiàn)原理:
實(shí)際上是將view的內(nèi)容繪制成圖片,再將各個(gè)view繪制出來的圖片拼接出來。
具體代碼:
將view繪制成圖片
func getImage(in view:UIView?) -> UIImage? { ?? ?guard let view = view else {return nil} ?? ?let size = view.bounds.size ?? ?UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale) ?? ?view.layer.render(in: UIGraphicsGetCurrentContext()!) ?? ?view.layer.contents = nil ?? ?let image = UIGraphicsGetImageFromCurrentImageContext() ?? ?UIGraphicsEndImageContext() ?? ?return image }
1.繪制狀態(tài)欄
// 先獲取狀態(tài)欄view func getStatusBar() -> UIView? { ?? ?if Float(UIDevice.current.systemVersion)! >= 13 { ? ? ? ? guard let statusBarManager = UIApplication.shared.keyWindow?.windowScene?.statusBarManager, ? ? ? ? ? ? ? let localStatusBar = statusBarManager.value(forKey: "createLocalStatusBar") as? NSObject, ? ? ? ? ? ? ? let statusBar = localStatusBar.value(forKey: "statusBar") as? UIView else {return nil} ? ? ? ? return statusBar ? ? } else { ? ? ? ? guard let statusBarWindow = UIApplication.shared.value(forKey: "statusBarWindow") as? UIWindow ?else {return nil} ? ? ? ? let statusBar = statusBarWindow.value(forKey: "statusBar") as? UIView ? ? ? ? return statusBar ? ? } } // 再繪制成圖片 let statusBarImage = getImage(in: getStatusBar())
2.繪制導(dǎo)航欄(如果有的話)
if let nav = vc.navigationController { // 表示有導(dǎo)航欄 ? ? let navBar = nav.navigationBar ? ? let navBarImage = getImage(in: navBar) }
在某些情況下,如自定義的導(dǎo)航欄,則需要另外自行獲取view再來繪制
3.繪制ScrollView
繪制scrollview長(zhǎng)圖的時(shí)候,如果直接繪制的話,那么得到的圖片就是scrollview的frame.size大小的圖片,而沒有滾動(dòng)到的地方則不會(huì)繪制進(jìn)去,所以要先將scrollview的size變成和contentSize一樣
func getScrollViewImage(scrollView:UIScrollView?) -> UIImage? { ? ? if let scroll = scrollView { ? ? ? ? let saveOffset = scroll.contentOffset // 保存偏移量,用于繪制圖片完成后還原 ? ? ? ? let saveFrame = scroll.frame // 保存frame ? ? ? ? scroll.contentOffset = CGPoint.zero ? ? ? ? scroll.frame = CGRect(origin: saveFrame.origin, size: scroll.contentSize) // 設(shè)置size和contentSize一致 ? ? ? ?? ? ? ? ? UIGraphicsBeginImageContext(scroll.frame.size) ? ? ? ? UIGraphicsBeginImageContextWithOptions(CGSize(width: scroll.frame.size.width, height: scroll.frame.size.height), false, UIScreen.main.scale) ? ? ? ? scroll.layer.render(in: UIGraphicsGetCurrentContext()!) ? ? ? ? let scrollImage = UIGraphicsGetImageFromCurrentImageContext() ? ? ? ? UIGraphicsEndImageContext() ? ? ? ?? ? ? ? ? scroll.contentOffset = saveOffset // 還原偏移量,否則繪制圖片之后,scrollview偏移量不正確 ? ? ? ? scroll.frame = saveFrame // 還原frame ? ? ? ? return scrollImage ? ? } ? ? return nil }
到這里,其實(shí)最難的一步已經(jīng)完成了,但是這個(gè)方法也不是完美的。當(dāng)這個(gè)scrollview添加到父視圖的時(shí)候是添加約束的方式來確定大小和位置的時(shí)候,使用這個(gè)方法繪制出來的圖片大小沒有問題,但是內(nèi)容卻可能只有屏幕上顯示出來的部分多一點(diǎn),其他部分是空白。具體原因我也不太清楚,只要在繪制成圖片之前將約束移除,繪制之后再添加回來
func getScrollViewImage(scrollView:UIScrollView?) -> UIImage? { ? ? if let scroll = scrollView { ? ? ? ? let saveOffset = scroll.contentOffset // 保存偏移量,用于繪制圖片完成后還原 ? ? ? ? let saveFrame = scroll.frame // 保存frame ? ? ? ? scroll.contentOffset = CGPoint.zero ? ? ? ? scroll.frame = CGRect(origin: saveFrame.origin, size: scroll.contentSize) // 設(shè)置size和contentSize一致 ? ? ? ? let layouts = scroll.superview!.constraints // 獲取的是scrollview的父容器的約束,這才是約束scrollview大小和位置的正確約束 ? ? ? ? scroll.superview?.removeConstraints(layouts) ? ? ? ?? ? ? ? ? UIGraphicsBeginImageContext(scroll.frame.size) ? ? ? ? UIGraphicsBeginImageContextWithOptions(CGSize(width: scroll.frame.size.width, height: scroll.frame.size.height), false, UIScreen.main.scale) ? ? ? ? scroll.layer.render(in: UIGraphicsGetCurrentContext()!) ? ? ? ? let scrollImage = UIGraphicsGetImageFromCurrentImageContext() ? ? ? ? UIGraphicsEndImageContext() ? ? ? ?? ? ? ? ? scroll.contentOffset = saveOffset // 還原偏移量,否則繪制圖片之后,scrollview偏移量不正確 ? ? ? ? scroll.frame = saveFrame // 還原frame ? ? ? ? scroll.superview?.addConstraints(layouts) // 還原約束 ? ? ? ? return scrollImage ? ? } ? ? return nil }
如果項(xiàng)目中集成了SnapKit的話可以用其給scrollview重新設(shè)置約束,繪制圖片結(jié)束后在還原也可以
func getScrollViewImage(scrollView:UIScrollView?) -> UIImage? { ? ? if let scroll = scrollView { ? ? ? ?? ?? ??? ?// ...... ? ? ? ? let layouts = scroll.superview!.constraints // 獲取的是scrollview的父容器的約束,這才是約束scrollview大小和位置的正確約束 ? ? ? ? scroll.snp.remakeConstraints { (make) in ? ? ? ? ? ? make.top.left.right.equalTo(0) ? ? ? ? ? ? make.height.equalTo(scroll.contentSize.height) ? ? ? ? } ? ? ? ?? ? ? ? ? // ......? ? ? ? ?? ? ? ? ? scroll.snp.removeConstraints() ? ? ? ? scroll.superview?.addConstraints(layouts) // 還原約束 ? ? ? ?? ? ? ? ? return scrollImage ? ? } ? ? return nil }
4.拼接圖片
已經(jīng)得到了所需要的各個(gè)部分的元素,這里按照上下位置將其拼接起來
func combineImages(with upImage:UIImage?, and downImage:UIImage?) -> UIImage? { ? ? if upImage == nil { ? ? ? ? return downImage ? ? } ? ? if downImage == nil { ? ? ? ? return upImage ? ? } ? ? guard let up = upImage, ? ? ? ? ? let down = downImage else {return nil} ? ? let size = CGSize(width: up.size.width, height: up.size.height + down.size.height) ? ? UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale) ? ?? ? ? let upRect = CGRect(origin: CGPoint(x: 0, y: 0), size: up.size) ? ? up.draw(in: upRect) ? ? let downRect = CGRect(x: (up.size.width - down.size.width) / 2, y: upRect.origin.y + upRect.size.height, width: down.size.width, height: down.size.height) ? ? down.draw(in: downRect) ? ?? ? ? let result = UIGraphicsGetImageFromCurrentImageContext() ? ? UIGraphicsEndImageContext() ? ? return result }
這里是圖片的上下拼接,左右拼接與這個(gè)類似,只需要計(jì)算好圖片的左右位置即可。
效果圖:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
IOS實(shí)現(xiàn)驗(yàn)證碼倒計(jì)時(shí)功能(一)
這篇文章主要介紹了IOS實(shí)現(xiàn)驗(yàn)證碼倒計(jì)時(shí)功能,點(diǎn)擊獲取驗(yàn)證碼,進(jìn)入時(shí)間倒計(jì)時(shí),感興趣的小伙伴們可以參考一下2016-01-01iOS?GCD之dispatch_group_enter和dispatch_group_leave使用
這篇文章主要為大家介紹了iOS?GCD之dispatch_group_enter和dispatch_group_leave使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03Objective-C中字符串NSString的常用操作方法總結(jié)
這篇文章主要介紹了Objective-C中字符串NSString的常用操作方法總結(jié),Objective-C中NSString和NSMutableString這兩個(gè)類下包含了操作字符串的大多數(shù)方法,需要的朋友可以參考下2016-04-04詳解Obejective-C中將JSON數(shù)據(jù)轉(zhuǎn)為模型的方法
這篇文章主要介紹了Obejective-C中JSON數(shù)據(jù)轉(zhuǎn)為模型的方法,同時(shí)介紹了使用jastor庫(kù)的方法,需要的朋友可以參考下2016-03-03