Skip to content

Instantly share code, notes, and snippets.

@juliensagot
Last active July 14, 2020 09:15
Show Gist options
  • Save juliensagot/d3c8585bf4929b16facb23f64ec84b41 to your computer and use it in GitHub Desktop.
Save juliensagot/d3c8585bf4929b16facb23f64ec84b41 to your computer and use it in GitHub Desktop.
SwiftUI subpixel alignment stroke animation issue
import SwiftUI
struct TestCard: View {
private let cornerRadius: CGFloat = 12
@Environment(\.displayScale) private var displayScale
@State private var isSelected = false
var body: some View {
GeometryReader { geometry in
Button(action: {
isSelected.toggle()
},
label: {
Rectangle()
.foregroundColor(Color.gray)
.clipShape(RoundedRectangle(cornerRadius: cornerRadius, style: .continuous))
.overlay(selectionOverlayView(in: geometry))
})
}
}
private func selectionOverlayView(in geometry: GeometryProxy) -> some View {
let lineWidth: CGFloat = 2.5
let spacing: CGFloat = 1.5
let bounds = CGRect(origin: .zero, size: geometry.size)
let inset = spacing + (lineWidth / 2)
let selectionRect = bounds.inset(by: UIEdgeInsets(top: -inset, left: -inset, bottom: -inset, right: -inset))
let offset = (spacing + (lineWidth / 2)).rounded(.up) - (spacing + (lineWidth / 2))
return RoundedRectangle(cornerRadius: cornerRadius + spacing + (lineWidth / 2), style: .continuous)
.stroke(Color.red, lineWidth: isSelected ? lineWidth : 0)
.animation(.linear(duration: 0.800))
.frame(width: selectionRect.width, height: selectionRect.height, alignment: .center)
.offset(x: -offset, y: -offset) // Fixes alignment
}
}
struct TestCard_Previews: PreviewProvider {
static var previews: some View {
TestCard()
.frame(width: 100, height: 135)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment