I'm attempting to subclass CIFilter for use in a SpriteKit game, as described in the iOS Games by Tutorials book. I have created my subclass inheriting from CIFilter, which has a (CIImage) inputImage property and implements an outputImage method which returns a CIImage. I had to provide an @objc override in order to stop Xcode complaining about a conflicting Objective-C getter.
When I create and assign my subclassed filter to an SKEffectNode attached to an SKScene, the node simply draws a gray background. If I use a built-in filter the SKEffectNode works just fine. As far as my code is concerned, it doesn't appear that my outputImage method is ever called, as XCode never breaks on any breakpoint I place within.
I have the same custom filter working fine in Objective-C, Swift just seems to be giving me some issues! My code is as follows:
GameScene.swift
import UIKit
import SpriteKit
class StartupScene: SKScene {
override func didMoveToView(view: SKView) {
anchorPoint = CGPointMake(0.5, 0.5)
let effectNode = SKEffectNode()
effectNode.shouldEnableEffects = true
let filter = OldTimeFilter();
effectNode.filter = filter
let backgroundNode = SKSpriteNode(color: UIColor.redColor(), size: frame.size)
effectNode.addChild(backgroundNode)
self.addChild(effectNode);
let labelNode = SKLabelNode(text: "Hello")
labelNode.fontColor = UIColor.blueColor();
backgroundNode.addChild(labelNode)
}
}
OldTimeFilter.swift
import Foundation
import CoreImage
class OldTimeFilter:CIFilter
{
var inputImage: CIImage?
@objc(outputImageCI)
func outputImage() -> CIImage
{
let time = CFAbsoluteTimeGetCurrent();
let first = sin(time / 15.0) * 100.0
let second = sin(time / 2.0) * 25.0
let v1: [Float] = [Float(first), 1.5]
let v2: [Float] = [Float(second), 1.5]
let randVal1 = noise2(UnsafeMutablePointer(v1))
let randVal2 = noise2(UnsafeMutablePointer(v2))
let colorControls = CIFilter(name: "CIColorControls")
colorControls.setValue(0.0, forKey: "InputSaturation")
colorControls.setValue(randVal2 * 0.2, forKey:"inputBrightness")
let vignette = CIFilter(name: "CIVignette")
vignette.setValue(0.2+randVal2, forKey: "inputRadius")
vignette.setValue(randVal2 * 0.2 + 0.8, forKey: "inputIntensity")
var transform = CGAffineTransformMakeTranslation(
CGFloat(0.0), CGFloat(randVal1 * 45.0))
colorControls.setValue(inputImage, forKey: kCIInputImageKey)
vignette.setValue(colorControls.outputImage,
forKey: kCIInputImageKey)
return vignette.outputImage.imageByApplyingTransform(transform)
}
}
If I remove @objc(outputImageCI) from the filter I get this error from Xcode: "Method outputImage() with Objective-C selector 'outputImage' conflicts with getter for 'outputImage' from superclass 'CIFilter' with the same Objective-C selector"
Am I missing something incredibly obvious?
outputImage
is a computed property not a method, so replace
@objc(outputImageCI)
func outputImage() -> CIImage
with this
override var outputImage:CIImage!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.