Skip to content

Instantly share code, notes, and snippets.

@kylebshr
Last active September 28, 2025 02:20
Show Gist options
  • Select an option

  • Save kylebshr/27d272d3bb86e07053bf06f39a4de6f4 to your computer and use it in GitHub Desktop.

Select an option

Save kylebshr/27d272d3bb86e07053bf06f39a4de6f4 to your computer and use it in GitHub Desktop.
SwiftUI Shape that will be a capsule up to a maximum corner radius. Useful for capsule UI that should adapt to a rounded rect past a certain scale.
//
// AdaptiveCapsule.swift
// Design
//
// Created by Kyle Bashour on 8/21/25.
//
import SwiftUI
/// Will draw as a capsule up to a maximum corner radius, after which it draws as a rounded rect.
public struct AdaptiveCapsule: InsettableShape {
public var maximumCornerRadius: CGFloat?
public var style: RoundedCornerStyle
private var insetAmount: CGFloat = 0
public init(maximumCornerRadius: CGFloat? = nil, style: RoundedCornerStyle = .continuous) {
self.maximumCornerRadius = maximumCornerRadius
self.style = style
}
public func path(in rect: CGRect) -> Path {
let insetRect = rect.insetBy(dx: insetAmount, dy: insetAmount)
var cornerRadius = min(insetRect.width, insetRect.height) / 2
if let maximumCornerRadius {
let insetMaximumCornerRadius = maximumCornerRadius - insetAmount
cornerRadius = min(insetMaximumCornerRadius, cornerRadius)
}
return Path(roundedRect: insetRect, cornerRadius: cornerRadius, style: style)
}
public func inset(by amount: CGFloat) -> AdaptiveCapsule {
var copy = self
copy.insetAmount += amount
return copy
}
}
#Preview {
VStack {
ZStack {
RoundedRectangle(cornerRadius: 40)
RoundedRectangle(cornerRadius: 40)
.inset(by: 20)
Text("RoundedRectangle")
.foregroundStyle(.black)
}
ZStack {
AdaptiveCapsule(maximumCornerRadius: 40)
AdaptiveCapsule(maximumCornerRadius: 40)
.inset(by: 20)
Text("Matches RoundedRectangle Insetting")
.foregroundStyle(.black)
}
ZStack {
AdaptiveCapsule(maximumCornerRadius: nil)
AdaptiveCapsule(maximumCornerRadius: nil)
.inset(by: 20)
Text("Capsule Behavior")
.foregroundStyle(.black)
}
VStack {
HStack {
AdaptiveCapsule(maximumCornerRadius: nil)
AdaptiveCapsule(maximumCornerRadius: nil)
AdaptiveCapsule(maximumCornerRadius: nil)
AdaptiveCapsule(maximumCornerRadius: nil)
AdaptiveCapsule(maximumCornerRadius: nil)
}
Text("Vertical Capsules")
.foregroundStyle(.black)
}
}
.padding()
.foregroundStyle(.blue.opacity(0.5))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment