王國慶 发表于 2025-4-12 15:15:15

在swiftui中利用实现类似微信右上角的功能菜单

https://i-blog.csdnimg.cn/direct/9d5ed10791b34a71b7bbcc5a3d3d286f.png
因为要开发iOS版本的pakeplus安装包,以是现在需要添加一些实用的功能,好比加载网页可以复制当前网址,可以利用外部safari打开,或者重新加载这样的功能,以是需要模拟实现右上角的功能菜单。实现逻辑就是利用position来控制菜单元置和三角形位置:
https://i-blog.csdnimg.cn/direct/0ea4420fc630473dbf65847b9bfa5d02.png
实现的代码如下:
import SwiftUI
import WebKit

struct BottomMenuView: View {
    @State private var selectedTab = 0
    @State private var isShowingDrawer = false
    @State private var isShowingMenu = false
   
    // Define your URLs here
    private let urls = [
      "https://www.baidu.com/",
      "https://juejin.cn/",
      "https://chat.deepseek.com/"
    ]
   
    var body: some View {
      ZStack {
            VStack(spacing: 0) {
                // Top Bar with Menu Button
                HStack {
                  Button(action: {
                        isShowingDrawer = true
                  }) {
                        Image(systemName: "line.3.horizontal")
                            .font(.title2)
                            .foregroundColor(.primary)
                  }
                  
                  Spacer()
                  
                  Text("PakePlus")
                  
                  Spacer()
                  
                  // 自定义菜单按钮
                  Button(action: {
                        isShowingMenu.toggle()
                  }) {
                        Image(systemName: "plus.circle")
                            .font(.title2)
                            .foregroundColor(.primary)
                  }
                }
                .background(Color(.systemBackground))
                .padding(.horizontal)
                .padding(.vertical, 6)
               
                // WebView for the selected URL
                WebView(url: URL(string: urls)!)
                  .edgesIgnoringSafeArea(.top)
               
                // Bottom Tab Bar
                HStack(spacing: 0) {
                  ForEach(0 ..< urls.count, id: \.self) { index in
                        Button(action: {
                            selectedTab = index
                        }) {
                            VStack {
                              Image(systemName: tabIcon(for: index))
                                    .font(.system(size: 20))
                              Text(tabTitle(for: index))
                                    .font(.caption)
                            }
                            .foregroundColor(selectedTab == index ? .blue : .gray)
                            .frame(maxWidth: .infinity)
                            .padding(.vertical, 8)
                        }
                  }
                }
                .background(Color(.systemBackground))
                .overlay(
                  Rectangle()
                        .frame(height: 0.5)
                        .foregroundColor(Color(.systemGray4)),
                  alignment: .top
                )
            }
            
            // 自定义菜单
            if isShowingMenu {
                Image(systemName: "arrowtriangle.up.fill")
                  .resizable()
                  .frame(width: 30, height: 30)
                  .position(x: UIScreen.main.bounds.width - 30, y: 50)
                  .foregroundStyle(Color(.systemGray6))
                VStack(alignment: .trailing, spacing: 0) {
                  Button(action: {
                        // 复制网址动作
                        isShowingMenu = false
                  }) {
                        Text("复制网址")
                            .padding(.horizontal, 16)
                            .padding(.vertical, 8)
                            .frame(width: 100)
                  }
                  .background(Color(.systemGray6))
                  .cornerRadius(8, corners: [.topLeft, .topRight])
                  
                  Button(action: {
                        // 外部打开动作
                        isShowingMenu = false
                  }) {
                        Text("外部打开")
                            .padding(.horizontal, 16)
                            .padding(.vertical, 8)
                            .frame(width: 100)
                  }
                  .background(Color(.systemGray6))
                  
                  Button(action: {
                        // 重新加载动作
                        isShowingMenu = false
                  }) {
                        Text("重新加载")
                            .padding(.horizontal, 16)
                            .padding(.vertical, 8)
                            .frame(width: 100)
                  }
                  .background(Color(.systemGray6))
                  .cornerRadius(8, corners: [.bottomLeft, .bottomRight])
                }
                .position(x: UIScreen.main.bounds.width - 60, y: 100)
                .transition(.opacity)
                .background(Color.white.opacity(0.0001))
            }
            
            // Side Drawer
            SideDrawerView(isShowing: $isShowingDrawer)
      }
      .onTapGesture {
            if isShowingMenu {
                isShowingMenu = false
            }
      }
    }
   
    private func tabIcon(for index: Int) -> String {
      switch index {
      case 0:
            return "house.fill"
      case 1:
            return "star.fill"
      case 2:
            return "play.fill"
      default:
            return "circle.fill"
      }
    }
   
    private func tabTitle(for index: Int) -> String {
      switch index {
      case 0:
            return "Home"
      case 1:
            return "Favorites"
      case 2:
            return "Videos"
      default:
            return "Tab"
      }
    }
}

#Preview {
    BottomMenuView()
}

// Add RoundedCorner extension
struct RoundedCorner: Shape {
    var radius: CGFloat = .infinity
    var corners: UIRectCorner = .allCorners

    func path(in rect: CGRect) -> Path {
      let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners,
                              cornerRadii: CGSize(width: radius, height: radius))
      return Path(path.cgPath)
    }
}

extension View {
    func cornerRadius(_ radius: CGFloat, corners: UIRectCorner) -> some View {
      clipShape(RoundedCorner(radius: radius, corners: corners))
    }
}
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 在swiftui中利用实现类似微信右上角的功能菜单