Search code examples
swiftimageuiimageswiftui

SwiftUI - Add Border to One Edge of an Image


It's a pretty straight-forward question - How does one apply a border effect to only the wanted edges of an Image with SwiftUI?

For example, I only want to apply a border to the top and bottom edges of an image because the image is taking up the entire width of the screen.

Image(mission.missionImageString)
    .resizable()
    .aspectRatio(contentMode: .fit)
    .border(Color.white, width: 2) //Adds a border to all 4 edges

Any help is appreciated!


Solution

  • You can use this modifier on any View:

    .border(width: 5, edges: [.top, .leading], color: .yellow)
    
    Demo

    Demo


    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 {
            edges.map { edge -> Path in
                switch edge {
                case .top: return Path(.init(x: rect.minX, y: rect.minY, width: rect.width, height: width))
                case .bottom: return Path(.init(x: rect.minX, y: rect.maxY - width, width: rect.width, height: width))
                case .leading: return Path(.init(x: rect.minX, y: rect.minY, width: width, height: rect.height))
                case .trailing: return Path(.init(x: rect.maxX - width, y: rect.minY, width: width, height: rect.height))
                }
            }.reduce(into: Path()) { $0.addPath($1) }
        }
    }