Generics 共享公共函数:如何触发子类操作?

Generics 共享公共函数:如何触发子类操作?,generics,swift3,overriding,Generics,Swift3,Overriding,我想实现以下特定功能(SatellitesViewController): …转换为更通用的函数(类型:UIViewController): 问题:将UIViewerController转换回源UIViewController子类型,以便将操作发送回调用源。 我得到的编译器错误是“UIViewController”没有这样的函数;这是真的。但是,检查调用源(发送方)的类型会显示真正的类型(具有以下功能): 发送方应为“SatellitesViewController”时为“UIVie

我想实现以下特定功能(SatellitesViewController):

…转换为更通用的函数(类型:UIViewController):

问题:将UIViewerController转换回源UIViewController子类型,以便将操作发送回调用源。 我得到的编译器错误是“UIViewController”没有这样的函数;这是真的。但是,检查调用源(发送方)的类型会显示真正的类型(具有以下功能):

发送方应为“SatellitesViewController”时为“UIViewController”:

问题:与通用UIViewController相比,如何强制发送方参数的类型为其真实类型? 这是典型的Swift通用场景吗


解决方案尝试: 通用路线似乎不是这里的解决方案
因此,我想我可以向UIViewController父级添加抽象按钮操作以满足回调:

... 然后覆盖子UIViewController中的功能(例如“SatellitesViewController”,如下所示:

extension SatellitesViewController {

    override func displayGrayOverview() {
        let swipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(handleDownSwipe))
        swipeGesture.direction = .down
        self.grayOverview.positionOverLay(sender:self, parentView: self.view)
        self.grayOverview.addGestureRecognizer(swipeGesture)
    }
...
}
但这只触发UIViewController的函数,而不是其子级的继承(重写)函数

***UIController's Button Action ***
我更喜欢在子UIViewController中处理实现,而不是在UIViewController类本身中;或者根本不处理实现……就像处理UIViewController的其他后代一样。 因此,它归结为:假设我在这里走的是正确的道路,我如何强制覆盖函数()相对于父函数()启动?
以下是每个请求的代码:

请求灰色覆盖视图的主机:

extension SatellitesViewController {

    func displayGrayOverview() {
        let swipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(handleDownSwipe))
        swipeGesture.direction = .down
        self.grayOverview.positionNetworkSatOverLay(sender:self, parentView: self.view)
        self.grayOverview.addGestureRecognizer(swipeGesture)
    }

    // -----------------------------------------------------------------------------------------------------

    func showCode(completion:@escaping BasicCallBack) {
        if Bundle.main.url(forResource:"NetworkSatellites", withExtension: "pdf") != nil {
            let preview = QLPreviewController()
            preview.dataSource = self
            preview.currentPreviewItemIndex = 0

            self.present(preview, animated: true, completion: { 
                completion()
            })
        }
    }

    // -----------------------------------------------------------------------------------------------------
    // MARK: - Selector handlers

    func handleDownSwipe() {
        grayOverview.removeFromSuperview()
    }

    // -----------------------------------------------------------------------------------------------------
    // MARK: - Handle Swipe Gesture

    func handleButtonAction(sender:UIButton) {
        showCode() {completion in
            self.grayOverview.removeFromSuperview()
        }
    }

    // -----------------------------------------------------------------------------------------------------

    @IBAction func infoAction(_ sender: UIButton) {
       displayGrayOverview()
    }
}

以下是我希望对所有UIViewController类型的sendervs:SatellitesViewController可用的调用函数:

extension UIView {
  final func positionNetworkSatOverLay(sender:SatellitesViewController,
                                   parentView:UIView,
                                   overlayColor:UIColor = UIColor.overlayGray) {
        self.backgroundColor = overlayColor
        let screenBounds = UIScreen.main.bounds
        self.frame = screenBounds
        self.tag = 201

        var buttonTitles:NSArray?
        guard let navButtonURL = Bundle.main.url(forResource: "NetworkInfo", withExtension: "plist") else {
            return
        }

        buttonTitles = NSArray(contentsOf: navButtonURL)

        let myButton = UIButton(type: .custom)
        myButton.frame.size = CGSize(width: 100.0, height: 32.0)
        myButton.setTitle(String(describing: buttonTitles![0]), for: .normal)
        myButton.sizeToFit()

        self.addSubview(myButton)
        myButton.translatesAutoresizingMaskIntoConstraints = false
        let viewDictionary:Dictionary = ["subView": myButton]
        self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-(x)-[subView(==w)]", options: [], metrics: ["x":200.0, "w":myButton.frame.size.width], views: viewDictionary))

        self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-(y)-[subView(==h)]", options: [], metrics: ["y":400.0,"h":myButton.frame.size.height], views: viewDictionary))


        myButton.addTarget(sender, action: #selector(sender.handleButtonAction), for: .touchUpInside)


        parentView.addSubview(self)
    }
    ...
}

请发布代码而不是图片。我已根据请求添加了源代码。
extension UIView {
  final func positionNetworkSatOverLay(sender:SatellitesViewController,
                                   parentView:UIView,
                                   overlayColor:UIColor = UIColor.overlayGray) {
        self.backgroundColor = overlayColor
        let screenBounds = UIScreen.main.bounds
        self.frame = screenBounds
        self.tag = 201

        var buttonTitles:NSArray?
        guard let navButtonURL = Bundle.main.url(forResource: "NetworkInfo", withExtension: "plist") else {
            return
        }

        buttonTitles = NSArray(contentsOf: navButtonURL)

        let myButton = UIButton(type: .custom)
        myButton.frame.size = CGSize(width: 100.0, height: 32.0)
        myButton.setTitle(String(describing: buttonTitles![0]), for: .normal)
        myButton.sizeToFit()

        self.addSubview(myButton)
        myButton.translatesAutoresizingMaskIntoConstraints = false
        let viewDictionary:Dictionary = ["subView": myButton]
        self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-(x)-[subView(==w)]", options: [], metrics: ["x":200.0, "w":myButton.frame.size.width], views: viewDictionary))

        self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-(y)-[subView(==h)]", options: [], metrics: ["y":400.0,"h":myButton.frame.size.height], views: viewDictionary))


        myButton.addTarget(sender, action: #selector(sender.handleButtonAction), for: .touchUpInside)


        parentView.addSubview(self)
    }
    ...
}