Cocoa: 将 NSView 掩码设置为 CAShapeLayer
Cocoa: Set NSView mask as CAShapeLayer
您好,我正在尝试将 CAShapeLayer
设置为 NSView
。但是我无法在 draw(_ dirtyRect: NSRect)
函数之外设置 CAShapeLayer
的角半径。
我必须使用 CAShapeLayer
来设置 NSBezierPath
来绘制自定义形状。所以,只有我使用 CAShapeLayer
而不是 NSView 的默认 CALayer
.
代码如下:
扩展 NSBezierPath
extension NSBezierPath {
var cgPath: CGPath {
let path = CGMutablePath()
var points = [CGPoint](repeating: .zero, count: 3)
for i in 0 ..< elementCount {
let type = element(at: i, associatedPoints: &points)
switch type {
case .moveTo: path.move(to: points[0])
case .lineTo: path.addLine(to: points[0])
case .curveTo: path.addCurve(to: points[2], control1: points[0], control2: points[1])
case .closePath: path.closeSubpath()
@unknown default:
fatalError("Unknown!")
}
}
return path
}
}
CustomView.swift
class CustomView: NSView{
let shapeLayer = CAShapeLayer()
var cornerRadius: CGFloat {
set{
let path = NSBezierPath(roundedRect: bounds, xRadius: newValue, yRadius: newValue)
shapeLayer.path = path.cgPath
path.close()
}
get{
return shapeLayer.cornerRadius
}
}
var backgroundColor: NSColor{
set{
shapeLayer.fillColor = newValue.cgColor
}
get{
return NSColor(cgColor: shapeLayer.backgroundColor ?? .clear)!
}
}
init() {
super.init(frame: .zero)
wantsLayer = true
shapeLayer.masksToBounds = true
layer?.addSublayer(shapeLayer)
// layer?.mask = shapeLayer
// layer?.masksToBounds = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ dirtyRect: NSRect) {
shapeLayer.frame = dirtyRect
let path = NSBezierPath(rect: dirtyRect)
shapeLayer.path = path.cgPath
// shapeLayer.cornerRadius = 22
shapeLayer.borderColor = NSColor.black.cgColor
shapeLayer.borderWidth = 2.0
path.close()
}
}
ViewController.swift
class ViewController: NSViewController {
private lazy var customView: CustomView = {
let customView = CustomView()
view.addSubview(customView)
customView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
customView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
customView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
customView.heightAnchor.constraint(equalToConstant: 44),
customView.widthAnchor.constraint(equalToConstant: 144)
])
return customView
}()
override func viewDidLoad() {
super.viewDidLoad()
// customView.layer?.cornerRadius = 22
customView.backgroundColor = .red
customView.cornerRadius = 22
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}
当前输出:
预期输出:
Code is commented in the attached codes..
请帮我解决这个问题。提前谢谢你...
下面是一个简单的例子。首先,绘制一个简单的矩形,其子类为 NSView
。所以实例化它以使用视图控制器创建一个对象。然后使用对象的图层使其成为具有描边颜色的圆形矩形。
// Subclass of `NSView` //
import Cocoa
class MyView: NSView {
var fillColor: NSColor
init(frame: CGRect, fillColor: NSColor){
self.fillColor = fillColor
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ rect: NSRect) {
super.draw(rect)
let path = NSBezierPath()
path.move(to: CGPoint.zero)
path.line(to: CGPoint(x: 0.0, y: self.frame.height))
path.line(to: CGPoint(x: self.frame.width, y: self.frame.height))
path.line(to: CGPoint(x: self.frame.width, y: 0.0))
path.line(to: CGPoint.zero)
fillColor.set()
path.fill()
}
}
// View controller //
import Cocoa
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
let rect = CGRect(origin: CGPoint(x: 50, y: 50), size: CGSize(width: 200, height: 50))
let myView = MyView(frame: rect, fillColor: NSColor.red)
myView.wantsLayer = true
if let myLayer = myView.layer {
myLayer.cornerRadius = 24.0
myLayer.borderWidth = 4.0
//myLayer.borderColor = NSColor.green.cgColor
}
view.addSubview(myView)
}
}
您好,我正在尝试将 CAShapeLayer
设置为 NSView
。但是我无法在 draw(_ dirtyRect: NSRect)
函数之外设置 CAShapeLayer
的角半径。
我必须使用 CAShapeLayer
来设置 NSBezierPath
来绘制自定义形状。所以,只有我使用 CAShapeLayer
而不是 NSView 的默认 CALayer
.
代码如下:
扩展 NSBezierPath
extension NSBezierPath {
var cgPath: CGPath {
let path = CGMutablePath()
var points = [CGPoint](repeating: .zero, count: 3)
for i in 0 ..< elementCount {
let type = element(at: i, associatedPoints: &points)
switch type {
case .moveTo: path.move(to: points[0])
case .lineTo: path.addLine(to: points[0])
case .curveTo: path.addCurve(to: points[2], control1: points[0], control2: points[1])
case .closePath: path.closeSubpath()
@unknown default:
fatalError("Unknown!")
}
}
return path
}
}
CustomView.swift
class CustomView: NSView{
let shapeLayer = CAShapeLayer()
var cornerRadius: CGFloat {
set{
let path = NSBezierPath(roundedRect: bounds, xRadius: newValue, yRadius: newValue)
shapeLayer.path = path.cgPath
path.close()
}
get{
return shapeLayer.cornerRadius
}
}
var backgroundColor: NSColor{
set{
shapeLayer.fillColor = newValue.cgColor
}
get{
return NSColor(cgColor: shapeLayer.backgroundColor ?? .clear)!
}
}
init() {
super.init(frame: .zero)
wantsLayer = true
shapeLayer.masksToBounds = true
layer?.addSublayer(shapeLayer)
// layer?.mask = shapeLayer
// layer?.masksToBounds = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ dirtyRect: NSRect) {
shapeLayer.frame = dirtyRect
let path = NSBezierPath(rect: dirtyRect)
shapeLayer.path = path.cgPath
// shapeLayer.cornerRadius = 22
shapeLayer.borderColor = NSColor.black.cgColor
shapeLayer.borderWidth = 2.0
path.close()
}
}
ViewController.swift
class ViewController: NSViewController {
private lazy var customView: CustomView = {
let customView = CustomView()
view.addSubview(customView)
customView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
customView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
customView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
customView.heightAnchor.constraint(equalToConstant: 44),
customView.widthAnchor.constraint(equalToConstant: 144)
])
return customView
}()
override func viewDidLoad() {
super.viewDidLoad()
// customView.layer?.cornerRadius = 22
customView.backgroundColor = .red
customView.cornerRadius = 22
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}
当前输出:
预期输出:
Code is commented in the attached codes..
请帮我解决这个问题。提前谢谢你...
下面是一个简单的例子。首先,绘制一个简单的矩形,其子类为 NSView
。所以实例化它以使用视图控制器创建一个对象。然后使用对象的图层使其成为具有描边颜色的圆形矩形。
// Subclass of `NSView` //
import Cocoa
class MyView: NSView {
var fillColor: NSColor
init(frame: CGRect, fillColor: NSColor){
self.fillColor = fillColor
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ rect: NSRect) {
super.draw(rect)
let path = NSBezierPath()
path.move(to: CGPoint.zero)
path.line(to: CGPoint(x: 0.0, y: self.frame.height))
path.line(to: CGPoint(x: self.frame.width, y: self.frame.height))
path.line(to: CGPoint(x: self.frame.width, y: 0.0))
path.line(to: CGPoint.zero)
fillColor.set()
path.fill()
}
}
// View controller //
import Cocoa
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
let rect = CGRect(origin: CGPoint(x: 50, y: 50), size: CGSize(width: 200, height: 50))
let myView = MyView(frame: rect, fillColor: NSColor.red)
myView.wantsLayer = true
if let myLayer = myView.layer {
myLayer.cornerRadius = 24.0
myLayer.borderWidth = 4.0
//myLayer.borderColor = NSColor.green.cgColor
}
view.addSubview(myView)
}
}