Hello everyone,
I found a few interesting places in the BadgeSymbol.swift file in this tutorial which looked like they could be improved:
-
under
GeometryReader,
path.addlines
just uses all of the points defined to create the shape. The code is written as an instruction to start and end at the same point which is redundant since a shape can be drawn starting at any point, and the start and endpoint will always be the same. -
path.move
is not needed sincepath.addlines
always defines a new shape based on the points in the new array. It doesn't reference back to a previouspath.addlines
block. -
The screen references only work in portrait mode. This is because
middle
is half of the smaller of the screen width (left to right) and height (top to bottom). So in landscape modemiddle
references the height to compute the left-right position which makes no sense. A cleaner way to do this is to reference the shape to the top center of the screen withmiddle
to always be halfway between the left and right edges of the screen andspacing
for distance from the top of the screen. And instead of usingspacing
to define the left/right bottom corners, the left/right position of these points should be referenced to the middle of the shape. The shape will always fit the screen as long as all of the size of the shape is constrained bylet width = min(geometry.size.width, geometry.size.height)
Anyways here is my code with comments for where changes have been made:
import SwiftUI
struct BadgeSymbol: View {
static let symbolColor = Color(red: 79.0 / 255, green: 79.0 / 255, blue: 191.0 / 255)
var body: some View {
GeometryReader { geometry in
Path { path in
let width = min(geometry.size.width, geometry.size.height)
let height = width * 0.75
let spacing = width * 0.030
//let middle = width * 0.5
//this reference is wrong in landscape mode where width = geometry.size.height
let middle = geometry.size.width * 0.5
//this correctly reference halfway between the left and right edges of the screen
let topWidth = width * 0.226
let topHeight = height * 0.488
path.addLines([
CGPoint(x: middle, y: spacing),
CGPoint(x: middle - topWidth, y: topHeight - spacing),
CGPoint(x: middle, y: topHeight / 2 + spacing),
CGPoint(x: middle + topWidth, y: topHeight - spacing)
//remove comma for last one
/* CGPoint(x: middle, y: spacing)
this is not needed...CoreGraphics closes the shape */
])
/* path.move(to: CGPoint(x: middle, y: topHeight / 2 + spacing * 3))
this is not needed...CoreGraphics starts a new shape at the new path.addLines statement */
path.addLines([
CGPoint(x: middle - topWidth, y: topHeight + spacing),
/*CGPoint(x: spacing, y: height - spacing),
CGPoint(x: width - spacing, y: height - spacing),
reference middle of the figure, not the edge of the screen! */
CGPoint(x: middle - topWidth*2.0, y: height - spacing),
CGPoint(x: middle + topWidth*2.0, y: height - spacing),
//now
CGPoint(x: middle + topWidth, y: topHeight + spacing),
CGPoint(x: middle, y: topHeight / 2 + spacing * 3)
])
}
.fill(Self.symbolColor)
}
}
}
#Preview {
BadgeSymbol()
}
I'm just learning so if I got any of this wrong please let me know!