You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中如何让Text具备Button的外观及按压交互效果?

解决方法

要实现带按压缩放效果的Button式导航,你可以通过以下步骤调整代码:

核心思路

  • 用Button替代NavigationLink,配合NavigationStack的navigationDestination处理页面跳转
  • 使用GestureState或@State跟踪按压状态(前者会在按压结束后自动重置,无需手动恢复)
  • 根据按压状态动态调整按钮尺寸,实现按压反馈

修改后的完整代码

import SwiftUI

struct MainMenuWithStack: View {
    // 用GestureState跟踪按压状态,按压结束自动恢复为false
    @GestureState private var isPressed = false
    // 导航路径,控制页面跳转逻辑
    @State private var navigationPath = NavigationPath()
    
    // 按钮基础尺寸
    private let baseWidth: CGFloat = 150
    private let baseHeight: CGFloat = 75
    // 按压时的缩放比例
    private let pressScale: CGFloat = 0.9
    
    var body: some View {
        NavigationStack(path: $navigationPath) {
            VStack(spacing: 5) {
                Button(action: {
                    // 点击时触发页面跳转
                    navigationPath.append("home")
                }) {
                    Text("Home")
                        .foregroundStyle(.white)
                        .font(.title)
                        .frame(
                            width: isPressed ? baseWidth * pressScale : baseWidth,
                            height: isPressed ? baseHeight * pressScale : baseHeight
                        )
                        .background(.blue)
                        .cornerRadius(10)
                        .animation(.easeInOut(duration: 0.1), value: isPressed)
                }
                // 添加按压手势,实时更新按压状态
                .gesture(
                    LongPressGesture(minimumDuration: .infinity)
                        .updating($isPressed) { currentState, gestureState, _ in
                            gestureState = currentState
                        }
                )
            }
        }
        // 配置导航目标页面
        .navigationDestination(for: String.self) { destination in
            if destination == "home" {
                HomePage()
            }
        }
    }
}

// 示例目标页面
struct HomePage: View {
    var body: some View {
        Text("Home Page")
            .font(.largeTitle)
    }
}

#Preview {
    MainMenuWithStack()
}

关键细节说明

  1. GestureState的优势:使用@GestureState而非普通@State,是因为它会在手势结束后自动将isPressed重置为初始值,省去手动恢复状态的代码。
  2. 平滑动画:添加.animation修饰符,让尺寸变化过渡更自然,提升交互质感。
  3. 灵活导航:通过NavigationPath和navigationDestination组合,完全由Button控制跳转时机,比原生NavigationLink更灵活。

如果你偏好更简洁的写法(iOS 15+可用),也可以用Button的.onPress和.onRelease修饰符替代手势:

Button(action: {
    navigationPath.append("home")
}) {
    // ... 按钮内容
}
.onPress {
    isPressed = true
}
.onRelease {
    isPressed = false
}

内容的提问来源于stack exchange,提问作者Bartender1382

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 00:42:38