Skip to content

Commit

Permalink
Merge pull request #247 from square/gabrielh/Box-specific-corner-radius
Browse files Browse the repository at this point in the history
Specific rounded corners for Box.CornerStyle.rounded
  • Loading branch information
gabreho committed Aug 9, 2021
2 parents 4428e60 + d23bad2 commit ee6310f
Showing 1 changed file with 94 additions and 3 deletions.
97 changes: 94 additions & 3 deletions BlueprintUICommonControls/Sources/Box.swift
Expand Up @@ -47,6 +47,10 @@ public struct Box: Element {
if self.backgroundColor != view.backgroundColor {
view.backgroundColor = self.backgroundColor
}

if self.cornerStyle.cornerMask != view.layer.maskedCorners {
view.layer.maskedCorners = self.cornerStyle.cornerMask
}

if self.cornerStyle.radius(for: context.bounds) != view.layer.cornerRadius {
view.layer.cornerRadius = self.cornerStyle.radius(for: context.bounds)
Expand All @@ -60,6 +64,10 @@ public struct Box: Element {
view.layer.borderWidth = self.borderStyle.width
}

if self.cornerStyle.shadowRoundedCorners != view.shadowRoundCorners {
view.shadowRoundCorners = self.cornerStyle.shadowRoundedCorners
}

if self.shadowStyle.radius != view.layer.shadowRadius {
view.layer.shadowRadius = self.shadowStyle.radius
}
Expand Down Expand Up @@ -103,7 +111,66 @@ extension Box {
public enum CornerStyle {
case square
case capsule
case rounded(radius: CGFloat)
case rounded(radius: CGFloat, corners: Corners = .all)

public struct Corners: OptionSet {
public let rawValue: UInt8

public init(rawValue: UInt8) {
self.rawValue = rawValue
}

public static let topLeft = Corners(rawValue: 1)
public static let topRight = Corners(rawValue: 1 << 1)
public static let bottomLeft = Corners(rawValue: 1 << 2)
public static let bottomRight = Corners(rawValue: 1 << 3)

public static var all: Corners = [.topLeft, .topRight, .bottomLeft, .bottomRight]
public static var top: Corners = [.topRight, .topLeft]
public static var left: Corners = [.topLeft, .bottomLeft]
public static var bottom: Corners = [.bottomLeft, .bottomRight]
public static var right: Corners = [.topRight, .bottomRight]

var toCACornerMask: CACornerMask {
var mask: CACornerMask = []
if self.contains(.topLeft) {
mask.update(with: .layerMinXMinYCorner)
}

if self.contains(.topRight) {
mask.update(with: .layerMaxXMinYCorner)
}

if self.contains(.bottomLeft) {
mask.update(with: .layerMinXMaxYCorner)
}

if self.contains(.bottomRight) {
mask.update(with: .layerMaxXMaxYCorner)
}
return mask
}

var toUIRectCorner: UIRectCorner {
var rectCorner: UIRectCorner = []
if self.contains(.topLeft) {
rectCorner.update(with: .topLeft)
}

if self.contains(.topRight) {
rectCorner.update(with: .topRight)
}

if self.contains(.bottomLeft) {
rectCorner.update(with: .bottomLeft)
}

if self.contains(.bottomRight) {
rectCorner.update(with: .bottomRight)
}
return rectCorner
}
}
}

public enum BorderStyle {
Expand Down Expand Up @@ -146,12 +213,29 @@ extension Box.CornerStyle {
return 0
case .capsule:
return min(bounds.width, bounds.height) / 2
case let .rounded(radius: radius):
case let .rounded(radius: radius, _):
let maximumRadius = min(bounds.width, bounds.height) / 2
return min(maximumRadius, radius)
}
}

fileprivate var cornerMask: CACornerMask {
switch self {
case .square, .capsule:
return Corners.all.toCACornerMask
case let .rounded(_, corners):
return corners.toCACornerMask
}
}

fileprivate var shadowRoundedCorners: UIRectCorner {
switch self {
case .square, .capsule:
return Corners.all.toUIRectCorner
case let .rounded(_, corners):
return corners.toUIRectCorner
}
}
}

extension Box.BorderStyle {
Expand Down Expand Up @@ -220,6 +304,8 @@ extension Box.ShadowStyle {
fileprivate final class BoxView: UIView {

let contentView = UIView()

var shadowRoundCorners: UIRectCorner = .allCorners

override init(frame: CGRect) {
super.init(frame: frame)
Expand All @@ -236,9 +322,14 @@ fileprivate final class BoxView: UIView {
contentView.frame = bounds

if layer.shadowColor != nil {
let cornerRadii = CGSize(
width: layer.cornerRadius,
height: layer.cornerRadius
)
layer.shadowPath = UIBezierPath(
roundedRect: bounds,
cornerRadius: layer.cornerRadius
byRoundingCorners: shadowRoundCorners,
cornerRadii: cornerRadii
).cgPath
}
}
Expand Down

0 comments on commit ee6310f

Please sign in to comment.