Welcome to my cookbook with awesome Views and studies all developed in SwiftUI.
If you have liked the content drop a star ⭐️, more SwiftUI code to come!
This is a "game" drag a view and drop into another. The objective is to analyse how to use the drag gesture in SwiftUI and also to get the frame of a View and update a state while doing it.
The drag is mostly done using a DragGesture and updating the offset of a View.
GradientCircle(colors: circleColors)
.frame(width: 80)
.overlay(
geometryReader()
)
.overlay(
Text("DRAG")
.fontWeight(.black)
.foregroundColor(.white))
.offset(model.dragOffset)
.gesture(
DragGesture()
.onChanged { gesture in
model.dragOffset = gesture.translation
calculateFrame = true
if model.isAbove(model.objectFrame, model.targetFrame) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
calculateFrame = false
}
model.won = true
}
}
.onEnded { gesture in
withAnimation(animation) {
model.dragOffset = .zero
calculateFrame = false
}
}
)
While developing the drag and drop game, I noticed a lack of information about the update of a @State inside a GeometryReader.
The GeometryReader is used to get the frame of a View.
Some people even saying that it was not possible. I went into the docs and noticed that it is possible. However, you might end up in an infinet loop.
To solve that you have to stop executing the GeometryReader.
The code for GeometryReaderStateUpdate.swift uses the solution for it.
For a detailed explanation, go at my StackOverflow answer.
A case study of the new UI trend.
This is mostly done by adding layers of ZStacks or even working with the zindex of a View.
In addition to that, to make things "glassy", you:
1 - add a white color with opacity to a View
Color.white.opacity(0.6)
2 - ...or a Color with blur.
Circle()
.background(
Color.white.blur(radius: 30.0)
)
|
|
In this case study, on the left, I present the difference of using a LinearGradient vs using a Color(.clear) and then applying the LinearGradient as a background.
On the right I present a simple way to make awesome Text with a LinearGradient.
The way to do it is to create an overlay and mask to the View itself.
To make things easy, I created an extension for that.
extension View {
public func gradientForeground(colors: [Color]) -> some View {
self.overlay(LinearGradient(gradient: .init(colors: colors),
startPoint: .topLeading,
endPoint: .bottomTrailing))
.mask(self)
}
}
| TransparentGradient.swift | ColoredText.swift |
|
|





