You can try something like:
protocol ShyObject : AnyObject {
var hidden: Bool { get set }
}
extension SequenceType where Generator.Element : ShyObject {
func hideAll() { for e in self { e.hidden = true } }
func showAll() { for e in self { e.hidden = false } }
}
import UIKit
extension UIView : ShyObject {}
// TODO: extend more shy types...
let nodes = Array(count: 5, repeatedValue: UIView())
nodes.hideAll()
If you specifically need hide()
method as well, you can provide it generically for all ShyObject
s:
extension ShyObject {
func hide() { hidden = true }
func show() { hidden = false }
}
And to implement conformance for a type that does not have hidden
:
class MyClass {}
extension MyClass : ShyObject {
var hidden: Bool {
get { return /* true or */ false }
set { /* hide me or show me */ }
}
}
let myObjects = Array(count: 5, repeatedValue: MyClass())
myObjects.hideAll()
We can also have allHidden
and allShown
properties too:
extension SequenceType where Generator.Element : ShyObject {
var allShown: Bool { return !contains{ $0.hidden == true } }
var allHidden: Bool { return !contains{ $0.hidden == false } }
}
extension MutableCollectionType where Generator.Element : ShyObject {
var allShown: Bool {
get { return !contains{ $0.hidden == true } }
set { newValue ? showAll() : hideAll() }
}
var allHidden: Bool {
get { return !contains{ $0.hidden == false } }
set { newValue ? hideAll() : showAll() }
}
}
var nodes = Array(count: 5, repeatedValue: UIView()) // note the `var` :(
nodes.allShown = false
nodes.allHidden // true (does not in itself require a mutable collection!)
... which works, but it has a major drawback that the sequence has to be mutable if we want to use a setter. This is because all computed properties with a setter are assumed by compiler to be mutating
even when the sequence elements are of a reference type like here... Still, we can at least have getter only allShown
and allHidden
properties without paying for it with mutability.
Note that, as @dfri commented at one point, this answer is more general than the question explicitly calls for. If this is not desired, @dfri suggests:
protocol Hideable {
func hide()
}
extension UIView : Hideable {
func hide() { self.hidden = true }
}
extension Array where Element: Hideable {
func hideAll() { for e in self { e.hide() } }
}