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

SwiftUI如何通过手势实现无模糊的多行文本缩放

SwiftUI 多行文本手势缩放实现问题

核心需求

实现通过捏合手势控制多行文本缩放的功能,需要同时满足两个要求:

  • 缩放交互流畅,和原生scaleEffect()的操作手感一致
  • 缩放后的文本始终清晰,无模糊、像素化问题

已尝试方案与存在的问题

  • 方案1:直接使用scaleEffect()做视图缩放
    缩放过程流畅无跳动,但放大后文本会出现模糊、像素化问题。
  • 方案2:在MagnificationGesture回调中直接修改字体大小
    文本始终保持清晰,但缩放过程中文本会频繁跳动,换行规则随字号动态变化;由于是多行文本,fixedSize()无法解决该布局问题。
  • 方案3:同步缩放字体尺寸与视图缩放比例
    实际运行效果和直接缩放字体完全一致,仍然存在布局跳动的问题。

相关实现代码

直接修改字体大小版本

struct ContentView: View {

    @State var activeTextScale: CGFloat = 1.0
    @State var lastScale: CGFloat = 1.0
    @State var fontSize: CGFloat = 24

    var body: some View {
        ZStack {
            ZStack {
                Text(
                    "Abcdefghijklmnopqrstuvwxyz Abcdefghijklmnopqrstuvwxyz Abcdefghijklmnopqrstuvwxyz"
                )
                .foregroundColor(.yellow)
                // .scaleEffect(activeTextScale)
                .font(.system(size: fontSize * activeTextScale))
                .background(
                    Rectangle()
                        .foregroundColor(.brown.opacity(0.6))
                    // .scaleEffect(activeTextScale)
                )
                .gesture(
                    MagnificationGesture()
                        .onChanged { value in
                            activeTextScale = value + lastScale
                        }
                        .onEnded { value in
                            lastScale = activeTextScale
                        }
                )
            }
        }
    }
}

同步缩放字体与视图版本

该版本运行后仍存在布局跳动问题:

struct ContentView: View {

    @State var activeTextScale: CGFloat = 1.0
    @State var lastScale: CGFloat = 1.0
    @State var fontSize: CGFloat = 24

    func getTextFontSize() -> CGFloat {
        let size = fontSize * activeTextScale
        print(activeTextScale)
        print(size.rounded())
        return size.rounded()
    }

    var body: some View {
        ZStack {
            VStack {
                Text(
                    "Abcdefghijklmnopqrstuvwxyz Abcdefghijklmnopqrstuvwxyz Abcdefghijklmnopqrstuvwxyz"
                )
                .foregroundColor(.yellow)
                .font(.system(size: getTextFontSize()))
                .background(
                    Rectangle()
                        .foregroundColor(.brown.opacity(0.6))
                )

            }
            .scaleEffect(activeTextScale)
            .gesture(
                MagnificationGesture()
                    .onChanged { value in
                        activeTextScale = value + lastScale
                    }
                    .onEnded { value in
                        lastScale = activeTextScale
                    }
            )
        }
    }
}

效果参考


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 16:03:31