SwiftUI(五)- ForEach循环创建视图&尺寸类&安全区域

引言

SwiftUI为开发者提供了丰富的工具,用于构建灵活而动态的界面布局。在本篇博客中,我们将重点讨论三个核心功能:ForEach的循环视图创建、尺寸类的动态适配,以及安全区域的布局控制。通过ForEach,可以轻松地为数据集合生成视图,适配不同屏幕的尺寸类则允许我们更灵活地调整布局。本篇博客将为大家展开这词儿功能在实际开发中的具体应用,助力SwiftUI项目更加流畅和高效。

ForEach循环创建视图

在实际开发场景中我们经常会需要使用一个循环来创建视图,在SwiftUI中,这个可以通过ForEach来实现。

需要注意的是ForEach虽然看起来和Swift的forEach()方法同名,但是在SwiftUI中ForEach表示的是一个独立的视图结构。我们甚至可以直接从视图中返回它。而在使用时,我们需要为它提供一个数组,并且明确的告诉SwiftUI如何唯一地识别每一个条目,以便让它知道如何更新它们。另外我们需要再闭包中来为每个循环创建一个视图。

循环简单类型数组

对于简单的的范围循环,我们直接将范围传递给ForEach。比如从10倒数到1,然后在最后添加一个文案,实现如下:

Swift 复制代码
        VStack(alignment: .leading) {
            // 循环10-1
            ForEach((1...10).reversed(), id: \.self) {
                Text("\($0)")
            }

            Text("Hello, world!").padding()
        }

对于简单类型的数组,比如整数、字符串、颜色等等,我们都可以通过这种方式遍历(id:\.self),让SwiftUI使用这些值本身作为标识符。

下面我们使用ForEach来循环遍历一个包含3个颜色的数组,并使用每种颜色的名称和颜色来创建文本视图:

Swift 复制代码
            // 循环颜色
            let colors: [Color] = [.red, .green, .blue]
            ForEach(colors, id: \.self) { color in
                Text(color.description.capitalized)
                    .padding()
                    .background(color)
            }

循环自定义类型数组

如果数组中有自定义类型,那么我们就需要主动指定我们自定义类型的中能够唯一标识它的属性,比如有这么一个自定义结构体:

Swift 复制代码
struct Cat {
    
    init(id: UUID = UUID(), name: String) {
        self.id = id
        self.name = name
    }
    /// 标识
    var id = UUID()
    /// 名称
    var name: String = ""
}

该结构体具有一个UUID类型的属性id,那么这就意味着它就是唯一的,非常适合作为标识。如果我们想要循环遍历这样的一个数字,创建一个文本视图显示每个小猫咪的名称放在VStack中,那么我们可以这样来实现:

Swift 复制代码
        // 自定义对象数组
        let cats = [
            Cat(name: "Kitty"),
            Cat(name: "Tom"),
            Cat(name: "Jerry")
        ]
        VStack(alignment: .leading) {
            ForEach(cats, id: \.id) { cat in
                Text(cat.name)
            }
        }

这会告诉SwiftUI可以通过查看每个视图的id属性来区分ForEach内部的视图。

如果我们让Cat结构体遵循Identifiable协议,那我们可以直接使用ForEach。遵循这个协议之后意味着需要添加一个唯一标识每个对象的id属性。但我们已经为它创建了该属性。

Swift 复制代码
struct Cat:Identifiable {
    
    init(id: UUID = UUID(), name: String) {
        self.id = id
        self.name = name
    }
    /// 标识
    var id = UUID()
    /// 名称
    var name: String = ""
}
Swift 复制代码
        // 自定义对象数组
        let cats = [
            Cat(name: "Kitty"),
            Cat(name: "Tom"),
            Cat(name: "Jerry")
        ]
        VStack(alignment: .leading) {
            
            ForEach(cats) { cat in
                Text(cat.name)
            }
        }

尺寸类

SwiftUI提供了对尺寸类别的支持,可以帮助我们根据设备的屏幕尺寸动态调整布局。这是通过读取环境中的尺寸类信息来实现的。在SwiftUI中,尺寸类可以被读取为.horizontalSizeClass和.verticalSizeClass,它们可以用来判断当前视图的宽度或者是高度是紧凑型(compact)还是常规型(regular)。

要使用尺寸类信息,首选需要定义一个@Environment属性,SwiftUI会自动从环境中读取该信息并赋值给它,代码如下:

Swift 复制代码
import SwiftUI

struct ContentView: View {
    // 从环境中读取尺寸类
    @Environment(\.horizontalSizeClass) var horizontalSizeClass
    @Environment(\.verticalSizeClass) var verticalSizeClass

    var body: some View {
        if horizontalSizeClass == .compact {
            Text("紧凑型横向尺寸")
        } else {
            Text("常规型横向尺寸")
        }
    }
}

尺寸类的检测在视频不同屏幕比如iPhone和iPad或者不同设备方向比如横向和竖屏时非常有用。

安全区域

默认情况下,SwiftUI的视图大多会保持在安全区域内,它会延伸到屏幕底部,但不会靠近设备底部的刘海。

如果我们想要实现真正的全屏,那就意味着视图会有一部分内容被刘海或者是灵动岛遮盖起来,那么我们可以使用edgeslgnoringSafeArea()修饰符。

例如我们创建一个红色的文本视图,并要求填满所有可用的空间,然后设置它忽略任何安全区域。

Swift 复制代码
        Text("Hello World")
            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
            .background(Color.red)
            .edgesIgnoringSafeArea(.all)

结语

在 SwiftUI 中,ForEach 循环、尺寸类适配和安全区域设置为我们提供了更高效的开发方式,使得界面布局的实现变得简单直观。ForEach 的循环视图创建提升了数据驱动视图的构建效率,尺寸类适配帮助我们针对不同屏幕动态调整布局,而安全区域的灵活设置则确保了内容在各设备上的正确展示。掌握这些功能不仅能让我们的代码更简洁,还能增强应用的用户体验。希望这篇文章的讲解能够为你的 SwiftUI 开发之路提供一些有用的启发和帮助!

相关推荐
2501_915918411 小时前
uni-app 项目 iOS 上架踩坑经验总结 从证书到审核的避坑指南
android·ios·小程序·https·uni-app·iphone·webview
游戏开发爱好者81 小时前
iOS 上架 uni-app 流程全解析,从打包到发布的完整实践
android·ios·小程序·https·uni-app·iphone·webview
他们都不看好你,偏偏你最不争气9 小时前
AutoLayout与Masonry:简化iOS布局
ios
2501_9160088912 小时前
iOS 抓包工具有哪些?全面盘点主流工具与功能对比分析
android·ios·小程序·https·uni-app·iphone·webview
2501_9159214312 小时前
iOS混淆工具实战 视频流媒体类 App 的版权与播放安全保护
android·ios·小程序·https·uni-app·iphone·webview
2501_9160088916 小时前
uni-app iOS 日志与崩溃分析全流程 多工具协作的实战指南
android·ios·小程序·https·uni-app·iphone·webview
2501_9159214317 小时前
iOS混淆工具实战 在线教育直播类 App 的课程与互动安全防护
android·安全·ios·小程序·uni-app·iphone·webview
Digitally19 小时前
没 iCloud, 如何数据从iPhone转移到iPhone
ios·iphone·icloud
笑尘pyrotechnic19 小时前
push pop 和 present dismiss
macos·ui·ios·objective-c·cocoa
Digitally20 小时前
如何将联系人从 iPhone 转移到 Redmi 手机
ios·智能手机·iphone