SwiftUI - Add Border to One Edge of an Image
Demo
Implementation
You can use this modifier on any View
:
.border(width: 5, edges: [.top, .leading], color: .yellow)
With the help of this simple extension:
extension View { func border(width: CGFloat, edges: [Edge], color: Color) -> some View { overlay(EdgeBorder(width: width, edges: edges).foregroundColor(color)) }}
And here is the magic struct behind this:
struct EdgeBorder: Shape { var width: CGFloat var edges: [Edge] func path(in rect: CGRect) -> Path { var path = Path() for edge in edges { var x: CGFloat { switch edge { case .top, .bottom, .leading: return rect.minX case .trailing: return rect.maxX - width } } var y: CGFloat { switch edge { case .top, .leading, .trailing: return rect.minY case .bottom: return rect.maxY - width } } var w: CGFloat { switch edge { case .top, .bottom: return rect.width case .leading, .trailing: return self.width } } var h: CGFloat { switch edge { case .top, .bottom: return self.width case .leading, .trailing: return rect.height } } path.addPath(Path(CGRect(x: x, y: y, width: w, height: h))) } return path }}
If somebody ever needs to just add a quick 1 (or more) sided border to a view (e.g., the top edge, or any random combination of edges), I've found this works well and is tweakable:
top edge:
.overlay(Rectangle().frame(width: nil, height: 1, alignment: .top).foregroundColor(Color.gray), alignment: .top)
leading edge:
.overlay(Rectangle().frame(width: 1, height: nil, alignment: .leading).foregroundColor(Color.gray), alignment: .leading)
etc.
Just tweak the height, width, and edge to produce the combination of borders you want.