頭と尻尾はくれてやる!

パソコンおやじのiPhoneアプリ・サイト作成・運営日記


macOSでFinderなどからtableにドラッグ&ドロップする



↑このようにアプリ外のファイルをNSTableViewオブジェクトにドラッグ&ドロップする。
NSTableViewはNSViewを継承している(※1)のでNSViewからのドラッグ&ドロップと同じでは?と最初は思ったが別な記述が必要になる。

optional func tableView(_ tableView: NSTableView, 
validateDrop info: NSDraggingInfo,
proposedRow row: Int,
proposedDropOperation dropOperation: NSTableView.DropOperation)
-> NSDragOperation
というNSTableViewDataSourceのメソッドでtableにドロップが可能かどうかの判定を行ってたりする。
実際にドロップされたファイル名などはNSTableViewのサブクラスで処理されるので、tableに表示するためdelegateを使ってViewControllerに渡し、tableに表示している。


YamaguchiTatsuya/DragAndDrop_OtherToTable: masOS sample code to drag and drop files from other app to NSTableView object
↑GitHubに置いたサンプルコードはこちら。



※1 NSTableViewの親はNSControlで、その親はNSView



macOS 10.15.2 Catalina
Swift 5.1.3
Xcode 11.3.1



関連記事
macOSでFinderなどからviewにドラッグ&ドロップする
macOSの同一アプリ内で画像などをドラッグ&ドロップする
macOSで同一アプリ内でtableからviewへドラッグ&ドロップする
macOSでFinderなどからtableにドラッグ&ドロップする(当記事)


参考記事
Using Drag and Drop with NSTableView — Nate Thompson
Drag and Drop Tutorial for macOS | raywenderlich.com
スポンサーサイト






macOSで同一アプリ内でtableからviewへドラッグ&ドロップする



↑このようにmacOS内のtableの表示項目(ファイル名とか)をドラッグし、NSViewオブジェクト部分へドロップする。

    func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) 
-> NSPasteboardWriting? {

return imageNames[row] as NSString
}
↑NSTableViewDataSourceのメソッドで何がドラッグ&ドロップされるのかを記述する。

    override func performDragOperation(_ draggingInfo: NSDraggingInfo) 
-> Bool {

let pasteBoard = draggingInfo.draggingPasteboard

let point = convert(draggingInfo.draggingLocation, from: nil)


if let strings = pasteBoard.readObjects(forClasses: [NSString.self],
options: nil) as? [String] {
processImages(strings, center: point)
}
return true
}
↑するとドロップした時点でpaste boardに入ってる先ほど指定した型のオブジェクトを得ることができる。


YamaguchiTatsuya/DragAndDrop_TableToView: masOS sample code to drag and drop files from NSTable to NSView object
↑GitHubに置いたサンプルコードはこちら。



macOS 10.15.2 Catalina
Swift 5.1.3
Xcode 11.3.1



関連記事
macOSでFinderなどからviewにドラッグ&ドロップする
macOSの同一アプリ内で画像などをドラッグ&ドロップする
macOSで同一アプリ内でtableからviewへドラッグ&ドロップする(当記事)
macOSでFinderなどからtableにドラッグ&ドロップする


参考記事
Using Drag and Drop with NSTableView — Nate Thompson
Drag and Drop Tutorial for macOS | raywenderlich.com


macOSの同一アプリ内で画像などをドラッグ&ドロップする



↑このようにNSViewオブジェクトに乗っている別なNSViewオブジェクト(ここでは画像)をマウスで動かしたい。

