Граница не отображается в NSView внутри NSTableCellView - PullRequest
0 голосов
/ 05 августа 2020

У меня три NSView s внутри NSTableCellView. В зависимости от данных для строки я хочу показать выбранную роль с рамкой на NSView следующим образом:

enter image description here

The blue border NSView is a subclass that looks like this:

class RolePill: NSView{
  override func draw(_ dirtyRect: NSRect)  {
    super.draw(dirtyRect)
    layer?.cornerRadius = 9
    layer?.borderWidth = 2
    layer?.borderColor = NSColor.clear.cgColor
  }
}

The role gets set initially when my table loads like this:

extension UsersVC: NSTableViewDelegate, NSTableViewDataSource{
  func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
    let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "UserCell"), owner: nil) as! UserCell

    let user = users[row]

    //Role
    cell.setRole(role: user.role)
  }
}

And my table cell, where the role gets set on load and on a button click, is set up like this:

class UserCell: NSTableCellView{
  @IBOutlet weak var wrapOwner: RolePill!
  @IBOutlet weak var wrapAdmin: RolePill!
  @IBOutlet weak var wrapUser: RolePill!

  @IBAction func clickOwner(_ sender: NSButton) {
    setRole(role: "owner")
  }
  @IBAction func clickAdmin(_ sender: NSButton) {
    setRole(role: "admin")
  }
  @IBAction func clickUser(_ sender: NSButton) {
    setRole(role: "user")
  }
  
  func setRole(role: String){
    let selectedColor = getAccentColor()
    let offColor = Color(named: "BravoDark")!
    let offTextColor = Color(named: "BFC0C2")
    
    switch role{
      case "owner":
        wrapOwner.layer?.borderColor = selectedColor.cgColor
        wrapAdmin.layer?.borderColor = offColor.cgColor
        wrapUser.layer?.borderColor = offColor.cgColor
      
        labelOwner.textColor = Color.white
        labelAdmin.textColor = offTextColor
        labelUser.textColor = offTextColor
      case "admin":
        wrapOwner.layer?.borderColor = offColor.cgColor
        wrapAdmin.layer?.borderColor = selectedColor.cgColor
        wrapUser.layer?.borderColor = offColor.cgColor
        
        labelOwner.textColor = offTextColor
        labelAdmin.textColor = Color.white
        labelUser.textColor = offTextColor
        
      default:
        wrapOwner.layer?.borderColor = offColor.cgColor
        wrapAdmin.layer?.borderColor = offColor.cgColor
        wrapUser.layer?.borderColor = selectedColor.cgColor
      
        labelOwner.textColor = offTextColor
        labelAdmin.textColor = offTextColor
        labelUser.textColor = Color.white 
    }
    
  }
}

When the table loads initially, and anytime it refreshes (tableView.reloadData()) I lose my border and it looks like this:

введите описание изображения здесь

Как видите, textColor правильно настроен на белый цвет. Но по какой-то причине граница не устанавливается, пока я не нажму на одну из кнопок IBAction и вручную не активирую изменение.

Я подозреваю, что это какая-то ошибка рисования слоя, когда RolePill класс перерисовывается каждый раз, когда мой NSTableView перезагружается, но я не знаю, как заставить его принимать исходное состояние роли, отправленное в tableView viewForRow.

Есть идеи, что я здесь делаю не так? Спасибо!

1 Ответ

0 голосов
/ 06 августа 2020

Мне удалось заставить это работать, установив все свойства NSView внутри setRole() следующим образом:

view.wantsLayer = true
view.layer?.cornerRadius = 11
view.layer?.borderWidth = 2
view.layer?.borderColor = getAccentColor().cgColor

label.textColor = Color.white

Казалось, что метод draw() в моем подклассе RolePill был вызвали часто, поэтому я не мог установить цвет границы там, поскольку он не знает, что такое состояние данных пользователя.

...