π¨ Selective corner rounding for SwiftUI with style and precision
CornerCraft provides an elegant solution for applying corner rounding to specific corners of SwiftUI views. With fine-grained control, 12 convenient preset modifiers, built-in animations, and a beautiful interactive showcase, it makes selective corner rounding simple, intuitive, and visually stunning.
- π― Selective Corner Control - Round specific corners using UIRectCorner
- π¨ 12 Convenient Presets - Ready-to-use modifiers for all corner combinations
- β¨ Built-in Animations - 6 animation types: easeInOut, spring, linear, easeIn, easeOut, and none
- πΌοΈ Optional Borders - Configurable border color and width
- πͺ Interactive Showcase - Beautiful demo view with live parameter controls
- π SwiftUI Native - Built specifically for SwiftUI with modern APIs
- π¦ Lightweight - Zero dependencies, minimal footprint
import SwiftUI
import CornerCraft
struct ContentView: View {
var body: some View {
VStack(spacing: 20) {
// Round specific corners
Rectangle()
.fill(Color.blue)
.frame(width: 100, height: 100)
.topLeftRounded(radius: 20)
// Round multiple corners with border
Text("Hello, CornerCraft!")
.padding()
.background(Color.gray.opacity(0.2))
.topRounded(radius: 15, borderColor: .blue, borderWidth: 2)
// Built-in animations - no extra .animation() needed!
Rectangle()
.fill(Color.green)
.frame(width: 100, height: 100)
.allRounded(radius: isAnimated ? 50 : 10, animationType: .spring(duration: 0.6, bounce: 0.3))
}
}
}Add CornerCraft to your project using Xcode:
- File β Add Package Dependencies
- Enter:
https://github.com/onlydstn/CornerCraft - Select your desired version
Or add to your Package.swift:
dependencies: [
.package(url: "https://github.com/onlydstn/CornerCraft", from: "1.0.0")
]pod 'CornerCraft', '~> 1.0'- Download the source files
- Add
CornerCraftShape.swiftandCornerCraftModifiers.swiftto your project
The main modifier for custom corner configurations.
func cornerCraft(
_ corners: UIRectCorner,
radius: CGFloat,
borderColor: Color? = nil,
borderWidth: CGFloat = 0,
animationType: CornerCraftAnimationType = .none
) -> some ViewParameters:
corners: UIRectCorner specifying which corners to roundradius: Corner radius valueborderColor: Optional border colorborderWidth: Border width (default: 0)animationType: Animation type for radius changes (default: .none)
Example:
Rectangle()
.cornerCraft([.topLeft, .bottomRight], radius: 25, animationType: .easeInOut(duration: 0.5))CornerCraft includes built-in animation support with 6 animation types:
public enum CornerCraftAnimationType {
case none // No animation
case easeInOut(duration: Double = 0.3) // Smooth ease in and out
case spring(duration: Double = 0.6, bounce: Double = 0.0) // Spring animation with bounce
case linear(duration: Double = 0.3) // Constant speed animation
case easeIn(duration: Double = 0.3) // Slow start, fast end
case easeOut(duration: Double = 0.3) // Fast start, slow end
}Examples:
// Spring animation with bounce
Rectangle()
.allRounded(radius: 20, animationType: .spring(duration: 0.8, bounce: 0.4))
// Smooth ease in-out
Rectangle()
.topRounded(radius: 15, animationType: .easeInOut(duration: 0.5))
// Linear animation
Rectangle()
.bottomLeftRounded(radius: 10, animationType: .linear(duration: 0.3))CornerCraft provides 12 convenient preset modifiers:
.topLeftRounded(radius: CGFloat, animationType: CornerCraftAnimationType = .none)
.topRightRounded(radius: CGFloat, animationType: CornerCraftAnimationType = .none)
.bottomLeftRounded(radius: CGFloat, animationType: CornerCraftAnimationType = .none)
.bottomRightRounded(radius: CGFloat, animationType: CornerCraftAnimationType = .none).topRounded(radius: CGFloat, animationType: CornerCraftAnimationType = .none) // topLeft + topRight
.bottomRounded(radius: CGFloat, animationType: CornerCraftAnimationType = .none) // bottomLeft + bottomRight
.leftRounded(radius: CGFloat, animationType: CornerCraftAnimationType = .none) // topLeft + bottomLeft
.rightRounded(radius: CGFloat, animationType: CornerCraftAnimationType = .none) // topRight + bottomRight.topLeftBottomRightRounded(radius: CGFloat, animationType: CornerCraftAnimationType = .none) // diagonal \
.topRightBottomLeftRounded(radius: CGFloat, animationType: CornerCraftAnimationType = .none) // diagonal /.allRounded(radius: CGFloat, animationType: CornerCraftAnimationType = .none) // all corners
.noneRounded(animationType: CornerCraftAnimationType = .none) // no rounding (rectangular)All preset modifiers support optional border and animation parameters:
.topRounded(radius: 20, borderColor: .blue, borderWidth: 2, animationType: .spring())// Single corner
Rectangle()
.fill(Color.red)
.frame(width: 100, height: 100)
.topLeftRounded(radius: 20)
// Multiple corners
Rectangle()
.fill(Color.blue)
.frame(width: 100, height: 100)
.cornerCraft([.topLeft, .bottomRight], radius: 25)Text("Bordered Content")
.padding()
.background(Color.gray.opacity(0.1))
.topRounded(radius: 12, borderColor: .accentColor, borderWidth: 2)@State private var isExpanded = false
Rectangle()
.fill(LinearGradient(colors: [.blue, .purple], startPoint: .topLeading, endPoint: .bottomTrailing))
.frame(width: 120, height: 120)
.allRounded(radius: isExpanded ? 60 : 12, animationType: .spring(duration: 0.6, bounce: 0.3))
.onTapGesture {
isExpanded.toggle()
}
// Multiple animation types
VStack {
Rectangle().topRounded(radius: animated ? 20 : 5, animationType: .easeInOut())
Rectangle().bottomRounded(radius: animated ? 20 : 5, animationType: .spring())
Rectangle().allRounded(radius: animated ? 20 : 5, animationType: .linear())
}VStack(alignment: .leading, spacing: 12) {
Text("Card Title")
.font(.headline)
Text("Card content goes here...")
.font(.body)
}
.padding()
.background(Color(.systemBackground))
.topRounded(radius: 16)
.shadow(radius: 4)Button("Primary Action") {
// Action
}
.padding(.horizontal, 20)
.padding(.vertical, 12)
.background(Color.accentColor)
.foregroundColor(.white)
.allRounded(radius: 12)TextField("Enter text", text: $text)
.textFieldStyle(.plain)
.padding()
.background(Color(.systemGray6))
.topRounded(radius: 8, borderColor: .gray.opacity(0.3), borderWidth: 1)let cornerRadius = min(geometry.size.width, geometry.size.height) * 0.25
Rectangle()
.fill(Color.orange)
.allRounded(radius: cornerRadius)Rectangle()
.fill(Color.green)
.cornerCraft(
isSpecialMode ? [.topLeft, .bottomRight] : .allCorners,
radius: 20
)Rectangle()
.fill(Color.purple)
.allRounded(radius: UIDevice.current.userInterfaceIdiom == .pad ? 24 : 16)CornerCraft includes a beautiful interactive showcase that demonstrates all features in real-time. The showcase is perfect for:
- Learning: See how each modifier and animation type works
- Experimenting: Test different corner combinations and parameters
- Prototyping: Quickly try ideas before implementing them
import SwiftUI
import CornerCraft
struct ContentView: View {
var body: some View {
CornerCraftShowcase()
}
}- π― Interactive Header Demo: Live preview with real-time parameter changes
- βοΈ Corner Selection: Visual buttons for all corner combinations
- ποΈ Parameter Controls: Sliders for radius and border width
- π¨ Color Picker: Border color selection with visual feedback
- π Animation Demos: Compare all 6 animation types side-by-side
- π± Preset Gallery: Visual showcase of all 12 preset modifiers
- πͺ Real-World Examples: Common UI patterns and use cases
The showcase uses smooth animations and provides immediate visual feedback, making it easy to understand how CornerCraft works and discover the perfect settings for your UI.
- iOS 16.0+
- Swift 5.9+
- Xcode 15.0+
CornerCraft is available under the MIT license. See the LICENSE file for more info.
Created by Dustin Nuzzo
β If you found CornerCraft helpful, please consider giving it a star!

