swift macOS - 自定义 NSCollectionViewDelegate 未被调用

swift macOS - Custom NSCollectionViewDelegate doesn't get called

我对 NSCollectionViewDelegate 进行了扩展,其中我声明了两个新函数来处理 NSCollectionViewItems 上的点击。我从自定义 NSCollectionViewItems 子类调用委托方法,并在我的 ViewController 中将 collectionView 的委托设置为 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")
}

没有接到电话。

我做错了什么?

提前致谢, 法比安

您没有实现 viewcontroller 中的功能。这被视为一个永远不会被调用的单独函数。现在,扩展是唯一被调用的部分。您可以尝试 override 函数,但最好使用扩展中的 observer 或直接使用视图(在您输入项目编号时在它)在长 运行.

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
}

就像@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)
   }

}

我希望你现在对如何使用 proto 有了更好的理解-…呃我的意思是 delegates ;-)祝你好运! (奖金提示:here is a quick-and-easy intro to learn more about delegates and other design patterns