ios - CIFilter 不回答自定义过滤器的 kCIAttributeDescription
问题描述
我创建了一个自定义 CIFilter 并使用类 func registerName 方法将其注册到 CIFilter 类中。自定义过滤器已创建并按预期工作。但是 CIFilter 不回答已注册的 kCIAttributeDescription。
CIFilter.localizedDescription(forFilterName: ciFilterName) 不回答 registerName 方法中使用的字符串。如果自定义过滤器实际被实例化,它确实包含属性描述。
系统中的所有 Apple 过滤器都会在不创建过滤器的情况下回答本地化描述。用户获取有关过滤器的信息以帮助选择过滤器。
自定义过滤器如何实现相同的行为?
这是注册码
CIFilter.registerName(kPRandom, constructor: PGLFilterConstructor(),
classAttributes: [
kCIAttributeFilterDisplayName : "Random Filters",
kCIAttributeFilterCategories :
[ kCICategoryStillImage,
kCICategoryTransition],
kCIAttributeDescription : "Swipe on stack Make command to add random filters to the stack. Select photos for random input with Parms Pick command"
]
)
ps自定义过滤器用于App Store上的iPad“Wills Filter Tool”应用程序。探索过滤器的世界非常令人惊奇,因此随机过滤器生成器被证明是应用过滤器的一个很好的学习和实验工具。
演示问题的 pps Swift Playground
import UIKit
import CoreImage
// demonstrates that registering a custom filter does
// not register the kCIAttributeDescription
let kPRandom = "Random Filters"
let kCIDissolveFilter = "CIDissolveTransition"
class PGLFilterConstructor: CIFilterConstructor {
//MARK: CIFilterConstructor protocol
func filter(withName: String) -> CIFilter? {
return CIFilter(name: withName)
}
}
class PGLRandomFilterAction: CIFilter {
// filter that answers the input as the outputImage
// a pass thru filter
@objc dynamic var inputImage: CIImage?
class func register() {
CIFilter.registerName(kPRandom, constructor: PGLFilterConstructor(), classAttributes:
[
kCIAttributeFilterDisplayName : "Random Filters",
kCIAttributeFilterCategories :
[ kCICategoryStillImage,
kCICategoryTransition],
kCIAttributeDescription : "Swipe on stack Make command to add random filters to the stack. Select photos for random input with Parms Pick command"
]
)
}
override var outputImage: CIImage? {
get {
return inputImage }
}
}
PGLRandomFilterAction.register()
// added to CIFilter
let randomDescription = CIFilter.localizedDescription(forFilterName: kPRandom)
let dissolveDescription = CIFilter.localizedDescription(forFilterName: kCIDissolveFilter)
// randomDescription contains the filter name. Should be the string
// set in the kCIAttributeDescription line
// dissolveDescription contains the expected description
解决方案
我的 PGLFilterConstructor 确实不是 NSObject 的后代。但是,将它和 @objc 添加到演示脚本并不能解决问题。
对于自定义注册的过滤器,localizedDescription 似乎是 CIFilter 区域中被忽视的行为。与 CoreImage 中正在进行的所有其他工作相比,这是次要的,所以我认为提交有关该行为的错误报告没有帮助。
因此,解决方案是一种变通方法。该应用程序基于 CIFilter.attributes 使用包装器类自定义 UI 控件。根据过滤器的类型在包装子类中进行定制。
对于这个问题,在包装子类中添加更多自定义。
在超类包装器(PGLSourceFilter)中返回标准描述
class func localizedDescription(filterName: String) -> String {
// custom subclasses should override
guard let standardDescription = CIFilter.localizedDescription(forFilterName: filterName)
else { return filterName }
return standardDescription
}
然后包装子类可以纠正缺失的描述
override class func localizedDescription(filterName: String) -> String {
// custom subclasses should override
return "Swipe 'Make' to add random filters. Select photos for random input on Parms 'Pick' command"
}
推荐阅读
- elasticsearch - Elastic-APM 索引名称无效 [_license]
- javascript - 模拟时钟 - JavaScript
- amazon-web-services - Amazon QLDB 多区域架构
- python - 如何比较python中的两个数组?
- swift - 使用泛型将 PartialKeyPath 向下转换为 ReferenceWriteableKeyPath?
- python - 使用 Python 使用密码对 GPG 文件进行解密时出错
- c++ - 为什么函数参数的类型推导优先于模板中的类型?
- java - Android 适配器无法用视图填充活动
- spring-boot - 如何在 Thymeleaf 中显示带有参数的本地化消息作为链接
- python - 当 PHP 脚本返回成功时触发 Python 异步函数