Sponsor Link
環境&対象
- macOS Big Sur 11.2
- Xcode 12.4
- iOS 14.4
作成したビューの Swift Package 化
作成したサイコロビュー(DiceView) を Swift Package 化して、再利用しやすくしてみます。
Swift Package の作成
Xcode の “File” メニューから “New” – “Swift Package…” を選択します。
ここでは、”SDSDiceView” という名称にしました。
ポイントとしては、同じダイアログ下部にある “Add to” には、現在のプロジェクトを ”Group”には、SwiftPackage を登録したいグループを選択する必要があります。
この設定をすることで、Swift Package を clone してきた フォルダを プロジェクト内部に D&D で登録した状態となります。
View の public 化
Swift Package 化するとデフォルトのアクセス制限では、モジュール内部に遮蔽されてしまいます。
必要な要素を Public にすることが必要となります。
具体的には、以下の要素を public 指定する必要があります。
- SDSDiceView struct そのもの
- SDSDiceView#init
- SDSDiceView#body
# SwiftPackage 化の際に、View 名を DiceView から SDSDiceView に変更しています。
//
// SDSDiceView.swift
//
// Created by : Tomoaki Yagishita on 2021/02/05
// © 2021 SmallDeskSoftware
//
import SwiftUI
import Combine
public struct SDSDiceView: View {
@Binding var dice:Int
let publisher:AnyPublisher
@State private var animate = false
// (1) public 化
public init(_ dice:Binding, _ requester:AnyPublisher) {
self._dice = dice
self.publisher = requester
}
// (2) public 化
public var body: some View {
VStack {
// (3) リソースは、Bundle.module 経由でアクセス
Image("\(dice)", bundle: .module)
.resizable()
.scaledToFit()
.rotation3DEffect(
Angle.degrees(animate ? 360 * 20 : 0),
axis: (x:1, y:1, z:1))
}
.onReceive(publisher) { () in
self.roll()
}
}
public func roll() {
withAnimation(Animation.default.repeatForever()) {
animate.toggle()
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
withAnimation {
self.dice = Int.random(in: 1...6)
animate.toggle()
}
}
return
}
}
struct SDSDiceView_Previews: PreviewProvider {
static var previews: some View {
SDSDiceView(.constant(3), PassthroughSubject().eraseToAnyPublisher())
}
}
リソースアクセスの変更
SwiftPackage 内のリソースには、Bundle.module 経由でアクセスすることになります。
# Bundle.module は、Package 内部から参照できる static 定義になっています。
上記の Public 化と合わせて修正します。
なお、この変更を行わないと、リソースを main の Bundle に探しに行き、アプリ実行時にリソースが見つけられずエラーとなります。
Package.swift で Target に resources 設定を行わないと、Bundle.module は定義されません
リモートリポジトリの作成
SourceControl ナビゲータに移動して、右クリックから New “SDSDiceView” Remote… を選択して、リポジトリを GitHub に作成します。
SwiftPackage としては、GitHub 以外でも問題ありません。参照できるリポジトリであれば OK です。
SwiftPackage として参照する
使う側のビューでは、import 宣言が必要となります。
モジュール名を SDSDiceView にしましたので、”import SDSDiceView” が必要となります。
//
// ContentView.swift
//
// Created by : Tomoaki Yagishita on 2021/02/03
// © 2021 SmallDeskSoftware
//
//
import SwiftUI
import Combine
import SDSDiceView // - 追加
struct ContentView: View {
@State private var dice1:Int = Int.random(in: 1...6)
@State private var dice2:Int = Int.random(in: 1...6)
@State private var dice3:Int = Int.random(in: 1...6)
var requester = PassthroughSubject()
var body: some View {
VStack {
HStack {
SDSDiceView($dice1, requester.eraseToAnyPublisher())
SDSDiceView($dice2, requester.eraseToAnyPublisher())
SDSDiceView($dice3, requester.eraseToAnyPublisher())
}
Text("\(dice1) - \(dice2) - \(dice3)")
Button(action: {
self.requester.send()
}, label: {
Text("Roll")
})
}
.padding()
}
}
ここで作成した SDSDiceView は、こちら にあります。
まとめ
これで、サイコロを振るようなアプリでは簡単に DiceView が使えるようになりました。
説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。
SwiftUI おすすめ本
SwiftUI を理解するには、以下の本がおすすめです。
# SwiftUI2.0 が登場したことで少し古くなってしまいましたが、いまでも 定番本です。
Sponsor Link