網站首頁 編程語言 正文
本文實例為大家分享了iOS實現簡易的長截圖的具體代碼,供大家參考,具體內容如下
長截圖的實現原理:
實際上是將view的內容繪制成圖片,再將各個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.繪制狀態欄
// 先獲取狀態欄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.繪制導航欄(如果有的話)
if let nav = vc.navigationController { // 表示有導航欄
? ? let navBar = nav.navigationBar
? ? let navBarImage = getImage(in: navBar)
}
在某些情況下,如自定義的導航欄,則需要另外自行獲取view再來繪制
3.繪制ScrollView
繪制scrollview長圖的時候,如果直接繪制的話,那么得到的圖片就是scrollview的frame.size大小的圖片,而沒有滾動到的地方則不會繪制進去,所以要先將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) // 設置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
}
到這里,其實最難的一步已經完成了,但是這個方法也不是完美的。當這個scrollview添加到父視圖的時候是添加約束的方式來確定大小和位置的時候,使用這個方法繪制出來的圖片大小沒有問題,但是內容卻可能只有屏幕上顯示出來的部分多一點,其他部分是空白。具體原因我也不太清楚,只要在繪制成圖片之前將約束移除,繪制之后再添加回來
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) // 設置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
}
如果項目中集成了SnapKit的話可以用其給scrollview重新設置約束,繪制圖片結束后在還原也可以
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.拼接圖片
已經得到了所需要的各個部分的元素,這里按照上下位置將其拼接起來
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
}
這里是圖片的上下拼接,左右拼接與這個類似,只需要計算好圖片的左右位置即可。
效果圖:
原文鏈接:https://blog.csdn.net/guchuang2599/article/details/115699095
相關推薦
- 2022-11-21 QT通過C++線程池運行Lambda自定義函數流程詳解_C 語言
- 2022-04-18 pyinstaller打包后,配置文件無法正常讀取的解決_python
- 2023-01-23 重啟后nvidia-smi命令不可執行出現“Make?sure?that?the?latest?NV
- 2022-06-02 C語言基于EasyX庫實現有圖形界面時鐘_C 語言
- 2022-08-31 python中函數的參數詳解_python
- 2022-10-03 React?正確使用useCallback?useMemo的方式_React
- 2022-12-01 可定制React自動完成搜索組件Turnstone實現示例_React
- 2023-01-21 Python?sklearn中的K-Means聚類使用方法淺析_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支