Hi,
what I am trying to build is a ListConroller that tells it's delegate when a new entry was selected. The actual data type behind the single list elements is generic.
Sounds easy I thought.
Version1 – What I wanted, but did not work: Having a List of Entry and of course the Delegate is dependent on this type, too
protocol ListControllerDelegate: class {
associatedtype Entry
func list(_ list: ListController<Entry>, didSelectEntry element: Entry)
}
class ListEntryController<Entry>: NSViewController {
var listView: NSTableCellView { get { return view as! NSTableCellView } }
var entry: Entry?
//…
}
class ListController<Entry>: NSObject, NSTableViewDelegate, NSTableViewDataSource {
// Here I want a delegate that Whose associatedtype is Entry, that's all
// ERROR: I would love something like this but it does not exist
weak var delegate: ListEntryController? where ListEntryController.Entry = Entry
var entries = [ListEntryController<Entry>]()
var selectedIndex: Int = 0 {
didSet {
delegate?.list(self, didSelectEntry: entries[selectedIndex])
}
}
// implementation of for getting data and selection change
// …
}
Version 2 – This seemed to be the ugly way that should work: I had to make my List dependent on the Delegate and use it's associated type
protocol ListControllerDelegate: class {
associatedtype Entry
func list(_ list: ListController<Self>, didSelectEntry element: Entry)
}
class ListEntryController<Entry>: NSViewController {
var listView: NSTableCellView { get { return view as! NSTableCellView } }
var entry: Entry?
/
}
// UGLY: List of thype Delegate :-(
class ListController<Delegate: ListControllerDelegate>: NSObject, NSTableViewDelegate, NSTableViewDataSource {
/
typealias Entry = Delegate.Entry
weak var delegate: Delegate?
var entries = [ListEntryController<Entry>]()
var selectedIndex: Int = 0 {
didSet {
// ERROR: does not accept self as argument, should be of type ListController<_>
delegate?.list(self, didSelectEntry: entries[selectedIndex])
}
}
// implementation of for getting data and selection change
// …
}
/
// UGLY again, the class needs to be final else implementation fails
final class MyClass: ListControllerDelegate {
typealias Entry = String
// would fail here if class is not final
internal func list(_ list: ListController<MyClass>, didSelectEntry element: String) {
}
}
So I am totally stuck. I am sure i am overlooking something and probably both ways are possible somehow. I simply may not have found the right notation?
Would be very glad if anyone could help? Where in the Swift documentation would I have found my answer?
All the best
Christoph