我想创建一个协议Pannable
,以便可以将其添加到现有单元格中以便进行平移:
@objc protocol Pannable {
var panGesture: UIPanGestureRecognizer { get }
var margin: CGPoint { get }
var limitLeft: CGFloat { get set }
var limitRight: CGFloat { get set }
var shadowOn: Bool { get set }
var background: UIView { get set }
var shadowView: UIView { get set }
var enablePanR: Bool { get set }
var enablePanL: Bool { get set }
func handlePan(_ recognizer: UIPanGestureRecognizer)
}
extension Pannable where Self: UITableViewCell {
var original: CGFloat { return background.frame.minX }
func handlePan(_ recognizer: UIPanGestureRecognizer) {
// pan cell
}
func configureLayout() {
contentView.layer.cornerRadius = background.layer.cornerRadius
let size = shadowOn ? shadowView.layer.shadowOffset.height : 0
let height = bounds.height - margin.y - size
let widths = bounds.width - margin.x * 2
let rect = CGRect(x: margin.x, y: size, width: widths, height: height)
background.frame = rect
contentView.frame = rect
shadowView.layer.shadowPath = UIBezierPath(roundedRect: rect, cornerRadius: background.layer.cornerRadius).cgPath
}
func setup() {
insertSubview(background, at: 0)
insertSubview(shadowView, at: 0)
background.clipsToBounds = true
panGesture.addTarget(self, action: #selector(handlePan))
panGesture.delegate = self
addGestureRecognizer(panGesture)
}
func reset() {
contentView.frame.origin.x = original
}
func enableShadow() {
shadowView.layer.shadowOffset = CGSize(width: 2, height: 2)
shadowView.layer.shadowRadius = 2
shadowView.layer.shadowOpacity = 0.5
shadowView.layer.shadowColor = UIColor.black.cgColor
shadowOn = true
}
}
要使用此Pannable
,我必须将setup()
和configureLayout()
添加到单元格的初始化程序和layoutSubviews()
:
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setup()
}
override func layoutSubviews() {
super.layoutSubviews()
configureLayout()
}
但是,这意味着我也可以将UITableViewCell
子类化并直接添加它而不是创建协议。是否可以使用协议并使用适当的初始化程序/ layoutSubviews扩展符合协议的UITableViewCell
?
答案 0 :(得分:1)
您的问题比问题提出的要深。您肯定已经(从编译器的尖叫声中)注意到这是行不通的:
extension Pannable where Self: UITableViewCell {
func handlePan(_ recognizer: UIPanGestureRecognizer) {
// pan cell
}
func setup() {
panGesture.addTarget(self, action: #selector(handlePan))
}
}
协议扩展是Swift的功能。 Objective-C无法看到它。但是选择器是Objective-C的功能。因此它看不到Swift协议扩展中声明的函数。
基本上,尝试使用协议扩展将功能注入到Objective-C本身将以某种方式自动调用的Objective-C类中,这注定是失败的项目。正是由于这个原因,在这里,子类将变得更加有意义。