2016-04-10 1 views
0

J'ai essayé de nombreuses façons de créer un NSTableview avec NSTableCellView personnalisé, mais je n'ai pas réussi à le faire fonctionner. La question est, comment puis-je faire cette chose?Comment créer un NSTableview avec des viewcells personnalisées

Voici la dernière chose que j'ai essayé:

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

    var cellIdentifier: String = "" 


    if tableColumn == tableView.tableColumns[0] { 

     cellIdentifier = "CellID" 

     if let cell = tableView.makeViewWithIdentifier(cellIdentifier, owner: self) as? MyTableCellView { 

      cell.identifier = cellIdentifier 
      // array is an array that contains NSView with layers with different colors 
      cell.myView = array[row] 
      return cell 
     } 
    } 
    return nil 
} 

enter image description here

Après avoir ajouté une étiquette:

enter image description here

Et le code complet:

classe ViewController: NSViewController, NSTableViewDelegate, NSTableViewDataSource {

override func viewDidLoad() { 
    super.viewDidLoad() 
    tableview.setDelegate(self) 
    tableview.setDataSource(self) 

    let view = NSView(frame: NSRect(x: 0, y: 0, width: 200, height: 200)) 
    view.layer?.backgroundColor = NSColor.blueColor().CGColor 
    array.append(view) 
    let view2 = NSView(frame: NSRect(x: 0, y: 0, width: 200, height: 200)) 
    view2.layer?.backgroundColor = NSColor.greenColor().CGColor 
    array.append(view2) 

    array2label.append("bu") 
    array2label.append("buu") 

    tableview.reloadData() 

    // Do any additional setup after loading the view. 
} 

override func viewWillAppear() { 


    //tableview.reloadData() 

    laView.layer?.backgroundColor = NSColor.greenColor().CGColor 
} 
@IBOutlet weak var laView: NSView! 

@IBOutlet weak var tableview: NSTableView! 

var array = [NSView]() 
var array2label = [String]()// = ["bu","buu"] 

func numberOfRowsInTableView(tableView: NSTableView) -> Int { 
    if (tableView.identifier == "Taula") { 

     return array.count 
     //return taulaGrafics.count 
    } else { 
     return 0 
    } 

} 

@IBOutlet weak var viewDeProva: NSView! 

func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? { 
    print ("Preparem la TableView") 
    var cellIdentifier: String = "" 


    if tableColumn == tableView.tableColumns[0] { 

     cellIdentifier = "CellID" 

     if let cell = tableView.makeViewWithIdentifier(cellIdentifier, owner: self) as? MyTableCellView { 
      print ("aqui") 
      print(array) 
      print(array2label) 

      cell.identifier = cellIdentifier 
      cell.myView = array[row] 
      cell.label.stringValue = array2label[row] 

      return cell 
     } 
    } 
    return nil 
} 

@IBAction func afegir(sender: NSButton) { 
    let view = NSView(frame: NSRect(x: 0, y: 0, width: 200, height: 200)) 
    view.layer?.backgroundColor = NSColor.yellowColor().CGColor 
    array.append(view) 
    array2label.append("buLabel") 
    tableview.reloadData() 
} 
@IBAction func treure(sender: NSButton) { 
    array.removeLast() 
    tableview.reloadData() 
} 
} 

enter image description here

if let cell = tableView.makeViewWithIdentifier(cellIdentifier, owner: self) as? MyTableCellView { 
      print ("aqui") 
      print(array) 
      print(array2label) 

      cell.identifier = cellIdentifier 
      cell.myView = array[row] 
      cell.myView.wantsLayer = true 
      cell.label.stringValue = array2label[row] 

      return cell 
     } 
+0

Avez-vous ajouté votre cellule personnalisée à la tableView dans le storyboard? Avez-vous défini l'identifiant? – mangerlahn

+0

@Max Oui oui, voir la nouvelle image sur la question –

+0

Comme cellView ne fait rien d'autre que myView, l'erreur pourrait être là. Pour tester ceci, ajoutez une étiquette ou un bouton à la cellule juste pour vérifier si elle est chargée. – mangerlahn

Répondre

0

Avec cela change le point de vue montrent la couleur qui devrait être:

