It seems a little odd to write a post about borders this late, since every post so far has already used them without calling them out explicitly. In each of the examples I’ve added borders to the code given to better illustrate the layout.
It’s worth spending a little time looking at them in their own right though, because they’re slightly more interesting than you might expect.
There is a single method for specifying the border for a view:
func border<S>(_ content: S, width: CGFloat = 1) -> some View where S : ShapeStyle
The first parameter is required and specifies a shape style, there’s a
quite a few options for that, but fortunately Color
confirms to the
ShapeStyle
protocol so for the simplest cases all we need to do is
specify a color.
The second parameter is optional and specifies the width of the border, defaulting to a single pixel.
As with most of SwiftUI, this is intuitive enough that add a single
pixel yellow border on Text
we would use code like this:
struct ContentView : View {
var body: some View {
Text("Nogitsune Takeshi")
.font(.title)
.border(Color.yellow)
}
}
And this produces the same example I’ve used before, except with the border that’s always been in the preview actually stated in code:
The reason that borders are really useful for experimenting with or
demonstrating layout is that they don’t work like
frame or
padding; in that they
do not add space around the Text
to draw the border.
It’s not obvious with a single pixel, but we can demonstrate this by increasing the width of the border:
struct ContentView : View {
var body: some View {
Text("Nogitsune Takeshi")
.font(.title)
.border(Color.yellow, width: 4)
}
}
If this worked like padding, the border would increase in width around
the text; instead we see that that border overlays it; .border
creates
a secondary view on its
child, and draws the border overlaid on top of it.
`.border` creates a secondary view on its child, and draws the border overlaid on top of it
If we wanted the border around the view instead, we can combine it with
.padding
:
struct ContentView : View {
var body: some View {
Text("Nogitsune Takeshi")
.font(.title)
.padding(4)
.border(Color.yellow, width: 4)
}
}
This creates the Text
view, and then .padding
creates another view
around that with additional padding added, and then .border
adds a
secondary view to the padding view, and draws overlaid on that:
It’s important to note the distinction that the border is on the padding view; combined effects can be performed by carefully placing the overlays in the correct place:
struct ContentView : View {
var body: some View {
Text("Nogitsune Takeshi")
.font(.title)
.border(Color.red)
.padding(4)
.border(Color.yellow, width: 4)
.border(Color.red)
}
}
Here we create a red border overlaid on the Text
, and then use padding
to draw a thicker yellow border around the Text
, and finally overlaid
another red border onto the padding:
The total border width is 5px since it includes the additional
pixel-wide border overlaid on the Text
, or put another way, the yellow
part of the border is 3px wide since the outer pixel is overlaid by the
red border added to it.