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() }
关键细节说明
- GestureState的优势:使用
@GestureState而非普通@State,是因为它会在手势结束后自动将isPressed重置为初始值,省去手动恢复状态的代码。 - 平滑动画:添加
.animation修饰符,让尺寸变化过渡更自然,提升交互质感。 - 灵活导航:通过
NavigationPath和navigationDestination组合,完全由Button控制跳转时机,比原生NavigationLink更灵活。
如果你偏好更简洁的写法(iOS 15+可用),也可以用Button的.onPress和.onRelease修饰符替代手势:
Button(action: { navigationPath.append("home") }) { // ... 按钮内容 } .onPress { isPressed = true } .onRelease { isPressed = false }
内容的提问来源于stack exchange,提问作者Bartender1382
相关产品推荐
相关产品推荐

