UIView
的实例是否可以调用执行闭包的方法,并且该闭包内部引用同一实例?这是非通用版本:
import UIKit
public extension UIView {
func layout(from: (UIView) -> ()) {
from(self)
}
}
例如,当我使用UILabel调用它时,我无权访问文字要求。我可以在闭包内部引用UILabel吗?我希望这样的事情会起作用:
func layout(from: (Self) -> ()) {
from(self)
}
但是它不能编译。有解决方法吗?这就是我想要的:
let label = UILabel(frame: .zero)
label.layout { $0.textAlignment = .natural } // Currenly not working, since $0 = UIView.
答案 0 :(得分:2)
不同的方法:具有相关类型的协议扩展。
protocol Layout {
associatedtype View : UIView = Self
func layout(from: (View) -> ())
}
extension Layout where Self : UIView {
func layout(from: (Self) -> ()) {
from(self)
}
}
extension UIView : Layout {}
let label = UILabel(frame: .zero)
label.layout { $0.textAlignment = .natural }
答案 1 :(得分:1)
有不同的方法。
首先,您可以使用closures' variable capturing system来直接在闭包内部使用变量,而无需将其作为参数传递。
public extension UIView {
func layout(from: () -> ()) {
from()
}
}
label.layout { label.textAlignment = .natural }
否则,如果您要传递通用的UIView
并相应地将行为更改为特定的行为-因为看起来您肯定知道要使用的类型,则可以使用向下转换:>
public extension UIView {
func layout(from: (UIView) -> ()) {
from(self)
}
}
let label = UILabel(frame: .zero)
label.layout { ($0 as! UILabel).textAlignment = .natural }
无论如何,你为什么这样做:
label.layout { $0.textAlignment = .natural }
代替:
label.textAlignment = .natural
是否有特定原因不这样做?我想幕后还有更大的事情,我只是很好奇。