class ViewController: NSViewController, NSTableViewDelegate, NSTableViewDataSource { 

override func viewDidLoad() { 
    super.viewDidLoad() 
    print("DidLoad") 
    tableview.setDelegate(self) 
    tableview.setDataSource(self) 
} 

override func viewWillAppear() { 
    print("WillAppear") 
    array.append(NSColor.blueColor().CGColor) 
    array2label.append("buIni") 
    tableview.reloadData() 
    laView.layer?.backgroundColor = NSColor.greenColor().CGColor 
} 

@IBOutlet weak var laView: NSView! 

@IBOutlet weak var tableview: NSTableView! 

var array = [CGColor]() 
var array2label = [String]() 

func numberOfRowsInTableView(tableView: NSTableView) -> Int { 
    if (tableView.identifier == "Taula") { 

     return array.count 
     //return taulaGrafics.count 
    } else { 
     return 0 
    } 

} 

@IBOutlet weak var viewDeProva: NSView! 

func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? { 
    print ("Preparem la TableView") 
    var cellIdentifier: String = "" 


    if tableColumn == tableView.tableColumns[0] { 

     cellIdentifier = "CellID" 

     if let cell = tableView.makeViewWithIdentifier(cellIdentifier, owner: self) as? MyTableCellView { 
      print ("Here") 
      print(array) 
      print(array2label) 
      cell.identifier = cellIdentifier 
      cell.myView.layer?.backgroundColor = array[row] 
      cell.label.stringValue = array2label[row] 

      return cell 
     } 
    } 
    return nil 
} 

@IBAction func afegir(sender: NSButton) { 
    let color = NSColor.yellowColor().CGColor 
    array.append(color) 
    array2label.append("buLabel") 
    tableview.reloadData() 
} 
@IBAction func treure(sender: NSButton) { 
    array.removeLast() 
    array2label.removeLast() 
    tableview.reloadData() 
} 
} 

Le problème était que le NSView à l'intérieur de NSTableViewCell ne peut pas être remplacé par une autre vue, car w Ce que vous faites est de changer la cellule prototype. Donc, si vous remplacez la vue, NSTableViewCell ne reconnaît pas ce calque NewView (je ne suis pas sûr à 100% pourquoi). On dirait que certaines informations sont partagées. Alors, comment pouvons-nous transmettre des informations à la cellule tableview? Comment pouvons-nous montrer une couche là? Eh bien la réponse est qu'il suffit de modifier la cellule prototype NSTableCellView ajouté sur le constructeur de l'interface ou de sa sous-classe (comme mon cas, voir ci-dessous la cellule). Modification de son contenu, mais pas de NSView !, à l'intérieur de la fonction . Voir à ce morceau de code:

if let cell = tableView.makeViewWithIdentifier(cellIdentifier, owner: self) as? MyTableCellView { 

      cell.identifier = cellIdentifier // that is to identify the cell 
      cell.myView.layer?.backgroundColor = array[row] // see that the array contains CGCOLORS not NSViews 
      // The program was not showing the colors because the 
      // view copied doesn't copy its layer, or at least 
      // doesn't show it. 
      // Even though, if you say: *******---This is incorrect: 
      cell.myView = arrayOfNSViews[row] //the program will 
      // crash when removing 2 rows, myView = nil !!!!. 
      // That is because when you remove the item of the array 
      // somehow you are removing myView too, because it make a 
      // copy or a reference to it (Not sure what exactly). 
      // Here continues the correct program: ******--- 

      cell.label.stringValue = array2label[row] 

      return cell 
} 

voir aussi que dans le cas textField: cell.label.stringValue = array2label[row], vous modifiez la valeur de chaîne de la textfield, pas tout NSTextfield. Alors les gars se souviennent et répètent mes mots: «Je ne vais pas changer la vue de la cellule, juste ses propriétés». Je viens de passer 4 jours pour constater que ...

Voici le NStableCellView promis:

class MyTableCellView: NSTableCellView { 

    @IBOutlet weak var myView: NSView! 

    @IBOutlet weak var label: NSTextField! 

} 

une image de la hiérarchie de la vue:

enter image description here