頭と尻尾はくれてやる!

iOSアプリなどの開発日記です


SwiftでInt?をCGFloat?にしたい

Swiftの関数でオプショナル型の整数をもらって、それがnilならnilで、値があるならCGFloatに(つまりCGFloat?に)したい。
func f(_ i: Int?) {
//let cgf = CGFloat(i)//—(1)
//let cgf = i as? CGFloat//—(2)
let cgf = (i != nil) ? CGFloat(i!) : nil//—(3)

}

//(1)はオプショナル型に対してはダメ、という下のようなエラーメッセージが出る。
Cannot invoke initializer for type 'CGFloat' with an argument list of type '(Int?)'

//(2)だとコンパイルは通るけど下のような警告通り機能しない。
Cast from 'Int?' to unrelated type 'CGFloat' always fails

//(3)の三項演算子はちゃんと動くけど、、、見にくいぞ!数ヶ月後に見たら怒りが湧くだろう。

Swiftのことだから何かうまい書き方がありそうなものだけど、よくわからなかった、、、

ということでextensionでなんとかしてみた。
実はオプショナル型のにextensionを書いたのは初めてだ。こんな風に書くのね。
extension Optional where Wrapped == Int {
var toOptCGFloat: CGFloat? {
if self == nil {
return nil
}
return CGFloat(self!)
}
}

こうしておくとさっきのは↓このようにすっきり書ける。
func f(_ i: Int?) {
let cgf = i.toOptCGFloat

}
スポンサーサイト






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


  TopPage  



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