Tom's SwiftUI experimentation spot.
Made a haptic image tap animation + project organisation
Learned about:
NavigationStackHStack,VStack,ZStackAppIconasset- Image assets
- Feedback Generators (
UIImpactFeedbackGenerator) - modifiers
safeArea
Made a grid of rectangles colored by a random starting color and each subsequent color has a hue rotation applied.
Learned about:
systemIcon(SF Symbols) - they have a cool explorer app here: https://developer.apple.com/sf-symbols/ForEachview@StatewithAnimation- really cool pattern. Creates an animation based on some change to a view. (e.gselectedColormay be set in the closure and and will have effects on other views that conditionally render based on this state. The animation will then effect all those dependent views. I have no idea how this works but it's a really nice dev experience so far.)matchedGeometryEffectmodifier for animations. You can tie two views together with a unique id to enable SwiftUI to work out how to transition between two states, even if the two views are distinct.
Made a simple HN client using their firebase API. The firebase API at https://hacker-news.firebaseio.com/v0. This API has some complexity as /topstories.json will return back a list of ids and you have to fetch each story individually.
Learned about:
Alamofirelibrary for making HTTP requests- has a cool
.responseDecodable(of: Story.self)method which can parse the json response into a struct that conforms to theCodableprotocol.
- has a cool
- installing dependencies
@StateObjectand@EnvironmentObject- Both are for services/classes that extend
ObservableObjectlike ourHNService. @StateObjectis for when you initialize the class in the view it is being used.@EnvironmentObjectis like dependency injection. You initialize the class further up the tree and it is injected into this view- (claude-3.5-sonnet used the react analogy of
useContext)
- (claude-3.5-sonnet used the react analogy of
- Both are for services/classes that extend
DispatchGroup()for asynchronous tasks- create a new group
- add a task into the group with
group.enter()(do your request etc) group.leave()once the task is done- The swift way to do this is to use
defer, which will execute once you exit the scope of the current codeblock, regardless of errors etc.
- The swift way to do this is to use
group.notify()to inform that all of the async tasks have been completed
guardI don't really understand. It feels likeguard (!isLoading) else { return }it is the same as doingif (isLoading) { return }... and just different syntax for expressing that. It might be slightly more readable? idk.- lists
- you can do the "pull to refresh" with
.refreshable { }modifier
- you can do the "pull to refresh" with
- Swipe list to open in safari
- Sheet to open a webview with the hn story
- Render the hn score in the list
- Inspired by a physiology course I'm taking. Human homeostasis seems like a bunch of PID controllers.
- Attempted to build a PID controller in swift
- Still don't know exactly how you are meant to tune the P,I,D gain values in a PID controller?
- Learned a tiny bit about swift charts:
Chart(temperatureData) { data in
LineMark(
x: .value("Time", data.time),
y: .value("Temperature", data.temperature)
)
.foregroundStyle(.blue)
RuleMark(y: .value("Setpoint", self.setpoint))
.foregroundStyle(.red)
}
.frame(height: 300)- Learned about the
Timerclass ... similar tosetInterval:
Timer.scheduledTimer(withTimeInterval: deltaTime, repeats: true) { _ in
// do it
}