view 和 layer 引出來的mask
view和layer 的關系
1、UIView不具備顯示功能,擁有顯示功能的是它內部的圖層即CALayer屬性。當UIView需要顯示到屏幕上時,會調用DrawRect:方法進行繪圖,并且將所有的內容繪制在自己的圖層上CALayer *layer,繪圖完成后,系統會將圖層拷貝到屏幕上,于是就完成了UIView的顯示。
2、UIView 的Layer屬性在系統內部,被維護著三份拷貝。分別是邏輯樹、動畫樹、顯示樹。
* 邏輯樹是代碼可以操作的
* 動畫樹是一個中間層,系統就在這一層上更改屬性,進行各種渲染操作;
* 顯示樹其內容就是當前正被顯示在屏幕上的內容
UIView 本身更像是一個CALayer的管理器,UIView 有個屬性CALayer *layer ,所有從UIView繼承的對象都繼承了該屬性。因此,可以通過layer 屬性對view 進行 轉換、縮放、旋轉等操作 .
3.UIView可以響應事件,Layer不可以.
UIKit使用UIResponder作為響應對象,來響應系統傳遞過來的事件并進行處理。UIApplication、UIViewController、UIView、和所有從UIView派生出來的UIKit類(包括UIWindow)都直接或間接地繼承自UIResponder類。
4、View和CALayer的Frame映射及View如何創建CALayer.
一個 Layer 的 frame 是由它的 anchorPoint,position,bounds,和 transform 共同決定的,而一個 View 的 frame 只是簡單的返回 Layer的 frame,同樣 View 的 center和 bounds 也是返回 Layer 的一些屬性
5、UIView主要是對顯示內容的管理而 CALayer 主要側重顯示內容的繪制。View中frame getter方法,bounds和center,UIView并沒有做什么工作;它只是簡單的各自調用它底層的CALayer的frame,bounds和position方法。
6、基本上你改變一個單獨的 layer 的任何屬性的時候,都會觸發一個從舊的值過渡到新值的簡單動畫(這就是所謂的可動畫 animatable)。然而,如果你改變的是 view 中 layer 的同一個屬性,它只會從這一幀直接跳變到下一幀。盡管兩種情況中都有 layer,但是當 layer 附加在 view 上時,它的默認的隱式動畫的 layer 行為就不起作用了。
animatable;幾乎所有的層的屬性都是隱性可動畫的。你可以在文檔中看到它們的簡介是以 'animatable' 結尾的。這不僅包括了比如位置,尺寸,顏色或者透明度這樣的絕大多數的數值屬性,甚至也囊括了像 isHidden 和 doubleSided 這樣的布爾值。 像 paths 這樣的屬性也是 animatable 的,但是它不支持隱式動畫。
什么是mask
CALayer有一個屬性叫做mask,通常被稱為蒙版圖層,mask類似于子視圖,但卻不是一個普通的子視圖,它本身也是CALayer類型,具有和其他圖層一樣的繪制和布局屬性。
mask 的作用就是讓父圖層與mask重疊的部分區域可見 , 通俗的說就是mask圖層實心的部分將會被保留下來,mask的其余部分則會被拋棄。mask 的backgroundColor必須設置,不設置mask 背景就是透明的,mask 是不會起作用的,但是backgroundColor設置什么顏色無所謂。為一個layer的mask 創建一個新的mask時,這個新的mask不能有superlayer 和sublayer。(官方文檔的說明)
mask 作用
1、.mask 可以配合CAGradientLayer、CAShapeLayer 使用。可以實現蒙層透明度、顯示不同形狀圖層、圖案鏤空、文字變色等等功能。
2.mask在動畫中使用,可以產生很好的動畫效果。
`
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.white
self.view.addSubview(backImg)
self.view.addSubview(iconImgView)
self.iconImgView.layer.mask = maskLayer
}
lazy var backImg: UIImageView = {
let backImg = UIImageView.init(frame: CGRect(x: 0, y: 100, width: self.view.frame.size.width, height: self.view.frame.size.width))
backImg.image = UIImage.init(named: "1")
backImg.contentMode = UIView.ContentMode.scaleAspectFill
return backImg
}()
lazy var iconImgView: UIImageView = {
let iconImgView = UIImageView.init(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height))
iconImgView.image = UIImage.init(named: "2")
iconImgView.contentMode = UIView.ContentMode.scaleAspectFill
let pan:UIPanGestureRecognizer = UIPanGestureRecognizer.init(target: self, action: #selector(panAction(_:)))
iconImgView.addGestureRecognizer(pan)
iconImgView.isUserInteractionEnabled = true
return iconImgView
}()
@objc func panAction(_ pan:UIPanGestureRecognizer) -> Void {
let translation = pan.translation(in: self.iconImgView)
self.iconImgView.center = CGPoint(x: 0 + translation.x, y: 0 + translation.y)
print("--------")
}
lazy var backView: UIView = {
let backView = UIView.init()
backView.backgroundColor = UIColor.gray
backView.frame = CGRect(x: 0, y: 0, width: 100, height: 100);
return backView
}()
lazy var maskLayer:CALayer = {
let maskLayer = CALayer.init()
maskLayer.frame = CGRect(x: 10, y: 20, width: 100, height: 100)
maskLayer.cornerRadius = 50;
maskLayer.backgroundColor = UIColor.red.cgColor
return maskLayer
}()
`
https://blog.csdn.net/u014600626/article/details/99854281
https://blog.csdn.net/u014600626/article/details/99854281