質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

1096閲覧

NSImageViewの画像をPNGでドラッグ&ドロップして保存 Swift

denshatrain

総合スコア16

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2019/07/27 05:25

前提・実現したいこと

SwiftでmacOS用のアプリを作っています。NSImageViewの画像をPNGでドラッグ&ドロップを使い、保存できるようにしたいです。以下のサイトを参考にしました。

https://www.youtube.com/watch?v=sBk-Z8eBJRU

発生している問題・エラーメッセージ

Thread 1: signal SIGABRT

該当のソースコード

swift

1 2import Cocoa 3 4class IconViewController: NSViewController { 5 6 var img: NSImage! 7 8 @IBOutlet var img1: NSImageView! 9 @IBOutlet var img2: NSImageView! 10 @IBOutlet var img3: NSImageView! 11 @IBOutlet var img4: NSImageView! 12 @IBOutlet var img5: NSImageView! 13 @IBOutlet var img6: NSImageView! 14 @IBOutlet var img7: NSImageView! 15 @IBOutlet var img8: NSImageView! 16 @IBOutlet var img9: NSImageView! 17 @IBOutlet var img10: NSImageView! 18 @IBOutlet var img11: NSImageView! 19 @IBOutlet var img12: NSImageView! 20 @IBOutlet var img13: NSImageView! 21 @IBOutlet var img14: NSImageView! 22 @IBOutlet var img15: NSImageView! 23 @IBOutlet var img16: NSImageView! 24 @IBOutlet var img17: NSImageView! 25 @IBOutlet var img18: NSImageView! 26 27 override func viewDidLoad() { 28 super.viewDidLoad() 29 // Do view setup here. 30 31 img1.image = img.resize(size: NSSize(width: 40, height: 40)) 32 img2.image = img.resize(size: NSSize(width: 60, height: 60)) 33 img3.image = img.resize(size: NSSize(width: 58, height: 58)) 34 img4.image = img.resize(size: NSSize(width: 87, height: 87)) 35 img5.image = img.resize(size: NSSize(width: 80, height: 80)) 36 img6.image = img.resize(size: NSSize(width: 120, height: 120)) 37 img7.image = img.resize(size: NSSize(width: 120, height: 120)) 38 img8.image = img.resize(size: NSSize(width: 180, height: 180)) 39 img9.image = img.resize(size: NSSize(width: 20, height: 20)) 40 img10.image = img.resize(size: NSSize(width: 40, height: 40)) 41 img11.image = img.resize(size: NSSize(width: 29, height: 29)) 42 img12.image = img.resize(size: NSSize(width: 58, height: 58)) 43 img13.image = img.resize(size: NSSize(width: 40, height: 40)) 44 img14.image = img.resize(size: NSSize(width: 80, height: 80)) 45 img15.image = img.resize(size: NSSize(width: 76, height: 76)) 46 img16.image = img.resize(size: NSSize(width: 152, height: 152)) 47 img17.image = img.resize(size: NSSize(width: 167, height: 167)) 48 img18.image = img.resize(size: NSSize(width: 1024, height: 1024)) 49 50 51 } 52 53} 54 55class DnDClass: NSImageView, NSDraggingSource { 56 57 var mouseDOWN: NSEvent? 58 59 override init(frame frameRect: NSRect) { 60 super.init(frame: frameRect) 61 } 62 required init?(coder: NSCoder) { 63 super.init(coder: coder) 64 } 65 66 // DRAG 67 68 func draggingSession(_ session: NSDraggingSession, sourceOperationMaskFor context: NSDraggingContext) -> NSDragOperation { 69 return .copy 70 } 71 72 // helpfuncs 73 74 override func mouseDown(with event: NSEvent) { 75 mouseDOWN = event 76 } 77 78 override func mouseDragged(with event: NSEvent) { 79 let down = mouseDOWN!.locationInWindow 80 let drag = event.locationInWindow 81 let dist = hypot(down.x - drag.y, down.y - drag.y) 82 if dist < 5 {return} 83 84 let img = self.image 85 let frameOrigin = convert(down, to: nil) 86 let frame = NSRect(origin: frameOrigin, size: (img?.size)!).offsetBy(dx: -(75), dy: -(75)) 87 88 let item = NSDraggingItem(pasteboardWriter: img?.png as! NSPasteboardWriting) //ここでエラーが出ています。 89 item.draggingFrame = frame 90 item.imageComponentsProvider = { 91 let component = NSDraggingImageComponent(key: .icon) 92 component.contents = img! 93 component.frame = NSRect(origin: NSPoint(), size: NSSize(width: self.bounds.width, height: self.bounds.height)) 94 return [component] 95 } 96 97 beginDraggingSession(with: [item], event: mouseDOWN!, source: self) 98 99 } 100 101} 102 103extension NSBitmapImageRep { 104 var png: Data? { 105 return representation(using: .png, properties: [:]) 106 } 107} 108extension Data { 109 var bitmap: NSBitmapImageRep? { 110 return NSBitmapImageRep(data: self) 111 } 112} 113extension NSImage { 114 var png: Data? { 115 return tiffRepresentation?.bitmap?.png 116 } 117 func savePNG(to url: URL) -> Bool { 118 do { 119 try png?.write(to: url) 120 return true 121 } catch { 122 print(error) 123 return false 124 } 125 126 } 127 128 func resize(size: NSSize) -> NSImage { 129 let newImage = NSImage(size: size) 130 newImage.lockFocus() 131 132 self.size = size 133 134 NSGraphicsContext.current?.imageInterpolation = .high 135 self.draw(at: NSPoint.zero, from: CGRect(x: 0, y: 0, width: size.width, height: size.height), operation: .copy, fraction: 1.0) 136 newImage.unlockFocus() 137 138 return newImage 139 } 140 141} 142

試したこと

エラーが出た場所のimg?.png"img"とするとエラーは出ませんでした。

補足情報(FW/ツールのバージョンなど)

Xcode 10.3
macOS Mojave 10.14.6

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

(NS)DataはNSPasteboardWritingではないので今の方法では無理です。

僕ならNSFilePromiseProviderを使いますが、説明がすごく長くなってしまうのでAppleのサンプルを動かしてみて勉強してください。

Supporting Drag and Drop Through File Promises


追記

簡単に概要だけ。
NSFilePromiseProviderは指定場所にファイルを保存しますという約束をドラッグできるようにするものです。
プログラマはファイルタイプとNSFilePromiseProviderDelegateを実装したclassのオブジェクトを与えます。
ファイルタイプはPNGなら"image.png"です。

NSFilePromiseProviderDelegateの概要は

filePromiseProvider(_:fileNameForType:)
でファイル名を返します。このファイル名が使われるかどうかはドロップを受け入れた側に依存するので注意してください。

operationQueue(for:)
はファイルの変換や保存を行うNSOperationQueueを返します。
実装しなければmainスレッド上のNSOperationQueueが使われます。
時間のかかる処理がある場合は別のNSOperationQueueを生成して返します。

filePromiseProvider(:writePromiseTo:completionHandler:)
が変換や保存を行うメソッドです。
ドロップを受け入れた側が指定する保存場所がURLで渡されますので、そのURLにファイルを保存します。
渡されたURLには一切の加工を加えないでください。そのままそのURLに保存します。
処理が終了したらcompletionHandler(
:)を必ず実行してください。

投稿2019/07/28 01:47

編集2019/07/28 02:17
MasakiHori

総合スコア3384

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問