因为要开发iOS版本的pakeplus安装包,所以现在需要添加一些实用的功能,比如加载网页可以复制当前网址,可以使用外部safari打开,或者重新加载这样的功能,所以需要模仿实现右上角的功能菜单。实现逻辑就是使用position来控制菜单位置和三角形位置:
实现的代码如下:
import SwiftUI
import WebKitstruct BottomMenuView: View {@State private var selectedTab = 0@State private var isShowingDrawer = false@State private var isShowingMenu = false// Define your URLs hereprivate 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 ButtonHStack {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 URLWebView(url: URL(string: urls[selectedTab])!).edgesIgnoringSafeArea(.top)// Bottom Tab BarHStack(spacing: 0) {ForEach(0 ..< urls.count, id: \.self) { index inButton(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 DrawerSideDrawerView(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 = .infinityvar corners: UIRectCorner = .allCornersfunc 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))}
}