NSTableViewでマウスクリックが発生したときと、発生したときを検出して、クリックされたセルの行と列を特定しようとしています。
これまでのところ、NSTableViewSelectionDidChangeNotificationを使用しようとしましたが、2つの問題があります。
これを行うためのより良い(そして正しい)方法はありますか?
ユーザーが行をクリックするのをキャッチするには(ユーザーが行をクリックしたときのみ、プログラムで選択されたときではありません):
NSTableViewをサブクラス化し、プロトコルを宣言します
MyTableView.h
_@protocol ExtendedTableViewDelegate <NSObject>
- (void)tableView:(NSTableView *)tableView didClickedRow:(NSInteger)row;
@end
@interface MyTableView : NSTableView
@property (nonatomic, weak) id<ExtendedTableViewDelegate> extendedDelegate;
@end
_
MyTableView.m
マウスダウンイベントを処理する(ユーザーが外側をクリックしたときにデリゲートコールバックが呼び出されないことに注意してください。その場合も処理する必要があります。その場合は、条件 "if (clickedRow != -1)
")
_- (void)mouseDown:(NSEvent *)theEvent {
NSPoint globalLocation = [theEvent locationInWindow];
NSPoint localLocation = [self convertPoint:globalLocation fromView:nil];
NSInteger clickedRow = [self rowAtPoint:localLocation];
[super mouseDown:theEvent];
if (clickedRow != -1) {
[self.extendedDelegate tableView:self didClickedRow:clickedRow];
}
}
_
WCを作成、VC ExtendedTableViewDelegateに準拠。
_@interface MyViewController : DocumentBaseViewController<ExtendedTableViewDelegate, NSTableViewDelegate, NSTableViewDataSource>
_
MyTableViewのextendedDelegateをWCに設定しますVC(MyViewController)
MyTableView.mのどこか
_self.myTableView.extendedDelegate = self
_
デリゲート(MyViewController.m)にコールバックを実装します
_- (void)tableView:(NSTableView *)tableView didClickedRow:(NSInteger)row {
// have fun
}
_
簡単な方法があります。
MacOS10.12.2およびXcode8.2.1でSwift 3.0.2でテスト済み
しましょう
tableView.action = #selector(onItemClicked)
その後
@objc private func onItemClicked() {
print("row \(tableView.clickedRow), col \(tableView.clickedColumn) clicked")
}
私は次のようにすることを好みます。
オーバーライド
-(BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(NSInteger)row;
スーパー実装を提供します。
RequiredRow = row;
RequiredColumn = [tableView clickedColumn];
お役に立てれば。
誰かがSwiftバージョンのPeterLapisuの答えを探している場合。
NSTableViewの拡張機能(NSTableView + Clickable.Swift)を追加します。
import Foundation
import Cocoa
extension NSTableView {
open override func mouseDown(with event: NSEvent) {
let globalLocation = event.locationInWindow
let localLocation = self.convert(globalLocation, to: nil)
let clickedRow = self.row(at: localLocation)
super.mouseDown(with: event)
if (clickedRow != -1) {
(self.delegate as? NSTableViewClickableDelegate)?.tableView(self, didClickRow: clickedRow)
}
}
}
protocol NSTableViewClickableDelegate: NSTableViewDelegate {
func tableView(_ tableView: NSTableView, didClickRow row: Int)
}
次に、それを使用するには、新しいデリゲートプロトコルを実装していることを確認してください。
extension MyViewController: NSTableViewClickableDelegate {
@nonobjc func tableView(_ tableView: NSTableView, didClickRow row: Int) {
Swift.print("Clicked row \(row)")
}
}
@nonobjc
属性は、didClickに近いという警告を消します。
誰かがSwiftおよび/またはNSOutlineViewでそれを探していた場合に備えて。
@Peter Lapisuの指示に基づいています。
class MYOutlineViewDelegate: NSOutlineView, NSOutlineViewDelegate,NSOutlineViewDataSource{
//....
}
extension MYOutlineViewDelegate{
func outlineView(outlineView: NSOutlineView, didClickTableRow item: AnyObject?) {
//Click stuff
}
override func mouseDown(theEvent: NSEvent) {
let globalLocation:NSPoint = theEvent.locationInWindow
let localLocation:NSPoint = self.convertPoint(globalLocation, fromView: nil)
let clickedRow:Int = self.rowAtPoint(localLocation)
super.mouseDown(theEvent)
if (clickedRow != -1) {
self.outlineView(self, didClickTableRow: self.itemAtRow(clickedRow))
}
}}