"凸"圆角,"凹"圆角
2021-02-08 本文已影响0人
山已几孑
image.png如图,也不知道这圆角叫啥,也没搜到,只能拼了一个出来,功能简单,也没啥Demo
。直接贴一个playground.swift, 如果有更好地的办法,也希望能指点下,总觉得还有规律没有找到。
//: A UIKit based Playground for presenting user interface
import UIKit
import PlaygroundSupport
import MachO
class CornerRectView : UIView {
class Corner: Equatable {
static func == (lhs: CornerRectView.Corner, rhs: CornerRectView.Corner) -> Bool {
return lhs.origin.rawValue == rhs.origin.rawValue
}
struct CornerOrigin: OptionSet {
let rawValue: Int
static let bottomRight = CornerOrigin(rawValue: 1)
static let bottomLeft = CornerOrigin(rawValue: 2)
static let topLeft = CornerOrigin(rawValue: 4)
static let topRight = CornerOrigin(rawValue: 8)
}
var origin: CornerOrigin
var cornerRadius: CGFloat = 0
init(origin: CornerOrigin, cornerRadius: CGFloat) {
self.origin = origin
self.cornerRadius = cornerRadius
}
}
override var backgroundColor: UIColor? {
set {
ky_backgroundColor = newValue
self.setNeedsDisplay()
}
get {
return ky_backgroundColor
}
}
private var ky_backgroundColor: UIColor?
let corners: [Corner] = [
Corner(origin: .bottomRight, cornerRadius: 0),
Corner(origin: .bottomLeft, cornerRadius: 0),
Corner(origin: .topLeft, cornerRadius: 0),
Corner(origin: .topRight, cornerRadius: 0)
]
var roundCornerLayer: CALayer?
/// 只提供俩种修改方式,一个是统一修改,传Corner.CornerOrigin就行,
func drawRoundCorner(cornerOrigin: Corner.CornerOrigin, cornerRadius: CGFloat) {
for corner in corners {
if corner.origin .isSubset(of: cornerOrigin) {
corner.cornerRadius = cornerRadius
}
}
self.setNeedsDisplay()
}
/// 只提供俩种修改方式,一个是分别修改,传Corner的数组Corner(origin: .topRight, cornerRadius: 0)
func drawCornerWith(sets:[Corner]) -> Void {
//遍历修改,如果重复就重复修改,务必保证正确
for newCorner in sets {
if let oldCorner = corners.first(where: {newCorner == $0}) {
oldCorner.cornerRadius = newCorner.cornerRadius;
}
}
self.setNeedsDisplay()
}
override func draw(_ rect: CGRect) {
super.draw(rect)
let path2 = UIBezierPath()
// 排一下序,保证按照一定的顺序画角
let sortedCorner = corners.sorted(by: {$0.origin.rawValue < $1.origin.rawValue})
for corner in sortedCorner {
let cornerRadius = corner.cornerRadius
var center: CGPoint
switch corner.origin {
case .bottomRight:
center = CGPoint(x: bounds.maxX - abs(cornerRadius), y: bounds.maxY - abs(cornerRadius))
if path2.isEmpty {
path2.move(to: CGPoint(x: bounds.maxX , y: bounds.maxY - abs(cornerRadius)))
} else {
path2.addLine(to: CGPoint(x: bounds.maxX , y: bounds.maxY - abs(cornerRadius)))
}
if cornerRadius < 0 {
center = center.applying(CGAffineTransform(translationX: -corner.cornerRadius, y: -corner.cornerRadius))
}
case .bottomLeft:
center = CGPoint(x: bounds.minX + abs(cornerRadius), y: bounds.maxY - abs(cornerRadius))
if path2.isEmpty {
path2.move(to: CGPoint(x: bounds.minX + abs(cornerRadius), y: bounds.maxY))
} else {
path2.addLine(to: CGPoint(x: bounds.minX + abs(cornerRadius), y: bounds.maxY))
}
if cornerRadius < 0 {
center = center.applying(CGAffineTransform(translationX: corner.cornerRadius, y: -corner.cornerRadius))
}
case .topLeft:
center = CGPoint(x: bounds.minX + abs(cornerRadius), y: bounds.minY + abs(cornerRadius))
if path2.isEmpty {
path2.move(to: CGPoint(x: bounds.minX, y: bounds.minY + abs(cornerRadius)))
} else {
path2.addLine(to: CGPoint(x: bounds.minX, y: bounds.minY + abs(cornerRadius)))
}
if cornerRadius < 0 {
center = center.applying(CGAffineTransform(translationX: corner.cornerRadius, y: corner.cornerRadius))
}
case .topRight:
center = CGPoint(x: bounds.maxX - abs(cornerRadius), y: bounds.minY + abs(cornerRadius))
if path2.isEmpty {
path2.move(to: CGPoint(x: bounds.maxX - abs(cornerRadius), y: bounds.minY))
} else {
path2.addLine(to: CGPoint(x: bounds.maxX - abs(cornerRadius), y: bounds.minY))
}
if cornerRadius < 0 {
center = center.applying(CGAffineTransform(translationX: -corner.cornerRadius, y: corner.cornerRadius))
}
default:
center = .zero
}
let index = log2(CGFloat(corner.origin.rawValue)); // 3
var startAngle = CGFloat.pi * 0.5 * index //CGFloat.pi * 1
var endAngle = CGFloat.pi * 0.5 * (index + 1)
if cornerRadius < 0 {
swap(&startAngle, &endAngle)
}
path2.addArc(withCenter: center, radius: cornerRadius, startAngle: startAngle, endAngle: endAngle, clockwise: cornerRadius > 0)
}
path2.close()
let shapeLayer = CAShapeLayer()
shapeLayer.path = path2.cgPath
let backgroundLayer = CALayer()
backgroundLayer.frame = rect
backgroundLayer.backgroundColor = (ky_backgroundColor ?? UIColor.white).cgColor
backgroundLayer.mask = shapeLayer
if self.roundCornerLayer != nil {
self.roundCornerLayer?.removeFromSuperlayer()
}
self.roundCornerLayer = backgroundLayer
self.layer.insertSublayer(backgroundLayer, at: 0)
}
}
class MyViewController : UIViewController {
var cornerView: CornerRectView!
override func loadView() {
let view = UIView()
view.backgroundColor = .white
self.view = view
// 第一个View
let label = CornerRectView(frame: CGRect(x: 50, y: 40, width: 100, height: 100))
label.backgroundColor = UIColor.yellow
label.drawCornerWith(sets: [CornerRectView.Corner(origin: .topLeft, cornerRadius: 20),
CornerRectView.Corner(origin: .topRight, cornerRadius: 20),
CornerRectView.Corner(origin: .bottomRight, cornerRadius: -20),
CornerRectView.Corner(origin: .bottomLeft, cornerRadius: -20)])
view.addSubview(label)
// 第二个View
let label11 = CornerRectView(frame: CGRect(x: 250, y: 40, width: 100, height: 100))
label11.backgroundColor = UIColor.purple
label11.drawCornerWith(sets: [CornerRectView.Corner(origin: .topLeft, cornerRadius: -20),
CornerRectView.Corner(origin: .topRight, cornerRadius: 0),
CornerRectView.Corner(origin: .bottomRight, cornerRadius: 20),
CornerRectView.Corner(origin: .bottomLeft, cornerRadius: 0)])
view.addSubview(label11)
// 第三个View
let view2 = CornerRectView(frame: CGRect(x: 50, y: 300, width: 100, height: 100))
view2.drawRoundCorner(cornerOrigin: [.bottomLeft,.bottomRight, .topLeft, .topRight], cornerRadius: -10)
view2.backgroundColor = UIColor.blue
view2.layer.shadowColor = UIColor.black.cgColor
view2.layer.shadowRadius = 10
view2.layer.shadowOpacity = 1
view.addSubview(view2)
// 第四个View
let view21 = CornerRectView(frame: CGRect(x: 250, y: 300, width: 100, height: 100))
view21.drawRoundCorner(cornerOrigin: [.bottomLeft,.bottomRight, .topLeft, .topRight], cornerRadius: 20)
view21.backgroundColor = UIColor.orange
view21.layer.shadowColor = UIColor.black.withAlphaComponent(0.3).cgColor
view21.layer.shadowRadius = 10
view21.layer.shadowOpacity = 1
view.addSubview(view21)
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()