burger menu swipe
This commit is contained in:
parent
478020f6f2
commit
05a0d85c09
@ -10,8 +10,9 @@ struct MainView: View {
|
||||
@State private var accounts = ["@user1", "@user2", "@user3"]
|
||||
@State private var sheetType: ProfileTab.SheetType? = nil
|
||||
|
||||
// Состояние для бокового меню
|
||||
// Состояния для бокового меню
|
||||
@State private var isSideMenuPresented = false
|
||||
@State private var menuOffset: CGFloat = 0
|
||||
|
||||
private var tabTitle: String {
|
||||
switch selectedTab {
|
||||
@ -23,6 +24,10 @@ struct MainView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private var menuWidth: CGFloat {
|
||||
UIScreen.main.bounds.width * 0.8
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
ZStack {
|
||||
@ -61,28 +66,69 @@ struct MainView: View {
|
||||
.sheet(item: $sheetType) { type in
|
||||
// ... sheet presentation logic
|
||||
}
|
||||
// Затемнение фона при открытом меню
|
||||
.background(isSideMenuPresented ? Color.black.opacity(0.4) : Color.clear)
|
||||
.onTapGesture {
|
||||
|
||||
// Затемнение и закрытие по тапу
|
||||
if isSideMenuPresented {
|
||||
withAnimation {
|
||||
Color.black.opacity(0.4 + Double((menuOffset / menuWidth)))
|
||||
.ignoresSafeArea()
|
||||
.onTapGesture {
|
||||
withAnimation(.easeInOut) {
|
||||
isSideMenuPresented = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Боковое меню
|
||||
if isSideMenuPresented {
|
||||
HStack {
|
||||
SideMenuView(isPresented: $isSideMenuPresented)
|
||||
.frame(width: UIScreen.main.bounds.width * 0.8)
|
||||
Spacer()
|
||||
.frame(width: menuWidth)
|
||||
.offset(x: (isSideMenuPresented ? 0 : -menuWidth) + menuOffset)
|
||||
.ignoresSafeArea(edges: .vertical)
|
||||
.zIndex(1)
|
||||
}
|
||||
.ignoresSafeArea(edges: .vertical) // Игнорируем safe area
|
||||
.transition(.move(edge: .leading))
|
||||
.zIndex(1) // Убедимся, что меню поверх всего
|
||||
.gesture(
|
||||
DragGesture()
|
||||
.onChanged { gesture in
|
||||
// Разрешаем открывать только свайпом от левого края, а закрывать — откуда угодно
|
||||
if !isSideMenuPresented && gesture.startLocation.x > 60 {
|
||||
return
|
||||
}
|
||||
|
||||
let translation = gesture.translation.width
|
||||
|
||||
if isSideMenuPresented {
|
||||
// Если меню открыто, позволяем двигать его влево до полного закрытия
|
||||
let newOffset = max(-menuWidth, translation)
|
||||
self.menuOffset = min(0, newOffset)
|
||||
} else {
|
||||
// Если меню закрыто, позволяем двигать его вправо до полного открытия
|
||||
self.menuOffset = max(0, translation)
|
||||
}
|
||||
}
|
||||
.onEnded { gesture in
|
||||
// Если свайп был не от края (для закрытого меню), ничего не делаем
|
||||
if !isSideMenuPresented && gesture.startLocation.x > 60 {
|
||||
return
|
||||
}
|
||||
|
||||
let threshold = menuWidth * 0.4
|
||||
|
||||
withAnimation(.easeInOut) {
|
||||
if isSideMenuPresented {
|
||||
// Если меню было открыто и сдвинуто влево больше, чем на `threshold`
|
||||
if menuOffset < -threshold {
|
||||
isSideMenuPresented = false
|
||||
}
|
||||
} else {
|
||||
// Если меню было закрыто и сдвинуто вправо больше, чем на `threshold`
|
||||
if menuOffset > threshold {
|
||||
isSideMenuPresented = true
|
||||
}
|
||||
}
|
||||
// Возвращаем временное смещение в 0, основное состояние `isSideMenuPresented` сделает остальное
|
||||
self.menuOffset = 0
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
.navigationViewStyle(StackNavigationViewStyle())
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user