iOS Swift 仿微信聊天圖片顯示

LinXunFeng發表於2017-12-14

效果圖

如圖所示,圖片左側有個小箭頭

效果圖

原理

其實原理比較簡單,準備一張圖片MaskImgae,先對其進行拉伸,然後按照其輪廓對圖片進行裁剪就行了

MaskImgae

步驟

這裡摘重點說,佈局什麼的按自己意願去弄吧。我固定了圖片的顯示大小為 102 * 152

1、對MaskImgae進行拉伸

// 設定拉伸範圍
let stretchInsets = UIEdgeInsetsMake(30, 28, 23, 28)
// 待拉伸的圖片
let stretchImage = UIImage(named: "SenderImageNodeMask")
// 進行拉伸
let bubbleMaskImage = stretchImage.resizableImage(withCapInsets: stretchInsets, resizingMode: .stretch)
複製程式碼

拉伸的效果如圖

拉伸效果

2、對imageView設定裁剪區域

這裡我的 imageView 叫 chatImgView 上面的拉伸效果圖是臨時把拉伸好的圖片賦值給了chatImgView,只是為了給大家看到效果而已,各位看官如果有賦值請記得改回來~~

好,下面進行裁剪

// 新建一個圖層
let layer = CALayer()
// 設定圖層顯示的內容為拉伸過的MaskImgae
layer.contents = bubbleMaskImage.cgImage
// 設定拉伸範圍(注意:這裡contentsCenter的CGRect是比例(不是絕對座標))
layer.contentsCenter = self.CGRectCenterRectForResizableImage(bubbleMaskImage)
// 設定圖層大小與chatImgView相同
layer.frame = CGRect(x: 0, y: 0, width: 102, height: 152)
// 設定比例
layer.contentsScale = UIScreen.main.scale
// 設定不透明度
layer.opacity = 1
// 設定裁剪範圍
self.chatImgView.layer.mask = layer
// 設定裁剪掉超出的區域
self.chatImgView.layer.masksToBounds = true
複製程式碼
func CGRectCenterRectForResizableImage(_ image: UIImage) -> CGRect {
    // LXFLog("\(image.capInsets)")
    // 這裡的image.capInsets就是UIEdgeInsetsMake(30, 28, 23, 28)
    return CGRect(
        x: image.capInsets.left / image.size.width,
        y: image.capInsets.top / image.size.height,
        width: (image.size.width - image.capInsets.right - image.capInsets.left) / image.size.width,
        height: (image.size.height - image.capInsets.bottom - image.capInsets.top) / image.size.height
    )
}
複製程式碼

這樣就完成了

解釋一下下

UIEdgeInsetsMake

MaskImgae 的大小為 56 * 50

// UIEdgeInsetsMake(top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat)
UIEdgeInsetsMake(30, 28, 23, 28)
複製程式碼

紅色範圍就是要拉伸的範圍(隨手一扣,不太準確,意思意思下就好了~~)

拉伸區域

contentsCenter

這是對某個區域進行全面拉伸,如果不設定的話預設值為

CGRect(x: 0, y: 0, width: 1, height: 1)
複製程式碼

就是直接進行縮放 那我們先來看看,如果不對contentsCenter這個值進行設定會是什麼效果

直接拉伸
我們來看下官方解釋

var contentsCenter: CGRect { get set }
Description	
The rectangle that defines how the layer contents are scaled
if the layer’s contents are resized. Animatable.
複製程式碼

翻譯:如果圖層的內容是重新設定了尺寸的,那定義的這個矩形(contentsCenter)是為了告訴圖層,圖層的內容是如何被縮放的

那明瞭,我們的圖片是被拉伸後再繪製到layer上的,為了正確顯示我們的圖片,我們得告訴layer它是怎麼被進行拉伸的。是的,就是下面程式碼所指定的範圍

UIEdgeInsetsMake(30, 28, 23, 28)
複製程式碼

但是,正如上面提到過的,contentsCenter所要賦值的CGRect是比例,不是絕對座標,所以現在我們得通過(30, 28, 23, 28)獲取比例值,轉換方法已經在上面給出了,就是CGRectCenterRectForResizableImage 我們來列印下 image.capInsets的內容

LXFLog("\(image.capInsets)")
LXFLog("\(image.capInsets.top)")
LXFLog("\(image.capInsets.bottom)")
LXFLog("\(image.capInsets.left)")
LXFLog("\(image.capInsets.right)")
複製程式碼

列印結果

UIEdgeInsets(top: 30.0, left: 28.0, bottom: 23.0, right: 28.0)
30.0
23.0
28.0
28.0
複製程式碼

好,現在結合 下面的圖 與 CGRectCenterRectForResizableImage 方法中的程式碼就很明確比例是怎麼取到的了

拉伸區域

附上相關專案:Swift 3.0 高仿微信

iOS   Swift 仿微信聊天圖片顯示

微信公眾號

相關文章