diff --git a/Sources/SkeletonUI/Enumerations/ShapeType.swift b/Sources/SkeletonUI/Enumerations/ShapeType.swift index 9c9c567..43928d6 100644 --- a/Sources/SkeletonUI/Enumerations/ShapeType.swift +++ b/Sources/SkeletonUI/Enumerations/ShapeType.swift @@ -3,6 +3,10 @@ import SwiftUI public enum RoundedType: Equatable { case radius(CGFloat, style: RoundedCornerStyle = .continuous) case size(CGSize, style: RoundedCornerStyle = .continuous) + case corners(topLeadingRadius: CGFloat, + bottomLeadingRadius: CGFloat, + bottomTrailingRadius: CGFloat, + topTrailingRadius: CGFloat) } public enum ShapeType: Equatable { @@ -18,6 +22,18 @@ public enum ShapeType: Equatable { return RoundedRectangle(cornerRadius: radius, style: style) case let .rounded(.size(size, style)): return RoundedRectangle(cornerSize: size, style: style) + case let .rounded(.corners(topLeadingRadius, bottomLeadingRadius, bottomTrailingRadius, topTrailingRadius)): + if #available(iOS 16.0, *) { + return .rect(topLeadingRadius: topLeadingRadius, + bottomLeadingRadius: bottomLeadingRadius, + bottomTrailingRadius: bottomTrailingRadius, + topTrailingRadius: topTrailingRadius) + } else { + return RoundedCorners(topLeadingRadius: topLeadingRadius, + topTrailingRadius: topTrailingRadius, + bottomLeadingRadius: bottomLeadingRadius, + bottomTrailingRadius: bottomTrailingRadius) + } case .rectangle: return Rectangle() case .circle: diff --git a/Sources/SkeletonUI/Shapes/RoundedCorners.swift b/Sources/SkeletonUI/Shapes/RoundedCorners.swift new file mode 100644 index 0000000..075fbaa --- /dev/null +++ b/Sources/SkeletonUI/Shapes/RoundedCorners.swift @@ -0,0 +1,42 @@ +import SwiftUI +import UIKit + +struct RoundedCorners: Shape { + var topLeadingRadius: CGFloat = 0.0 + var topTrailingRadius: CGFloat = 0.0 + var bottomLeadingRadius: CGFloat = 0.0 + var bottomTrailingRadius: CGFloat = 0.0 + + func path(in rect: CGRect) -> Path { + var path = Path() + + let w = rect.size.width + let h = rect.size.height + + // Make sure we do not exceed the size of the rectangle + let tr = min(min(self.topTrailingRadius, h/2), w/2) + let tl = min(min(self.topLeadingRadius, h/2), w/2) + let bl = min(min(self.bottomLeadingRadius, h/2), w/2) + let br = min(min(self.bottomTrailingRadius, h/2), w/2) + + path.move(to: CGPoint(x: w / 2.0, y: 0)) + path.addLine(to: CGPoint(x: w - tr, y: 0)) + path.addArc(center: CGPoint(x: w - tr, y: tr), radius: tr, + startAngle: Angle(degrees: -90), endAngle: Angle(degrees: 0), clockwise: false) + + path.addLine(to: CGPoint(x: w, y: h - br)) + path.addArc(center: CGPoint(x: w - br, y: h - br), radius: br, + startAngle: Angle(degrees: 0), endAngle: Angle(degrees: 90), clockwise: false) + + path.addLine(to: CGPoint(x: bl, y: h)) + path.addArc(center: CGPoint(x: bl, y: h - bl), radius: bl, + startAngle: Angle(degrees: 90), endAngle: Angle(degrees: 180), clockwise: false) + + path.addLine(to: CGPoint(x: 0, y: tl)) + path.addArc(center: CGPoint(x: tl, y: tl), radius: tl, + startAngle: Angle(degrees: 180), endAngle: Angle(degrees: 270), clockwise: false) + path.closeSubpath() + + return path + } +}