Using SwiftUI I want to press a button and have it switch the class which is used to filter an image.
In SwiftUI, the button would do something like what follows:
@ObservedObject var currentFilter = FilterChoice()
...
var body: some View {..
Button(action:{
print("clicked")
var newFilter = Luminance()
self.currentFilter = newFilter
}) {
Text("Switch to Luminance Filter")
}
}
There is an ObservableObject:
class FilterChoice: ObservableObject {
@Published var filter = Luminance()
}
Which is consumed by a UIViewRepresentable:
struct FilteredPhotoView: UIViewRepresentable {
@ObservedObject var currentFilter = FilterChoice()
func makeUIView(context: Context) -> UIView {
...
// Code works and pulls correct filter but can not be changed
let className = currentFilter.filter
let filteredImage = testImage.filterWithOperation(className)
...
}...
Currently, FilteredPhotoView is properly returning the filtered image.
But how can ObservedObject be used to change a CLASS?
In other words, the ObservedObject sets the class correctly here:
class FilterChoice: ObservableObject {
@Published var filter = Luminance()
}
But how can this ObservableObject be changed so that the class can be changed in SwiftUI? For example, I want to click a button and the filter should be changed to another class (for example:
new filter = ColorInversion()
I think I understand how ObservableObjects work but I can't get it to work as a change of class rather than something simple like a string value.
What you actually need is some generics.
Declare a protocol like this:
protocol ImageFilter {
func apply(to image: UIImage) // for example
}
Declare here any methods or properties that all your filters will share and that will be used by FilterChoice. Next declare all your filters as conforming to the protocol:
class Luminance: ImageFilter {
// implement all the methods and properties declared in the protocol
// for every filter
}
Next declare your @Published
filter to conform to that protocol
class FilterChoice: ObservableObject {
@Published var filter: ImageFilter
public init(filter: ImageFilter) {
self.filter = filter
}
// etc.
}
You will be able to change the filters used by @Published
.