溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

iOS如何實(shí)現(xiàn)簡單長截圖

發(fā)布時(shí)間:2022-07-21 09:55:03 來源:億速云 閱讀:193 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹了iOS如何實(shí)現(xiàn)簡單長截圖的相關(guān)知識,內(nèi)容詳細(xì)易懂,操作簡單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇iOS如何實(shí)現(xiàn)簡單長截圖文章都會(huì)有所收獲,下面我們一起來看看吧。

長截圖的實(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長圖的時(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ì)算好圖片的左右位置即可。

效果圖:

iOS如何實(shí)現(xiàn)簡單長截圖

iOS如何實(shí)現(xiàn)簡單長截圖

iOS如何實(shí)現(xiàn)簡單長截圖

關(guān)于“iOS如何實(shí)現(xiàn)簡單長截圖”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“iOS如何實(shí)現(xiàn)簡單長截圖”知識都有一定的了解,大家如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

ios
AI