Установите выход элемента в TableCellView в файле .xib на настраиваемый подкласс NSTableCellView

Я хочу наполнить свой NSTableView содержанием. В таблице-ячейке-строке есть 3 элемента (2 NSTextFields и 1 NSImageView). Для этого я создал пользовательский NSTableCellView, где я хочу установить @IBOutlets из 3 элементов, чтобы установить там значение для них. Но когда я пытаюсь установить точки привязки, единственный вариант - создать действие.

Когда я пытаюсь написать @IBOutlet weak var personName: NSTextfield, а затем установить ссылки, я не могу, потому что «xcode не может найти класс в текущей рабочей области»

Когда я создаю NSTableView внутри main.storyboard, я могу установить ссылки на розетки. Так в чем же разница между .storyboard и .xib?

Когда я пытаюсь подключить @IBOutlet к элементу «Имя человека» Устранение неполадок

Мой NSViewController (владелец .xib)

class ViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate {

    @IBOutlet weak var tableView: NSTableView! //ref to tableView in xib
    var persons:[Person] = [] //content to fill tableview

    override func viewDidLoad() {
        super.viewDidLoad()

        persons.append(Person(name: "John", age: 23, piRef: "/Users/xy/Desktop/profilePic.png"))
        persons.append(Person(name: "Marie", age: 26, piRef: "/Users/xy/Desktop/profilePic.png"))


        tableView.delegate = self
        tableView.dataSource = self
    }


    func numberOfRows(in tableView: NSTableView) -> Int {        
        return persons.count        
    }

    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {

        let tableCellView:personTableCell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "defaultRow"), owner: self) as! personTableCell
//NSTableColumn in xib has id "defaulRow"

        if let person:Person = persons[row] {

            tableCellView.setPerson(person: person) //call method inside NSTableCellView-subclass to set item values
        }

        return tableCellView        
    }    
}


Пользовательский подкласс NSTableCellView ("personTableCell")

class personTableCell: NSTableCellView {

    var person:Person! = nil

    //here should be:
    //@IBOutlet weak var personName: NSTextField!
    //@IBOutlet weak var personAge: NSTextField!
    //@IBOutlet weak var personImg: NSImageView!

    func setPerson(person: Person) {

        self.person = person

        self.personName = person.name
        self.personAge = person.age
        self.personImg = NSImage(byReferencingFile: person.profileImgRef)

    }

}

Я хочу иметь возможность добавлять ссылки на выходы элемента в мой подкласс NSTableCellView.


person Jozott    schedule 28.03.2019    source источник


Ответы (1)


Мне кажется, ты делаешь это труднее, чем должно быть. makeView дает вам ссылку на ячейку. Таким образом, вы можете получить доступ к его участникам напрямую. Нет необходимости в розетках (поэтому Xcode не сделает их за вас).

Я не могу читать ваши скриншоты достаточно хорошо, чтобы сказать, как определены текстовые поля (старые глаза), поэтому я могу привести только общий пример из рабочей демонстрации настраиваемого класса ячеек:

class DIYTableViewDelegate: NSObject, NSTableViewDelegate {
    var count = 0   // counts the number of views actually created

    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
        let id = tableColumn!.identifier
        var view = tableView.makeView(withIdentifier: id, owner: nil) as? CustomTableCellView
        if view == nil {
            view = createCell(id)
            count += 1
        }
        view!.textField!.stringValue = "\(id.rawValue) \(row) \(view!.count) \(count)"
        view!.count += 1

        return view
    }
}

Кроме того, в Swift принято использовать заглавную первую букву типов (классов, структур, перечислений, протоколов) и методов и свойств в нижнем регистре. Не влияет на то, как ваш код компилируется, но помогает другим Swifties читать его.

Вот еще один пример, который может помочь:

    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {

        guard let vw = tableView.makeView(withIdentifier: tableColumn!.identifier, owner: self) as? CustomTableCellView else { return nil }

        vw.textField?.stringValue = String(pictures[row].dropLast(4))
        vw.imageView?.image = NSImage(named: pictures[row])

        return vw
    }
person Ron    schedule 28.03.2019
comment
если бы у меня было 2 текстовых поля в 1 ячейке, как я мог бы установить значение определенного - person Jozott; 28.03.2019
comment
Было бы полезно, если бы я действительно мог увидеть, как вы определяете поля в раскадровке. Извините, я не могу прочитать скриншот. - person Ron; 28.03.2019
comment
Их идентификаторы - fileName и fileImg, или есть другой способ их определить? - person Jozott; 28.03.2019
comment
Неважно, как вы их называете. Вы можете ссылаться на них от делегата, как я показываю в моем примере. См. Отредактировать мой исходный ответ - person Ron; 28.03.2019