diff --git a/Shared/Views/Tab/MainView.swift b/Shared/Views/Tab/MainView.swift index 824ca78..f1aaa2a 100644 --- a/Shared/Views/Tab/MainView.swift +++ b/Shared/Views/Tab/MainView.swift @@ -30,7 +30,7 @@ struct MainView: View { var body: some View { NavigationView { - ZStack { + ZStack(alignment: .leading) { // Выравниваем ZStack по левому краю // Основной контент VStack(spacing: 0) { TopBarView( @@ -61,6 +61,7 @@ struct MainView: View { print("Create button tapped") } } + .frame(maxWidth: .infinity, maxHeight: .infinity) // Убедимся, что основной контент занимает все пространство .ignoresSafeArea(edges: .bottom) .navigationBarHidden(true) .sheet(item: $sheetType) { type in @@ -69,7 +70,7 @@ struct MainView: View { // Затемнение и закрытие по тапу if isSideMenuPresented { - Color.black.opacity(0.4 + Double((menuOffset / menuWidth))) + Color.black.opacity(0.4 * Double(((menuWidth + menuOffset) / menuWidth))) .ignoresSafeArea() .onTapGesture { withAnimation(.easeInOut) { @@ -81,56 +82,48 @@ struct MainView: View { // Боковое меню SideMenuView(isPresented: $isSideMenuPresented) .frame(width: menuWidth) - .offset(x: (isSideMenuPresented ? 0 : -menuWidth) + menuOffset) + .offset(x: -menuWidth + menuOffset) // Новая логика смещения .ignoresSafeArea(edges: .vertical) - .zIndex(1) } .gesture( DragGesture() .onChanged { gesture in - // Разрешаем открывать только свайпом от левого края, а закрывать — откуда угодно - if !isSideMenuPresented && gesture.startLocation.x > 60 { - return - } + if !isSideMenuPresented && gesture.startLocation.x > 60 { return } let translation = gesture.translation.width if isSideMenuPresented { - // Если меню открыто, позволяем двигать его влево до полного закрытия - let newOffset = max(-menuWidth, translation) - self.menuOffset = min(0, newOffset) + // При закрытии двигаем от 0 до -menuWidth + self.menuOffset = max(0, menuWidth + translation) } else { - // Если меню закрыто, позволяем двигать его вправо до полного открытия - self.menuOffset = max(0, translation) + // При открытии двигаем от 0 до menuWidth + self.menuOffset = min(menuWidth, translation) } } .onEnded { gesture in - // Если свайп был не от края (для закрытого меню), ничего не делаем - if !isSideMenuPresented && gesture.startLocation.x > 60 { - return - } + if !isSideMenuPresented && gesture.startLocation.x > 60 { return } let threshold = menuWidth * 0.4 withAnimation(.easeInOut) { - if isSideMenuPresented { - // Если меню было открыто и сдвинуто влево больше, чем на `threshold` - if menuOffset < -threshold { - isSideMenuPresented = false - } + if self.menuOffset > threshold { + isSideMenuPresented = true } else { - // Если меню было закрыто и сдвинуто вправо больше, чем на `threshold` - if menuOffset > threshold { - isSideMenuPresented = true - } + isSideMenuPresented = false } - // Возвращаем временное смещение в 0, основное состояние `isSideMenuPresented` сделает остальное - self.menuOffset = 0 + // Сбрасываем menuOffset, так как isSideMenuPresented теперь главный источник истины + self.menuOffset = isSideMenuPresented ? menuWidth : 0 } } ) } .navigationViewStyle(StackNavigationViewStyle()) + .onChange(of: isSideMenuPresented) { presented in + // Плавная анимация при нажатии на кнопку, а не только при жесте + withAnimation(.easeInOut) { + menuOffset = presented ? menuWidth : 0 + } + } } }