2017-01-26 2 views
1

Я пытаюсь добавить NSPopover в пользовательский NSTableCellView в NSTableView. Я могу получить NSPopover, чтобы он соответствовал правильному элементу, но позиция popover неверна. Чтобы яснить свою проблему, если у кого-то есть лучшее предложение для дизайна: когда пользователь наводится на контакт в таблице контактов, я хочу показать больше информации для этого контакта в popover (без щелчка)Получение позиции пользовательского NSTableCellView в NSTableView

В настоящее время NSPopover инициализируется следующим образом: contactPopover = NSPopover(contentViewController: contactViewController, sender: allContactsViewController.view, bounds: contactTableCellView.frame) , где этот инициализатор просто устанавливает поведение popover и вызывает popover.show (...) где contactTableCellView - это вид ячейки таблицы контакта, который я хочу.

Проблема заключается в том, что contactTableCellView.frame всегда имеет (x, y) = (0,0), потому что именно там начинается шаблон для настраиваемого NSTableCellView в xib. Чтобы правильно поместить popover в таблицу, мне нужно получить позицию представления ячейки таблицы относительно начала NSTable.

Прямо сейчас у каждого NSTableCellView есть настройка отслеживания мыши, так что при вводе мыши я уведомляю список контактов, чтобы отобразить popover, где я передаю соответствующий вид ячейки таблицы с мышью. Это дает мне доступ к представлению ячейки таблицы при попытке получить позицию относительно таблицы, но я не могу найти что-либо в документации о том, как получить реальную позицию представления ячейки таблицы относительно начала таблицы.

Смотрела: https://developer.apple.com/reference/appkit/nstableview https://developer.apple.com/reference/appkit/nstablecellview

+0

FYI, я бы разместил картинку для ясности проблемы и того, что у меня есть сейчас, но поскольку это для моего продукта компании, я не могу этого сделать. – Kirkova

ответ

0

Переход от конвоя с помощью @KenThomases, где лучшим способом было бы, чтобы ячейка представления таблицы сама управляла popover, но это возможно только наполовину. Я объясню:

Поскольку таблицы перерисовывают представления ячейки таблицы, contactTableCellView не может обещать, что он существует на протяжении всего срока службы NSPopover. Для того, чтобы popover существовал с жизненным циклом, не связанным с contactTableCellView, должен был иметь объект NSPopover в моем классе, содержащем NSTableView (позволяет называть его addressBookViewController). Таким образом, addressBookViewController будет иметь член с именем contactPopover и до тех пор, пока addressBookViewController все еще находится в памяти, мы можем быть уверены, что popover будет существовать. Проблема с этим заключалась в получении правильных границ для ссылки на popover.

Если передать текущий contactTableCellView обратно в addressBookViewController и просто использовать что-то вроде contactPopover.show(relativeTo:contactTableCellView.bounds of:contactTableCellView preferredEdge:.minY) как упомянуто @KenThomases, вы увидите, что поповер не застревает на первом/верхний элемент в NSTableView независимо от того, какой элемент я парить но я хочу, чтобы popover указывал на элемент, который зависал.

Я не смог найти какой-либо справочный материал, чтобы доказать свою гипотезу, но из моего результата кажется, что NSTableView имеет ячейки/представления, которые содержат настраиваемый ContactTableCellView, который я создал. Именно по этой причине я получаю «contactTableCellView.frame всегда имеет (x, y) = (0,0)». Кадр всегда относится к родительскому объекту, который в этом случае является представлением/ячейкой с тем же размером, что и TableCellView. И этот внешний вид имел фрейм, который я хотел/ожидал, чтобы иметь контакт с TableCellView.frame. Сказать это ясно:

contactTableCellView.superView? .frame дал правильный (x, y) в NSTableView, и этот фрейм не удаляется, поскольку contactTableCellView получает перерисовывание по разным причинам. Используя мои выводы, я был в состоянии получить поповер появляется относительно правильного элемента, как я хотел грубо, как это в Swift 3:

class AddressBookViewController { 
... 
var contactCardPopover: NSPopover? 
... 

func showContact(sender: AnyObject, contact: ContactVM) { 
    guard let contactTableCellView = sender as? ContactTableCellView else { return } 

    // when contactCardVC is non-nil, a popover currently open. This makes sure 2 don't open in the same tableView. 
    if contactViewController == nil { 
     contactCardViewController = ContactViewController(contact: contact) 

     // this here is the important part!!!! Using the contactTableCellView.superview 
     if let tableCell = participantTableCellView.superview { 

      contactCardPopover = NSPopover(contentViewController: contactCardViewController, sender: tableCell, bounds: tableCell.frame) 
      contactCardPopover.delegate = self 
     } 
    } 
} 

} 

Так SuperView из ContactTableCellView имеет правильный кадр, поэтому мой NSPopover работает на пользовательский NSTableCellView, как я изначально хотел! Для выяснения этой конкретной части потребовалось несколько часов.

1

Я не уверен, что речь идет о:

contactPopover = NSPopover(contentViewController: contactViewController, sender: allContactsViewController.view, bounds: contactTableCellView.frame) 

Где этот метод пришел? Это не часть самого NSPopover.

Во всяком случае, это должно делать только то, что вы хотите, предполагая поповер созданного без постороннего багажа:

contactPopover.show(relativeTo:contactTableCellView.bounds of:contactTableCellView preferredEdge:.minY) 

Это расположит поповер относительно точки зрения клеток без вас, чтобы выяснить, где вид ячейки в виде таблицы.

+0

Я добавил разъяснение к своему OP. Кажется, что проблема связана с 'contactTableCellView.bounds' или' contactTableCellView.frame', давая (x, y) как (0,0). Это неправильно дает то, что я ожидал бы от кадра ячейки. – Kirkova

+0

, возможно, внутри ячейки TableView оно ограничено 0,0 ячейкой TableView и относительно границ вашего приложения – muescha

+1

@ Кирковой, дело в том, что вам не нужно заботиться о позиции ячейки в представлении таблицы. Если вы показываете ** относительно вида ячейки, а не вида таблицы **, тогда 'NSPopover' будет определять соответствующую позицию экрана. –

Смежные вопросы