import SwiftUI
struct ContentView: View {
@State var showHamburgerMenu = false
var body: some View {
let drag = DragGesture()
.onEnded {
if $0.translation.width < -100 {
withAnimation {
self.showHamburgerMenu = false
}
}
}
NavigationView {
GeometryReader { geometry in
ZStack(alignment: .leading) {
MainView(showHamburgerMenu: self.$showHamburgerMenu)
.frame(width: geometry.size.width, height: geometry.size.height)
.offset(x: self.showHamburgerMenu ? geometry.size.width/2 : 0)
.disabled(self.showHamburgerMenu ? true : false)
if self.showHamburgerMenu {
SideMenuView(isOpen: $showHamburgerMenu)
.frame(width: geometry.size.width)
// .frame(width: geometry.size.width/2)
.transition(.move(edge: .leading))
}
}
.gesture(drag)
}
.navigationTitle("← Menu")
.navigationBarTitleDisplayMode(.inline)
.navigationBarItems(leading: (
Button(action: {
withAnimation {
self.showHamburgerMenu.toggle()
}
}) {
// Image(systemName: "line.horizontal.3")
Image(systemName: showHamburgerMenu ? "xmark" : "line.horizontal.3")
// .imageScale(.large)
.font(.title2)
.foregroundColor(.red)
}
))
}
}
}
struct MainView: View {
@Binding var showHamburgerMenu: Bool
@State var isShowSubViw = false
var body: some View {
ZStack{
Color.yellow
.frame(maxWidth: .infinity, maxHeight: .infinity)
.ignoresSafeArea()
ScrollView(.horizontal, showsIndicators: false) {
HStack{
GeometryReader { geometry in
ImageCarouselView(numberOfImages: 1) {
// Text("Bananas 🐻🐻")
Image(decorative: "d01")
.resizable()
.scaledToFit()
.frame(maxWidth: 80, maxHeight: 80, alignment: .center)
.clipShape(Circle())
}
}.frame(width: 383, height: 240)
GeometryReader { geometry in
ImageCarouselView(numberOfImages: 1) {
Text("Peaches 🍑🍑")
}
}.frame(width: 380, height: 240)
GeometryReader { geometry in
ImageCarouselView(numberOfImages: 1) {
Text("Apples 🍏🍏")
}
}.frame(width: 380, height: 240)
GeometryReader { geometry in
ImageCarouselView(numberOfImages: 1) {
Text("inuwan 🐶🐶")
}
}.frame(width: 382, height: 240)
GeometryReader { geometry in
ImageCarouselView(numberOfImages: 1) {
// Text("sakana 🐟🐟")
Image(decorative: "d04")
.resizable()
.scaledToFit()
.frame(maxWidth: 80, maxHeight: 80, alignment: .center)
.clipShape(Circle())
}
}.frame(width: 388, height: 240)
}.padding(.leading)
}
.foregroundColor(Color.white)
// .background(Color.yellow)
}
GeometryReader { geometory in
ZStack {
if isShowSubViw {
SubView()
} else {
Button(action: {
withAnimation() {
self.isShowSubViw.toggle()
}
}) {
Text("SubViewへ")
}
.padding(.top, 100)
VStack {
Text("MainView")
.font(.system(size: 35, weight: .black, design: .default))
.padding(.top, 50)
}
}
}
.frame(width: geometory.size.width,
height: geometory.size.height)
// .background(Color.yellow)
.animation(.easeInOut(duration: 0.42))
}
.transition(.move(edge: .leading))
}
}
struct SubView: View {
@State var isShowSubViw = false
let imageUrl = URL(string: "https://kyou.gif.jp/img/d07.jpg")
var body: some View {
ZStack{
LinearGradient(gradient: Gradient(colors: [Color.yellow, Color.green]), startPoint: .init(x: 0.3, y: 0.3), endPoint: .init(x: 0.55, y: 0.55))
.frame(maxWidth: .infinity, maxHeight: .infinity)
.ignoresSafeArea()
VStack{
AsyncImage(url: imageUrl) { image in
image.resizable()
.aspectRatio(contentMode: .fill)
.clipShape(Circle())
} placeholder: {
ProgressView()
}
.frame(width: 80, height: 80, alignment: .center)
.padding(.bottom, 50)
.padding(.trailing, 5)
// .mask(RoundedRectangle(cornerRadius: 10))
}
GeometryReader { geometory in
ZStack {
if isShowSubViw {
MainView(showHamburgerMenu: $isShowSubViw)
} else {
Button(action: {
withAnimation() {
self.isShowSubViw.toggle()
}
}) {
Text("MainViewへ")
}
.padding(.top, 100)
VStack {
Text("SubView")
.font(.system(size: 35, weight: .black, design: .default))
.padding(.top, 50)
}
}
}
.frame(width: geometory.size.width,
height: geometory.size.height)
// .background(Color.green)
// .background(
// gradient: Gradient(colors: [Color.yellow, Color.green]),
// startPoint: .init(x: 0.3, y: 0.3), // start地点
// endPoint: .init(x: 0.55, y: 0.55) // end地点
// ))
.animation(.easeInOut(duration: 0.42))
}
.transition(.move(edge: .leading))
}
}
}
struct SideMenuView: View {
@Binding var isOpen: Bool
let width: CGFloat = 280
var body: some View {
ZStack {
GeometryReader { geometry in
EmptyView()
}
.background(Color.gray.opacity(0.3))
.opacity(self.isOpen ? 1.0 : 0.0)
.opacity(1.0)
.animation(.easeIn(duration: 0.25))
.onTapGesture {
self.isOpen = false
}
VStack(alignment: .leading) {
HStack {
Image(systemName: "person")
.foregroundColor(.white)
.imageScale(.large)
NavigationLink(destination: ProfileView()) {
Text("Profile")
.foregroundColor(.white)
.font(.headline)
}
}
.padding(.top, 80)
HStack {
Image(systemName: "envelope")
.foregroundColor(.white)
.imageScale(.large)
NavigationLink(destination: MessagesView()) {
Text("Messages")
.foregroundColor(.white)
.font(.headline)
}
}
.padding(.top, 30)
HStack {
Image(systemName: "gear")
.foregroundColor(.white)
.imageScale(.large)
NavigationLink(destination: SettingsView()) {
Text("Settings")
.foregroundColor(.white)
.font(.headline)
}
}
.padding(.top, 30)
HStack {
Image(systemName: "pencil.circle")
.foregroundColor(.white)
.imageScale(.large)
NavigationLink(destination: PencilView()) {
Text("Pencil test")
.foregroundColor(.white)
.font(.headline)
}
}
.padding(.top, 30)
Spacer()
}
// .padding()
// .frame(maxWidth: .infinity, alignment: .leading)
// .background(Color(red: 132/255, green: 132/255, blue: 132/255))
// .edgesIgnoringSafeArea(.all)
.frame(width: width)
// .background(Color(UIColor.systemGray6))
.background(Color.gray)
.offset(x: self.isOpen ? 0 : -self.width)
.animation(.easeIn(duration: 0.25))
// .padding(.top, 100)
.padding(.leading, -100)
Spacer()
}
}
}
struct PencilView: View {
var body: some View {
ZStack{
Color.purple
.frame(maxWidth: .infinity, maxHeight: .infinity)
.ignoresSafeArea()
VStack{
Text("PencilView Subview")
Text("MyPencilView")
.font(.title)
}
.navigationTitle("PencilView")
.navigationBarBackButtonHidden(true)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
NavigationBackItem(title: "Menuへ戻る")
}
}
}
}
}
struct SettingsView: View {
var body: some View {
ZStack{
Color.yellow
.frame(maxWidth: .infinity, maxHeight: .infinity)
.ignoresSafeArea()
VStack{
Text("Settings Subview")
Text("MySubview")
.font(.title)
}
.navigationTitle("SettingsView")
.navigationBarBackButtonHidden(true)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
NavigationBackItem(title: "Menuへ戻る")
}
}
}
}
}
struct MessagesView: View {
var body: some View {
ZStack{
Color.green
.frame(maxWidth: .infinity, maxHeight: .infinity)
.ignoresSafeArea()
VStack{
Text("Messages Subview")
}
.navigationTitle("MessagesView")
.navigationBarBackButtonHidden(true)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
NavigationBackItem(title: "Menuへ戻る")
}
}
}
}
}
struct ProfileView: View {
init(){
//List全体の背景色の設定
UITableView.appearance().backgroundColor = UIColor.white
}
@State private var isNextPresented = false
var body: some View {
ZStack{
Color.orange
.frame(maxWidth: .infinity, maxHeight: .infinity)
.ignoresSafeArea()
NavigationView {
VStack{
Text("Profile Subview")
.font(.title)
List {
NavigationLink("ChildViewへ") {
ChildView()
}.listRowBackground(Color.gray.opacity(0.2))
}
}
}
// .navigationTitle("ProfileView")
.navigationBarBackButtonHidden(true)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
NavigationBackItem(title: "Menuへ戻る")
}
ToolbarItem(placement: .navigationBarTrailing){
Button {
isNextPresented.toggle()
} label: {
HStack {
Text("Next")
Image(systemName: "person.fill")
}
}
.fullScreenCover(isPresented: $isNextPresented) {
NextView()
}
}
}
}
}
}
struct ChildView: View {
@Environment(\.dismiss) var dismiss
var body: some View {
VStack {
Text("ChildView")
.font(.title)
}
.navigationBarBackButtonHidden(true)
Button(action: {
dismiss()
}, label: {
Text("Profile Subviewへ")
})
}
}
struct NextView: View {
@Environment(\.dismiss) private var dismiss
var body: some View {
VStack(spacing: 32) {
Text("Hello,NextView")
.font(.title)
Button {
dismiss()
} label: {
HStack {
Text("Nextへ")
Image(systemName: "chevron.up")
.resizable()
.frame(width: 30, height: 20)
}
}
}
}
}
struct NavigationBackItem: View {
@Environment(\.dismiss) private var dismissOn
var title : String = ""
var body: some View {
Button {
dismissOn()
} label: {
HStack {
Image(systemName: "lessthan")
.foregroundColor(.blue)
.padding(.leading, -4.0)
Text(title)
.foregroundColor(Color.blue)
.padding(.leading, -7.0)
}
}
}
}
struct ImageCarouselView: View {
private var numberOfImages: Int
private var content: Content
@State private var currentIndex: Int = 0
private let timer = Timer.publish(every: 3, on: .main, in: .common).autoconnect()
init(numberOfImages: Int, @ViewBuilder content: () -> Content) {
self.numberOfImages = numberOfImages
self.content = content()
}
var body: some View {
GeometryReader { geometry in
HStack(spacing: 0) {
self.content
}
.frame(width: geometry.size.width - 50, height: geometry.size.height - 50, alignment: .center)
.offset(x: CGFloat(self.currentIndex) * -geometry.size.width, y: 0)
.animation(.spring())
.onReceive(self.timer) { _ in
self.currentIndex = (self.currentIndex + 1) % 5
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}