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 开发之路提供一些有用的启发和帮助!

相关推荐
yngsqq11 分钟前
037集——JoinEntities连接多段线polyline和圆弧arc(CAD—C#二次开发入门)
开发语言·c#·swift
麦田里的守望者江27 分钟前
KMP 中的 expect 和 actual 声明
android·ios·kotlin
_黎明2 小时前
【Swift】字符串和字符
开发语言·ios·swift
ZVAyIVqt0UFji4 小时前
iOS屏幕共享技术实践
macos·ios·objective-c·cocoa
hfxns_5 小时前
iOS 18.2 Beta 4开发者预览版发布,相机新增辅助功能
ios
AirDroid_cn15 小时前
如何控制自己玩手机的时间?两台苹果手机帮助自律
ios·智能手机·ipad·手机使用技巧·苹果手机使用技巧
郝晨妤17 小时前
鸿蒙原生应用开发元服务 元服务是什么?和App的关系?(保姆级步骤)
android·ios·华为od·华为·华为云·harmonyos·鸿蒙
tealcwu19 小时前
【Unity踩坑】在Mac上安装Cocoapods失败
unity·ios·游戏引擎
名字不要太长 像我这样就好20 小时前
【iOS】iOS的轻量级数据库——FMDB
数据库·ios·sqlite·objective-c
@解忧杂货铺20 小时前
Android和IOS的区别
android·ios·cocoa