KVCメソッド:keyPathsForValuesAffectingValueForKey:CIFilterでの応用
KVCメソッド:keyPathsForValuesAffectingValueForKey:CIFilterでの応用 /// KVC, key key 。
override class func keyPathsForValuesAffectingValue(forKey key: String) -> Set<String> {
// super.keyPathsForValuesAffectingValue input***
var supSet = super.keyPathsForValuesAffectingValue(forKey: key)
// KVC , "toneMap", ""outputImage""
if key == "outputImage" {
supSet.insert("toneMap")
}
return supSet
}
結論を先に言います.
/// KVC, key key 。
override class func keyPathsForValuesAffectingValue(forKey key: String) -> Set<String> {
// super.keyPathsForValuesAffectingValue input***
var supSet = super.keyPathsForValuesAffectingValue(forKey: key)
// KVC , "toneMap", ""outputImage""
if key == "outputImage" {
supSet.insert("toneMap")
}
return supSet
}
たとえば、上記の方法では、toneMapの値を設定すると、filterのoutputImageメソッドが出発します.返されたSetに「toneMap」が含まれていない場合、toneMapの設定時にoutputImageはトリガーされません.
テスト手順:
import Cocoa
class TestFilter: CIFilter {
@objc dynamic var inputImage: CIImage?
@objc dynamic var inputWidth: Double = 0
@objc dynamic var toneMap: Double = 0
@objc dynamic var inputToneMap: Double = 0
var inputToneMap2: Double = 0
/// KVC, key key 。
override class func keyPathsForValuesAffectingValue(forKey key: String) -> Set<String> {
// super.keyPathsForValuesAffectingValue input***
var supSet = super.keyPathsForValuesAffectingValue(forKey: key)
// KVC , "inputWidth", ""outputImage""
if key == "outputImage" {
supSet.insert("toneMap")
}
return supSet
}
override var attributes: [String: Any] {
return [
kCIAttributeFilterDisplayName: "TestFilter", // filter name
"inputImage": [kCIAttributeIdentity : 0,
kCIAttributeClass : "CIImage",
kCIAttributeDisplayName : "Image",
kCIAttributeType : kCIAttributeTypeImage],
"inputWidth" : [kCIAttributeIdentity : 0,
kCIAttributeClass : "NSNumber",
kCIAttributeDefault : 0,
kCIAttributeDisplayName : "inputWidth",
kCIAttributeType : kCIAttributeTypeScalar],
"toneMap" : [kCIAttributeIdentity : 0,
kCIAttributeClass : "NSNumber",
kCIAttributeDefault : 0,
kCIAttributeDisplayName : "toneMap",
kCIAttributeType : kCIAttributeTypeScalar],
"inputToneMap" : [kCIAttributeIdentity : 0,
kCIAttributeClass : "NSNumber",
kCIAttributeDefault : 0,
kCIAttributeDisplayName : "inputToneMap",
kCIAttributeType : kCIAttributeTypeScalar],
"inputToneMap2" : [kCIAttributeIdentity : 0,
kCIAttributeClass : "NSNumber",
kCIAttributeDefault : 0,
kCIAttributeDisplayName : "inputToneMap2",
kCIAttributeType : kCIAttributeTypeScalar]]
}
override var outputImage: CIImage? {
let result = inputImage?.transformed(by: .init(scaleX: 0.2, y: 0.2))
return result
}
}
import Cocoa
class TestFilter2: CIFilter {
@objc dynamic var inputImage: CIImage?
override var attributes: [String: Any] {
return [
kCIAttributeFilterDisplayName: "TestFilter2", // filter name
"inputImage": [kCIAttributeIdentity : 0,
kCIAttributeClass : "CIImage",
kCIAttributeDisplayName : "Image",
kCIAttributeType : kCIAttributeTypeImage]]
}
override var outputImage: CIImage? {
let result = inputImage?.transformed(by: .init(scaleX: 0.2, y: 0.2))
return result
}
}
func testFilterChain() {
let testF1 = TestFilter.init()
let testF2 = TestFilter2.init()
// TestFilter2 ”inputImage“ TestFilter ”outputImage“
testF2.bind(NSBindingName(rawValue: "inputImage"), to: testF1, withKeyPath: kCIOutputImageKey, options: nil)
// , TestFilter outputImage
testF1.inputWidth = 100.0
testF1.setValue(19.0, forKey: "inputWidth")
testF1.toneMap = 0.2
let t1OutImg = testF1.outputImage
}