なんちゃってスライドメニュー 2
.offset()を使ってメニューを出し入れするもので条件により不具合が起こるみたい。
原因ははっきりしないけれど、おそらくViewサイズの取得タイミングとかで正確な値が取れないのかもしれない。
なので
.position()を使ってメニューを出し入れします。
位置固定なら.offset()で問題ないんでしょうが変更する事があるのなら.position()を使う方が良さそうです。
【MyApp.swift】
@main
struct MyApp: App {
@StateObject var dataModel = DataModel()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(dataModel)
}
}
}
・Viewサイズは削除してCGPointを返す関数に変更しました。
【DataModel.swift】
class DataModel: ObservableObject {
@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 MenuPosition() -> CGPoint {
let x :Double = showMenu ? menuWidth/2.0: -(menuWidth/2.0)
return CGPoint(x: x, y: menuHeight/2.0+20)
}
}
・シンプルにしました。
【ContentView.swift】
struct ContentView: View {
@EnvironmentObject var dataModel: DataModel
var body: some View {
ZStack {
ImageView()
MenuView()
}
}
}
・ここに .position()を付けてメニュー関係をまとめました。
【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 {
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()
}
}
)
}
.position(dataModel.MenuPosition())
}
}
・変更無し。
【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")
}
}
}