swift macOS - 自定义 NSCollectionViewDelegate 不会被调用

问题描述 投票:0回答:2

我对

NSCollectionViewDelegate
进行了扩展,其中声明了两个新函数来处理 NSCollectionViewItems 上的点击。我从自定义 NSCollectionViewItems 子类调用委托方法,并将 collectionView 的委托设置为 ViewController 中的
self
。然而,新函数是在
NSCollectionViewDelegate
中调用的,而不是在我的 ViewController 中。

我的 NSCollectionViewDelegate 扩展:

extension NSCollectionViewDelegate {

    func collectionView(_ collectionView: NSCollectionView, didDoubleClickOnItem item: Int) {
        print("didDoubleClickOnItem delegate")
    }

    func collectionView(_ collectionView: NSCollectionView, didRightClickOnItem item: Int) {
        print("didRightClickOnItem delegate")
    }
}

这些函数在我的 NSCollectionViewItem 子类中调用:

self.collectionView.delegate?.collectionView(self.collectionView, didDoubleClickOnItem: itemIndex)

但是我的ViewController中实现的功能

func collectionView(_ collectionView: NSCollectionView, didDoubleClickOnItem item: Int) {
    
    print("didDoubleClickOnItem")
}

没有接到电话。

我做错了什么?

提前致谢

swift macos delegates macos-sierra nscollectionview
2个回答
4
投票

就像 @AMAN77 所说,您已经使用一些新的(并且已经实现的)功能扩展了

NSCollectionViewDelegate
的基本委托功能,因此编译器认为这没有什么坏处。

没有任何规则强制您只能使用一名代表。如果您希望您的

ViewController
被呼叫,作为代表
NSCollectionViewItems
的代表,请执行以下操作。

创建满足您需求的协议;有人会告诉你的代表什么?

大概是这样的:

protocol NSCollectionViewClickHandler {
    func collectionView(_ collectionView: NSCollectionView, didDoubleClickOnItem item: Int)
    func collectionView(_ collectionView: NSCollectionView, didRightClickOnItem item: Int)
}

因此,既然您希望

ViewController
充当委托,那么它就应该实现这些功能。 (您已经这样做了至少
didDoubleClickOnItem

恕我直言,如果您愿意在您的ViewController

的扩展中
执行此操作,那么看起来很整洁

class ViewController { // All the regular stuff goes in here // … override func viewDidLoad() { super.viewDidLoad() // set self as (NSCollectionViewClickHandler) delegate of some object } } extension ViewController: NSCollectionViewDelegate { // implement those function of NSCollectionViewDelegate that you'd like to use, // and the ones that are required. } extension ViewController: NSCollectionViewClickHandler { func collectionView(_ collectionView: NSCollectionView, didDoubleClickOnItem item: Int) { print("didDoubleClickOnItem") } func collectionView(_ collectionView: NSCollectionView, didRightClickOnItem item: Int) { print("didDoubleClickOnItem") } // If you need other methods to properly implement your delegate methods, // you can group them in this extension as well: they logically belong together. // … } class YourSubclassOfNSCollectionViewItems: NSCollectionViewItems { var clickDelegate: NSCollectionViewClickHandler? func someFunction() { // does something, and gets the itemIndex clickDelegate?.collectionView(self.collectionView, didDoubleClickOnItem: itemIndex) } }

我希望您现在对如何使用原型有更好的了解-…呃我的意思是

代表;-)祝你好运! (额外提示:这是一个快速简单的介绍,可以了解有关委托和其他设计模式的更多信息


1
投票
您没有在视图控制器中实现该功能。这被视为一个从未被调用的单独函数。现在扩展是唯一被调用的部分。您可以尝试

覆盖该功能,但从长远来看,最好使用扩展程序中的观察者或直接使用视图(在使用时传递项目编号)。

NotificationCenter.default.addObserver(self, selector: #selector(self.handleDoubleClick), name: ObserverNotifNames.loginError, object: nil) NotificationCenter.default.post(name: "didDoubleClickOnItem", object:nil, userInfo:["item":item]) func handleDoubleClick(_ notification:Notification){ let userInfo = (notification as NSNotification).userInfo as! [String: AnyObject] let item = userInfo["item"] //Do something with the item }
    
© www.soinside.com 2019 - 2024. All rights reserved.