Это создает две проблемы:
- Без наложения MenuButton имеет нестандартный размер, например. 50x50 и может нормально размещаться в окружающей его иерархии представлений. При добавлении наложения кнопка MenuButton становится размером с экран и поэтому не может быть размещена должным образом.
- При отображении наложение, пока меню активно, оно может отображать только те виды, которые находятся в иерархии представлений.
Код: Выделить всё
struct MenuButton: View {
@State private var isExpanded = false
let buttons: [String]
let buttonSize: CGFloat = 60
let itemButtonSize: CGFloat = 50
var body: some View {
ZStack {
// Overlay
/*Color.black.opacity(0.2)
.edgesIgnoringSafeArea(.all)
.opacity(isExpanded ? 1 : 0)
.onTapGesture {
isExpanded = false
}*/
ForEach(buttons.indices, id: \.self) { index in
VStack {
Image(systemName: buttons[index])
.frame(width: itemButtonSize, height: itemButtonSize)
.background(Color(.systemGray6))
.clipShape(Circle())
}
.offset(
x: 0,
y: isExpanded ? Double(index+1) * (-itemButtonSize - 20) : Double(index+1) * (-itemButtonSize + 20)
)
.opacity(isExpanded ? 1 : 0)
.animation(isExpanded ? .spring(response: 0.2, dampingFraction: 0.5, blendDuration: 0).delay(Double(index) * 0.05) : .easeOut(duration: 0.2), value: isExpanded)
}
Button {
withAnimation {
isExpanded.toggle()
}
} label: {
Image(systemName: isExpanded ? "xmark" : "plus")
.frame(width: buttonSize, height: buttonSize)
.foregroundColor(.gray)
.background(Color(.systemGray6))
.clipShape(Circle())
}
}
}
}
struct MenuView: View {
var body: some View {
VStack {
Spacer()
HStack {
Spacer()
MenuButton(buttons: ["circle", "star", "bell"])
.padding()
}
Text("Bottom")
}
}
}
#Preview {
MenuView()
}


Подробнее здесь: https://stackoverflow.com/questions/793 ... -active-ab