SwiftUI = ObservableObject作为类的选择

时间:2019-11-25 14:42:31

标签: swift uikit swiftui combine

使用SwiftUI,我想按下一个按钮并让它切换用于过滤图像的类。

在SwiftUI中,该按钮将执行以下操作:

@ObservedObject var currentFilter = FilterChoice()
...
var body: some View {..
  Button(action:{
    print("clicked")
    var newFilter = Luminance()
    self.currentFilter = newFilter
  }) {
     Text("Switch to Luminance Filter")
  }
}

有一个ObservableObject:

class FilterChoice: ObservableObject {  
    @Published var filter = Luminance()
}

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)
     ...   
  }...

当前,FilteredPhotoView正确返回过滤后的图像。

但是如何使用ObservedObject更改CLASS?

换句话说,ObservedObject在此处正确设置了该类:

class FilterChoice: ObservableObject {
   @Published var filter = Luminance()    
}

但是如何更改此ObservableObject,以便可以在SwiftUI中更改该类?例如,我要单击一个按钮,然后将过滤器更改为另一个类(例如:

new filter = ColorInversion()

我想我了解ObservableObjects的工作原理,但是我不能让它作为类的更改而不是像字符串值之类的简单内容来工作。

1 个答案:

答案 0 :(得分:1)

您真正需要的是一些泛型。

声明这样的协议:

protocol ImageFilter {

    func apply(to image: UIImage) // for example
}

在此声明所有过滤器将共享的任何方法或属性,并将由FilterChoice使用。 接下来,将所有过滤器声明为符合协议:

class Luminance: ImageFilter {
    // implement all the methods and properties declared in the protocol
    // for every filter
}

接下来声明您的@Published过滤器以符合该协议

class FilterChoice: ObservableObject {
    @Published var filter: ImageFilter

    public init(filter: ImageFilter) {
        self.filter = filter
    }

    // etc.
}

您将能够更改@Published使用的过滤器。