We’ve arrived at day 62 of the 100 Days of SwiftUI! Yesterday, we had the second of two consolidation days. I used these past two days to go over difficult topics and have decided that I will come back to the challenges after I have completed the remainder of the course. Today, we’re starting a new project called Instafilter. Let’s dive in!
Instafilter SwiftUI app introduction
In this project, we’ll be making an app that allows users to import an image from the image library on their device. Then, they can modify that image by applying various image effects. In order to accomplish this, we’ll be making use of a framework we have not used before: Core Image.
How property wrappers become structs
We’ve previously seen how Swift lets us store changing data in our structs by using the @State
property wrapper and how we can bind values to those properties so that our view automatically updates whenever they change.
Since this concept of property wrappers becoming structs is a bit of a difficult concept to explain for a beginner like myself, I will refer you to Paul’s article on the matter.
Responding to state changes using onChange()
Because of the way Swift sends binding updates to property wrappers, assigning property observers used with property wrappers often won’t work. To fix this, we need to apply the .onChange()
modifier, which tells Swift to run a function whenever a particular value changes.
//
// ContentView.swift
// Instafilter
import SwiftUI
struct ContentView: View {
@State private var blurAmount = 0.0
var body: some View {
VStack {
Text("Hello, World!")
.blur(radius: blurAmount)
Slider(value: $blurAmount, in: 0...20)
.onChange(of: blurAmount) { newValue in
print("New value is \(newValue)")
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Showing multiple options with confirmationDialog()
SwiftUI gives us
Hacking with Swift, Paul Hudson (@twostraws)alert()
for presenting important announcements with one or two buttons, andsheet()
for presenting whole views on top of the current view, but it also gives usconfirmationDialog()
: an alternative toalert()
that lets us add many buttons.
//
// ContentView.swift
// Instafilter
import SwiftUI
struct ContentView: View {
@State private var showingConfirmation = false
@State private var backgroundColor = Color.white
var body: some View {
Text("Hello, World!")
.frame(width: 300, height: 300)
.background(backgroundColor)
.onTapGesture {
showingConfirmation = true
}
.confirmationDialog("Change background", isPresented: $showingConfirmation) {
Button("Red") { backgroundColor = .red }
Button("Green") { backgroundColor = .green }
Button("Blue") { backgroundColor = .blue }
Button("Cancel", role: .cancel) { }
} message: {
Text("Select a new color")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Wrap up
And that’s it for day 62! Tomorrow, we’ll begin the implementation of our Instafilter app. Time to rest up and get ready. Stay tuned!
100 Days of SwiftUI – Day 62