【お知らせ】
SwiftUIで作った macOS Todo アプリ
ToDone
を100ダウンロードまで無料にしました。マニュアルページは、ToDone サポートページ です。
【本文】
将来的には、ペイントを簡単にしたようなグラフィックエディターを作りたいのですが、そこには一気に進めないので、まずは図形をドラッグできるところまでをやってみようと思います。
このコーナーでは、任意のテキストエディタでコードを記述し、 ターミナルを使ってビルドする方法で作業を進めています。Xcode をお使いの場合は、Xcodeで作業する場合 をご一読ください。
なお、ターミナルを使う場合も、Swift コンパイラや SwiftUI フレームワークなどを Mac にインストールするために Xcode をインストールして、一度起動させなければなりません。インストールが終われば Xcode は終了しても大丈夫です。
また、作成したアプリケーションを App Storeに提出するためのファイルにするには、 Xcode を使わなければならなかったかもしれません。 どこかで Xcode を使わずに作る方法を見たような気もするのですが...
私の開発環境は次のとおりです。
ドラッグで図形を移動するには、DragGesture を使うのが良さそうです。まずは次のサンプルを土台にしてみます。
DragGesture | Apple Developer Documentation
Xcode では、プロダクト名App.swift になります。コード内容は macOS 用に少し変更しています。
import SwiftUI
@main
struct FooApp: App {
init() {
// Tab(タブ)に関するメニューを削除するために次のコードを追加しました。
NSWindow.allowsAutomaticWindowTabbing = false
}
var body: some Scene {
WindowGroup {
ContentView()
}
.commands(content: {
// New Window メニューを削除するために次のコードを追加しました。
CommandGroup(replacing: .newItem) {}
})
}
}
Xcode では、ContentView.swift になります。コード内容は macOS 用に少し変更しています。
import SwiftUI
struct ContentView: View {
@State var isDragging = false
var drag: some Gesture {
DragGesture()
.onChanged { _ in self.isDragging = true }
.onEnded { _ in self.isDragging = false }
}
var body: some View {
VStack {
Circle()
.fill(self.isDragging ? Color.red : Color.blue)
.frame(width: 100, height: 100, alignment: .center)
.gesture(drag)
}
// macOS 用にウィンドウの大きさを設定しています。
.frame(minWidth: 300, maxWidth: .infinity, minHeight: 300, maxHeight: .infinity)
// macOS 用にウィンドウを閉じるとアプリケーションも終了するようにしています
.onDisappear(){ NSApplication.shared.terminate(self)}
}
}
Xcode で作業する場合は、この部分は無視してください。 ターミナルで作業する場合は「アイコン」を参考にしてアプリケーションバンドルを作ってください。 アプリケーションの名前を変えるために、Info.plist の CFBundleName を書き換えます。ここでは「Drag」という名前にしました。
アイコンは次のサイトから .icns ファイルをダウンロードしました。
フリーアイコンSVG、PNG、ICO、ICNS
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"https://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>foo</string>
<key>CFBundleIconFile</key>
<string>icon-macbook.icns</string>
<key>CFBundleName</key>
<string>Drag</string>
</dict>
</plist>
Xcode で作業している場合は、▶︎(ビルドボタン)をクリックするか、⌘Rを押してください。ターミナルでビルドする場合は次のようにします。
swiftc App.swift View.swift -o foo
mv foo Foo.app/Contents/MacOS
青い円をドラッグすると、移動はできませんが赤い色に変わります。マウスをリリース(ドロップ)すると青い色に戻ります。とりあえずドラッグとドロップのタイミングは感知できているみたいです。これを移動に変えれば良いわけですよねー。簡単にできるかな?
Xcode では、ContentView.swift になります。App.swift(プロダクト名App.swift)は、前述と同じです。
import SwiftUI
struct ContentView: View {
@State var isDragging = false
@State var location = CGPoint(x: 150, y: 150)
var drag: some Gesture {
DragGesture()
.onChanged { value in
location = value.location
self.isDragging = true
}
.onEnded { _ in self.isDragging = false }
}
var body: some View {
VStack {
Circle()
.fill(self.isDragging ? Color.red : Color.blue)
//.frame(width: 100, height: 100, alignment: .center)
.frame(width: 100, height: 100)
.position(location)
.gesture(drag)
}
.frame(minWidth: 300, maxWidth: .infinity, minHeight: 300, maxHeight: .infinity)
.onDisappear(){ NSApplication.shared.terminate(self)}
}
}
ドラッグで円を移動できるようになりました。