Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 协议与子类_Swift_Protocols_Subclass - Fatal编程技术网

Swift 协议与子类

Swift 协议与子类,swift,protocols,subclass,Swift,Protocols,Subclass,我想创建一个协议Pannable,以便将其添加到现有单元格中,以便平移它们: @objc protocol Pannable { var panGesture: UIPanGestureRecognizer { get } var margin: CGPoint { get } var limitLeft: CGFloat { get set } var limitRight: CGFloat { get set } var shadowOn: Bo

我想创建一个协议
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()


但这意味着我可以将
UITableViewCell
子类化,直接添加它,而不是创建协议。有没有一种方法可以使用协议并扩展
UITableViewCell
使协议与适当的初始值设定项/布局子视图一致?

您的问题比问题所暗示的要复杂得多。当然,您已经注意到(从编译器的尖叫声中)这是行不通的:

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本身将以某种方式自动调用该类,这是一个注定失败的项目。正是因为这个原因,子类在这里会更有意义

extension Pannable where Self: UITableViewCell {
    func handlePan(_ recognizer: UIPanGestureRecognizer) {
        // pan cell
    }
    func setup() {
        panGesture.addTarget(self, action: #selector(handlePan))
    }
}