burger menu fix pos

This commit is contained in:
cheykrym 2025-08-14 02:21:34 +03:00
parent 05a0d85c09
commit f172e33123

View File

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