• 如何使用ViewThatFits组件实现APP在不同设备屏幕的完美适配
  • 发布于 1个月前
  • 107 热度
    1 评论
前言
最近在开发过程中,我频繁遇到了不同设备屏幕适配的问题,相信这也是很多 iOS 开发者的日常痛点。幸运的是,从 iOS 16 开始,苹果给我们带来了一个堪称"救星"的工具——ViewThatFits。这个小东西看似简单,实则威力巨大,它能让我们的 UI 组件像变色龙一样,根据可用空间智能调整自己的样子。今天就带大家深入探索这个实用的 SwiftUI 组件,看看它如何化解我们的适配难题。

ViewThatFits 是什么?
简单来说,ViewThatFits 就是 SwiftUI 在 iOS 16 中推出的一个"聪明的容器",它的核心能力是:根据可用空间自动挑选最合适的视图来展示。它的工作方式就像一场"试衣服"的过程——你先准备几套尺寸从大到小的"衣服"(视图),然后 ViewThatFits 会从第一件开始试,直到找到第一件"穿得下"(能装得下)的"衣服"来展示。这种机制特别适合那些容器大小不确定,需要视图能随机应变的场景。

基本使用方法
ViewThatFits 的使用超级简单,几行代码就能搞定:
ViewThatFits(in: .vertical) {
    // 首选方案(最完整的内容)
    VStack {
        Image(systemName: "swift")
            .imageScale(.large)
            .foregroundStyle(.tint)
        
        Text("我们迫不及待想看到你用 Swift 创造的作品")
    }
    .font(.system(size: 45))
    .fontWeight(.ultraLight)
    .frame(width: 350, height: 350)
    
    // 备选方案一
    Text("用 Swift 创造")
        .font(.system(size: 45))
        .fontWeight(.ultraLight)
    // 堆代码 duidaima.com
    // 备选方案二
    Text("Swift")
        .font(.system(size: 40))
        .fontWeight(.ultraLight)
    
    // 备选方案三(最精简的内容)
    Image(systemName: "swift")
        .foregroundStyle(.tint)
        .font(.system(size: 40))
}

使用 ViewThatFits 主要需要关注两点:
in 参数:指定你想要适配的方向。默认情况下它会考虑水平和垂直两个方向,但你也可以指定只考虑垂直方向(.vertical)或水平方向(.horizontal)。
content:在这里你可以按照"从奢到简"的顺序排列各种备选视图,ViewThatFits 会尽可能使用排在前面的视图,实在放不下才会考虑后面的选项。

实战案例
来看一个真实案例,感受下 ViewThatFits 到底有多好用:
import SwiftUI

struct ContentView: View {
    
    @Stateprivatevar frameSize: CGFloat = 350
    @Stateprivatevar isEditing = false
    
    var body: some View {
        VStack {
            Spacer()
            VStack {
                ViewThatFits(in: .vertical) {
                    // 豪华全餐
                    VStack {
                        Image(systemName: "swift")
                            .imageScale(.large)
                            .foregroundStyle(.tint)
                        
                        Text("我们迫不及待想看到你用 Swift 创造的作品")
                    }
                    .font(.system(size: 45))
                    
                    // 经济套餐
                    Text("用 Swift 创造")
                        .font(.system(size: 45))
                    
                    // 简易套餐
                    Text("Swift")
                    
                    // 应急口粮
                    Image(systemName: "swift")
                        .foregroundStyle(.tint)
                }
            }
            .fontWeight(.ultraLight)
            .font(.system(size: 40))
            .frame(width: frameSize, height: frameSize)
            
            .overlay {
                RoundedRectangle(cornerSize: CGSize(width: 12, height: 12))
                    .stroke(Color.blue, lineWidth: 1)
            }
            Spacer()
            Slider(value: $frameSize, in: 60...350) { isEditing in
                self.isEditing = isEditing
            }
            Text("框架大小: \(Int(frameSize))")
        }
        .padding()
    }
}
这个例子中,我做了一个可以用滑块调整大小的容器。当你拖动滑块改变容器尺寸时,神奇的一幕发生了:
.容器够大时,显示完整的图标和文字(豪华全餐)
.空间变小,自动降级为只显示"用 Swift 创造"(经济套餐)
.再小点,就只剩下"Swift"文字(简易套餐)
.如果空间极度有限,最终只显示一个 Swift 图标(应急口粮)
整个过程完全自动,不需要你写一行额外的判断代码!
看看这炸裂的效果:

ViewThatFits 的绝佳应用场景
从我的实战经验来看,ViewThatFits 在这些场景下简直是救命神器:
多设备适配:告别为 iPhone、iPad 写不同布局的日子
动态内容处理:遇到长短不一的用户输入内容也不怕
省去复杂判断:再也不用写一堆 if-else 来判断屏幕尺寸

优雅降级显示:内容可以根据可用空间自动"精简版"→"超精简版"


总结
说实话,ViewThatFits 是我最近发现的 SwiftUI "宝藏组件"之一。它用最简单的方式解决了困扰开发者已久的布局适配问题。不用再写复杂的条件判断,不用再担心不同设备的显示效果,ViewThatFits 一招搞定。如果你的应用需要适配从 iPhone mini 到 iPad Pro 的各种屏幕,或者有些视图的容器大小会动态变化,强烈建议你试试这个组件。相信你会和我一样,爱上这种"一劳永逸"的开发体验。

最后说一句,SwiftUI 的这些小惊喜,正是让我们这些开发者沉迷其中的原因,不是吗?
用户评论