元々iOSで似たようなことをやってるコードがあったのでmacOS用に移植した。
{
let panGestureRecognizer = NSPanGestureRecognizer(target: self,
action: #selector(self.drawView(recognizer:)))

imageView.addGestureRecognizer(panGestureRecognizer)
}
↑ジェスチャーを設定。

    @objc private func drawView(recognizer: NSPanGestureRecognizer) {

guard let targetView = recognizer.view else {
assertionFailure("targetView is nil")
return
}

let distance = recognizer.translation(in: targetView)

let newCenter = CGPoint(x: targetView.center.x + distance.x,
y: targetView.center.y + distance.y)

targetView.center = newCenter

recognizer.setTranslation(CGPoint(x: 0, y: 0), in: targetView)
}
↑そのジェスチャーを拾う部分。
ほとんどiOSと同じなんだけど、他にmacOSならではのやり方があるのかも?


YamaguchiTatsuya/DragAndDrop_InView: masOS sample code to drag and drop an image in NSView object
↑GitHubに置いたサンプルコードはこちら。



macOS 10.15.2 Catalina
Swift 5.1.3
Xcode 11.3.1



関連記事
macOSでFinderなどからviewにドラッグ&ドロップする
macOSの同一アプリ内で画像などをドラッグ&ドロップする(当記事)
macOSで同一アプリ内でtableからviewへドラッグ&ドロップする
macOSでFinderなどからtableにドラッグ&ドロップする


参考記事
Using Drag and Drop with NSTableView — Nate Thompson
Drag and Drop Tutorial for macOS | raywenderlich.com



macOSでFinderなどからviewにドラッグ&ドロップする

macOSでのドラッグ&ドロップを実装してみた。
まずFinderやデスクトップからmacOSアプリへのドラッグ&ドロップの場合。



↑こんな感じでアプリ外からアプリ内のNSViewオブジェクト領域へドラッグ&ドロップするという動作。


Drag and Drop Tutorial for macOS | raywenderlich.com
↑参考にしたのはこちら。
ただ現在のSwift 5.1.3だと動かなかったこともあり、自分が理解できるように書き換えた。


いくつかのサンプルコードを見たがドロップするところのviewはNSViewのサブクラスとしてクラスのファイルを作成している。そこに
registerForDraggedTypes([.fileURL])
と記述しておくとドロップを受け付けてくれる。

optional func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation
override func prepareForDragOperation(_ sender: NSDraggingInfo) -> Bool
override func performDragOperation(_ draggingInfo: NSDraggingInfo) -> Bool
↑といったメソッドでどんなファイルがドラッグされてドロップしようとしてるのか、ドロップされたタイミングなどを取得できる。


YamaguchiTatsuya/DragAndDrop_OtherToView: masOS sample code to drag and drop files from other app to NSView object
↑GitHubに置いたサンプルコードはこちら。
マウスがドロップできるview上に来ると枠が表示される、といった機能は省いている。



macOS Catalina 10.15.2
Swift 5.1.3
Xcode 11.3.1



関連記事
macOSでFinderなどからviewにドラッグ&ドロップする(当記事)
macOSの同一アプリ内で画像などをドラッグ&ドロップする
macOSで同一アプリ内でtableからviewへドラッグ&ドロップする
macOSでFinderなどからtableにドラッグ&ドロップする

参考記事
Using Drag and Drop with NSTableView — Nate Thompson
Drag and Drop Tutorial for macOS | raywenderlich.com


macOSでバインドを使いテーブルを表示する

macOSでテーブルを表示させようとした。
NSTableViewDelegate、NSTableViewDataSourceを使わずにバインドを使う。
NSArrayControllerで検索するといろいろと参考ページが見つかると思う。

この方法は以前Objective-Cでやったことがあったのだが、今回はSwiftでやろうとしたらえらくはまってしまった。はまりすぎて、俺の理解がおかしいのか?とObjective-Cに戻ってまで確認したりもした。

YamaguchiTatsuya/NSTableViewWithBindings: Simple sample code for macOS, to show table view with bindings
↑とりあえず最小限のサンプルコードをGitHubで公開してみた。


NSArrayControllerをドラッグ&ドロップする

↑Interface builderでViewControllerにArrayControllerを追加(矢印のようにドラッグ&ドロップ)。

NSArrayController追加後の画面

↑ここに見えるので、これを選択して
1. outletを接続
2. Content ArrayをViewControllerのpropsArrayに設定

すると、ViewController内の以下のコードのように
        let tp1 = TableProps(name: "apple")
let tp2 = TableProps(name: "banana")
let tp3 = TableProps(name: "chocolate")

assert(arrayController != nil, "arrayController is nil")

arrayController?.addObject(tp1)
arrayController?.addObject(tp2)
arrayController?.addObject(tp3)

for tp in propsArray {
print(tp.name)
}

↑arrayControllerにデータを突っ込んだ直後にpropsArrayの中身を確認すると、ちゃんと表示されている!バインディングすげー!って感心しました。


テーブルで表示するには他にもテーブル周りでバインドを設定する必要がありますがサンプルコードでご確認ください。


なお、結局Objective-Cで動いたのにSwiftで動かず、
this class is not key value coding-compliant for the key name.
といったエラーばかり出てたのは、TablePropsクラスで@objc dynamic というのが必要だったためのようでした。

//var name: String = “” 実行時エラー
@objc dynamic var name: String = “”


Version
Swift 5.1.3




Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.