fix network pop
This commit is contained in:
parent
906456a543
commit
728066030b
131
punchnet/Views/Network/NetworkMenuView.swift
Normal file
131
punchnet/Views/Network/NetworkMenuView.swift
Normal file
@ -0,0 +1,131 @@
|
||||
import SwiftUI
|
||||
|
||||
/// 弹出菜单主容器
|
||||
struct NetworkMenuPopup: View {
|
||||
@Binding var isPresented: Bool
|
||||
@State private var isNetworkEnabled = true
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
// 1. 顶部用户信息区 (不响应悬停)
|
||||
HStack(spacing: 12) {
|
||||
Image(systemName: "person.fill")
|
||||
.font(.system(size: 14))
|
||||
.frame(width: 34, height: 34)
|
||||
.background(Color.gray.opacity(0.1))
|
||||
.clipShape(Circle())
|
||||
|
||||
Text("test3")
|
||||
.font(.system(size: 15, weight: .medium))
|
||||
}
|
||||
.padding(.horizontal, 16)
|
||||
.padding(.vertical, 16)
|
||||
|
||||
Divider().opacity(0.3).padding(.horizontal, 16)
|
||||
|
||||
// 2. 菜单功能列表
|
||||
VStack(spacing: 4) {
|
||||
NetworkMenuRow(title: "管理平台")
|
||||
.onTapGesture {
|
||||
print("点击管理平台")
|
||||
}
|
||||
|
||||
NetworkMenuRow(title: "我的网络", subtitle: "test的网络") {
|
||||
Toggle("", isOn: $isNetworkEnabled)
|
||||
.toggleStyle(.switch)
|
||||
.scaleEffect(0.65)
|
||||
.labelsHidden()
|
||||
.tint(Color(red: 0.15, green: 0.2, blue: 0.3))
|
||||
}
|
||||
|
||||
NetworkMenuRow(title: "出口节点", subtitle: "未选择")
|
||||
|
||||
NetworkMenuRow(title: "退出登录", showArrow: false)
|
||||
.onTapGesture {
|
||||
withAnimation(.easeOut(duration: 0.2)) {
|
||||
isPresented = false
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(6) // 为悬停的高亮背景留出呼吸感
|
||||
}
|
||||
.frame(width: 240)
|
||||
.background(
|
||||
RoundedRectangle(cornerRadius: 14)
|
||||
.fill(Color(NSColor.windowBackgroundColor))
|
||||
)
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 14)
|
||||
.stroke(Color.gray.opacity(0.1), lineWidth: 1)
|
||||
)
|
||||
.shadow(color: .black.opacity(0.12), radius: 12, x: 0, y: 6)
|
||||
}
|
||||
}
|
||||
|
||||
/// 菜单行组件 (支持 Hover 效果)
|
||||
struct NetworkMenuRow<RightContent: View>: View {
|
||||
let title: String
|
||||
var subtitle: String? = nil
|
||||
var showArrow: Bool = true
|
||||
var rightContent: RightContent?
|
||||
|
||||
@State private var isHovering = false // 内部维护悬停状态
|
||||
|
||||
init(title: String, subtitle: String? = nil, showArrow: Bool = true) where RightContent == EmptyView {
|
||||
self.init(title: title, subtitle: subtitle, showArrow: showArrow) {
|
||||
EmptyView()
|
||||
}
|
||||
}
|
||||
|
||||
init(title: String, subtitle: String? = nil, showArrow: Bool = true, @ViewBuilder rightContent: () -> RightContent? = { nil }) {
|
||||
self.title = title
|
||||
self.subtitle = subtitle
|
||||
self.showArrow = showArrow
|
||||
self.rightContent = rightContent()
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 0) {
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
Text(title)
|
||||
.font(.system(size: 13.5))
|
||||
.foregroundColor(.primary)
|
||||
if let sub = subtitle {
|
||||
Text(sub)
|
||||
.font(.system(size: 11.5))
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
// 右侧内容
|
||||
if let content = rightContent {
|
||||
content
|
||||
}
|
||||
|
||||
// 右侧箭头
|
||||
if showArrow {
|
||||
Image(systemName: "chevron.right")
|
||||
.font(.system(size: 9, weight: .bold))
|
||||
.foregroundColor(.secondary.opacity(0.4))
|
||||
.padding(.leading, 6)
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, 12)
|
||||
.padding(.vertical, 10)
|
||||
// --- 悬停效果实现 ---
|
||||
.background(
|
||||
RoundedRectangle(cornerRadius: 8)
|
||||
.fill(isHovering ? Color.gray.opacity(0.12) : Color.clear)
|
||||
)
|
||||
.onHover { hovering in
|
||||
withAnimation(.easeInOut(duration: 0.15)) {
|
||||
isHovering = hovering
|
||||
}
|
||||
}
|
||||
// ------------------
|
||||
.contentShape(Rectangle())
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user