Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 406 Vote(s) - 3.48 Average
  • 1
  • 2
  • 3
  • 4
  • 5
SwiftUI - Add Border to One Edge of an Image

#1
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!**
Reply

#2
You can use **this modifier** on *any* `View`:
```
.border(width: 5, edges: [.top, .leading], color: .yellow)
```

##### Demo
[![Demo][1]][1]

---

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) }
}
}
```


[1]:
Reply

#3
I find the most elegant solution is to create a custom shape and add it as an overlay. It works nicely with the SwiftUI image.

```swift
struct BottomBorder: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()

path.move(to: CGPoint(x: rect.minX, y: rect.maxY))
path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))

return path
}
}

struct ContentView: View {
var body: some View {
Image("image")
.overlay(BottomBorder().stroke(Color.red, lineWidth: 8))
}
}
```
[![An image with a bottom border][1]][1]


[1]:
Reply

#4
**Add a top border aka Divider:**

.overlay( Divider()
.frame(maxWidth: .infinity, maxHeight:1)
.background(Color.green), alignment: .top)


**Example Usage:**

Image("YouImageName")
.resizable()
.scaledToFit()
.frame(height: 40)
.padding(.top, 6) // padding above you Image, before your border
.overlay( Divider()
.frame(maxWidth: .infinity, maxHeight:1)
.background(Color.green), alignment: .top) // End Overlay
.padding(.top, 0) // padding above border

**Explanation:**

For a horizontal border aka Divider, frame width is the length of the border and height is the thickness of the border. Vertical border the frame width is thickness and frame height is the length.

The .background will set the color of the border.

Alignment will set, where the border will draw. For example "alignment: .bottom" will place the border on the bottom of the Image and "alignment: .top" on the top of the Image.

".leading & .trailing" will draw the border on the left and right of the Image correspondingly.

For a vertical border:

.overlay( Divider()
.frame(maxWidth: 1, maxHeight: .infinity)
.background(Color.green), alignment: .leading )
Reply

#5
a very easy way to accomplish this

```swift
VStack(spacing: 0) {
ViewThatNeedsABorder()

Divider() // or use rectangle
}
```

you could swap the divider for a rectangle as well and get the same effect. Style the divider or rectangle as needed using frame, or background etc.

if you need left/right borders use an HStack instead of a VStack, or even combine HStack and VStack to get borders on multiple sides ie: left and top.
Reply

#6
If you don't need to control thickness, you can do this:

.overlay(Divider(), alignment: .top)
.overlay(Divider(), alignment: .bottom)

Set the color of the divider using:

.overlay(Divider().background(.red), alignment: .left)
Reply

#7
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.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through