2017-01-26 4 views
1

NSTableView内のカスタムNSTableCellViewにNSPopoverを追加しようとしています。正しい要素に対応するようにNSPopoverを表示させることはできますが、Popoverの位置は正しくありません。誰かがデザインに関するより良い提案をしている場合に私の問題を明確にする:ユーザーが連絡先の連絡先に連絡先を置いたときに、その連絡先の詳細情報をポップオーバーに表示したい(クリック不要)NSTableView内のカスタムNSTableCellViewの位置を取得する

現在NSPopoverは次のように初期化されます。 contactPopover = NSPopover(contentViewController: contactViewController, sender: allContactsViewController.view, bounds: contactTableCellView.frame) このイニシャライザはポップオーバービヘイビアを軽く設定し、popover.show(...)を呼び出します。 ここで、contactTableCellViewは、必要な連絡先のテーブルセルビューです。

contactTableCellView.frameは、カスタムNSTableCellViewのテンプレートがxibで開始されるため、常に(x、y)=(0,0)である可能性があります。 Popoverをテーブルに適切に配置するには、NSTableの起点を基準にしてテーブルのセルビューの位置を取得する必要があります。

現在、各NSTableCellViewにはマウスのトラッキングが設定されているため、マウス入力時に連絡先リストに通知して、対応するマウス入力の表のセルビューを渡すポップオーバーを表示します。これは、テーブルの相対的な位置を取得しようとすると、テーブルのセルビューにアクセスすることができますが、テーブルの起点に相対的なテーブルのセルビューの実際の位置を取得する方法については、ドキュメントでは何も見つかりません。私はこれが何であるかはよく分からないhttps://developer.apple.com/reference/appkit/nstableview https://developer.apple.com/reference/appkit/nstablecellview

+0

この問題を明確にするために、私が現在持っているものを投稿しますが、これは私の会社の製品のためではありません。 – Kirkova

答えて

0

@KenThomasesでconvoをオフにすると、テーブルビューのセル自体がポップオーバーを管理するのが最善の方法ですが、それは半分に過ぎません。私は説明します:

テーブルはテーブルのセルビューを再描画するので、contactTableCellViewはNSPopoverの存続期間全体にわたって存在することを約束できません。 contactTableCellViewと無関係なライフサイクルを持つpopoverが存在するためには、NSTableView(addressBookViewControllerと呼ぶことができます)を保持するクラスにNSPopoverオブジェクトが存在する必要がありました。したがって、addressBookViewControllerにはcontactPopoverという名前のメンバーがあり、addressBookViewControllerがまだメモリ内にある限り、ポップオーバーが存在することが確認できます。これに関する問題は、ポップオーバーがリンクするための正しい境界を取得することでした。

あなたが現在のcontactTableCellViewをaddressBookViewControllerに戻して、@ KenThomasesのようにcontactPopover.show(relativeTo:contactTableCellView.bounds of:contactTableCellView preferredEdge:.minY)のようなものを使用すると、Popoverは、どの要素に移動してもNSTableViewの最初の/先頭の要素に固執しますしかし、私は、ポップオーバーが上に乗っている要素を指すようにしたい。

私の仮説を証明するための参考資料は見つかりませんでしたが、私の結果から、NSTableViewには私が作成したカスタムContactTableCellViewを含むセル/ビューがあるようです。これは私が "contactTableCellView.frameにはいつも(x、y)=(0,0)"があるという理由です。フレームは常に親オブジェクトと相対的です。この場合、TableCellViewと同じサイズのビュー/セルです。そして、この外部ビューには、私が望んでいたフレーム/想定されたcontactTableCellView.frameがあるというフレームがありました。これを明確に言うには:

contactTableCellView.superView?.frameはNSTableViewに正しい(x、y)を与え、このフレームは削除されません。なぜなら、contactTableCellViewはさまざまな理由で再描画されるからです。私の調査結果を使用して、私はポップオーバーを得ることができた私はスウィフト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 
     } 
    } 
} 

} 

私NSPopoverがオン動作しますので、そうContactTableCellViewのスーパーは、正しいフレームを持っています私が元々望んでいたようなカスタムNSTableCellView!この特定の部分を理解するのに数時間かかりました。

1

は見

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

そのメソッドがどこから来ましたの?それ自体はNSPopoverの一部ではありません。

とにかく、これは余分な荷物なしで作成されたポップオーバーを想定し、ちょうどあなたが欲しいものを行う必要があります:あなたはセルの表示がどこにあるかを把握することなく、細胞ビューにポップオーバーを位置決めします

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

テーブルビュー内に表示されます。

+0

私はOPに明瞭さを加えました。この問題は実際には(contact)、contactTableCellView.bounds(Contact TableCellView.frames)、(x、y)を(0,0)として与えるようです。それは、私がセルのフレームを期待するものを正しく与えていない。 – Kirkova

+0

多分、TableViewセルの中で0,0のTableViewセルにバインドされていて、アプリケーションの境界である – muescha

+1

@Kirkovaに対して、テーブルビュー内のセルビューの位置を気にする必要はありません。テーブルビューではなくセルビューに対して**を表示すると、 'NSPopover'が適切なスクリーン位置を把握します。 –

関連する問題