例如,
superview?.subviews.filter{
$0 != self &&
$0.responds(to: #selector(setter: Blueable.blue))
}.map{
($0 as! Blueable).blue = false
}
是否有类似......的概念。
x.blue??? = false
'???'意思是'如果它响应蓝色,则称为蓝色'......
注意 - 我完全感谢我可以撰写扩展程序callIfResponds:to
或特定扩展程序blueIfBlueable
。
我想知道这里是否有一些原生的swiftyness,我不知道。这似乎是一个非常基本的概念。
脚注:
在随后的激烈讨论中,提到使用协议。只是为了所有人阅读的好处,这是使用协议的一种方法:
protocol Blueable:class {
var blue:Bool { get set }
}
extension Blueable where Self:UIView {
func unblueAllSiblings() { // make this the only blued item
superview?.subviews.filter{$0 != self}
.flatMap{$0 as? Blueable}
.forEach{$0.blue = false}
}
}
// explanation: anything "blueable" must have a blue on/off concept.
// you get 'unblueAllSiblings' for free, which you can call from
// any blueable item to unblue all siblings (likely, if that one just became blue)
使用它,例如......
@IBDesignable
class UILabelStarred: UILabel, Blueable {
var blueStar: UIView? = nil
let height:CGFloat = 40
let shinyness:CGFloat = 0.72
let shader:Shader = Shaders.Glossy
let s:TimeInterval = 0.35
@IBInspectable var blue:Bool = false {
didSet {
if (blue == true) { unblueAllSiblings() }
blueize()
}
}
func blueize() {
if (blueStar == nil) {
blueStar = UIView()
self.addSubview(blueStar!)
... draw, say, a blue star here
}
if (blue) {
UIView.animate(withDuration: s) {
self. blueStar!.backgroundColor = corporateBlue03
self.textColor = corporateBlue03
}
}
else {
UIView.animate(withDuration: s) {
self. blueStar!.backgroundColor = UIColor.white
self.textColor = sfBlack5
}
}
}
}
回到最初的问题,这一切都很好。但是你不能“接受”现有类中的现有属性(一个简单的例子是isHidden
)。
此外,只要我们讨论它,请注意,在该示例协议扩展中,您遗憾地无法自动拥有协议或扩展,因为它从协议或扩展的“内部”调用unblueAllSiblings,正是如此原因:why you can't do it
答案 0 :(得分:4)
正如其他人所说,更好的解决方法是通过有条件的类型转换而不是使用fun f (z, w) = (z (w 4)) + 3
fun foo z = z + 1;
fun bar x = x * 2;
val ans = f(foo, bar);
val ans = ((4 * 2) + 1) + 3
。但是,不要忽略只使用responds(to:)
循环 - 它们非常强大,允许您使用模式匹配和for in
子句,允许您迭代给定的元素子集。
where
for case let blueable as Blueable in superview?.subviews ?? [] where blueable !== self {
blueable.blue = false
}
使用type-casting pattern仅匹配case let blueable as Blueable
的元素,并在成功时将其绑定到Blueable
。
blueable
排除了where blueable !== self
的匹配。
答案 1 :(得分:2)
不知何故,我认为你想要的是:
superview?.subviews.filter {
$0 != self // filter out self
}.flatMap {
$0 as? Blueable
}.forEach {
$0.blue = false
}
为什么要在检查类型时检查类是否符合setter?
检查选择器不应该在纯Swift中使用。您将需要它主要用于与Obj-C API交互 - 动态方法,协议或非正式协议中的可选方法。
答案 2 :(得分:2)
为什么不直接检查类型的一致性?类似的东西:
superview?.subviews.forEach {
guard $0 !== self else { return }
($0 as? Blueable)?.blue = false
}
答案 3 :(得分:1)
您可以添加此扩展程序
extension UIView {
var siblings: [UIView] { return self.superview?.subviews.filter { $0 != self } ?? [] }
}
现在选择您喜欢的解决方案
siblings.flatMap { $0 as? Blueable }.forEach { $0.blue = false }
siblings.forEach { ($0 as? Blueable)?.blue = false }