なんちゃってスライドメニュー
スイッチボタンをタップするとメニューがスクリーン外へ出て行ったり外から入ってきたりする。
作業用のViewとメニュー用のViewを用意して、ContentViewに配置する。
メニューのViewのオフセットを変更するとメニューがスライドする感じで。
x: を変更すると左右にスライド。
y: を変更すると上下にスライド。
【MyApp.swift】
@main
struct MyApp: App {
@StateObject var dataModel = DataModel()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(dataModel)
}
}
}
・分かりやすいようにデータをまとめておく。
【DataModel.swift】
class DataModel: ObservableObject {
@Published var viewWidth: CGFloat = CGFloat.zero
@Published var viewHeight: CGFloat = CGFloat.zero
@Published var menuWidth: CGFloat = 200.0
@Published var menuHeight: CGFloat = 300.0
@Published var showMenu: Bool = true
@Published var originalImage: UIImage? = UIImage(named: "Test1") // フォルダに画像ファイルを用意
func MenuWidthOffset() -> CGFloat {
let value: CGFloat = (menuWidth - viewWidth)/2.0
return showMenu ? (value) : (value - menuWidth)
}
func MenuHeightOffset() -> CGFloat {
return (menuHeight - viewHeight)/2.0
}
}
・ContentViewが表示された時に .onAppearで幅と縦を保存しておく。
【ContentView.swift】
struct ContentView: View {
@EnvironmentObject var dataModel: DataModel
var body: some View {
GeometryReader{ geometry in
ZStack {
ImageView()
MenuView()
.offset(x:dataModel.MenuWidthOffset(),y:dataModel.MenuHeightOffset())
}
.onAppear{
dataModel.viewWidth = geometry.size.width
dataModel.viewHeight = geometry.size.height
}
}
}
}
・基本という事でシンプル構成で。
【MenuView.swift】
struct MenuView: View {
@EnvironmentObject var dataModel: DataModel
var body: some View {
HStack(alignment: .top) {
ZStack {
RoundedRectangle(cornerRadius: 15.0) // メニューの下地
.fill(Color.white)
.frame(width: dataModel.menuWidth, height: dataModel.menuHeight )
.shadow(color: .black,radius: 10 , x: 5, y: 5)
VStack(alignment: .center, content: {
Button("Test1") {
withAnimation { // Test1、2、画像ファイルをフォルダに用意した
dataModel.originalImage = UIImage(named: "Test1")
}
}
Button("Test2") {
withAnimation {
dataModel.originalImage = UIImage(named: "Test2")
}
}
})
}
// メニューの開閉ボタン。矢印を左向き右向きに切り替え
Image(systemName: dataModel.showMenu ? "arrowshape.left.fill":"arrowshape.right.fill")
.background(Color.white)
.offset(x:dataModel.showMenu ? -40: 10,y:20) // 微調整(笑)
.gesture(
TapGesture()
.onEnded{_ in
withAnimation {
dataModel.showMenu.toggle()
}
}
)
}
}
}
・作業用Viewの代わり。
【ImageView.swift】
struct ImageView: View {
@EnvironmentObject var dataModel: DataModel
var body: some View {
if let image = dataModel.originalImage { // 画像ファイル読み込みで問題有無の分岐
Image(uiImage: image)
.resizable()
.scaledToFill()
}
else {
Image(systemName: "doc")
Text("No data")
}
}
}
作成アプリを初回起動した時にメニュー位置がバグります。
終了して起動し直すと正常な位置にメニューが表示されます。
作成ツールのバグか、お行儀がよろしくないか、後で調査する。