SwiftUI极简教程24:构建一个Banner图片轮播(上)

简介: SwiftUI极简教程24:构建一个Banner图片轮播(上)

在本章中,你将学会如何构建一个Banner轮播图。

在很多App首页中,我们可以看到在主要视图的顶部位置,常常有一个Banner轮播图的存在,它通过左右滑动图片的形式,展示给用户查看推荐的信息。

在本章中,我们就来实现下如何使用SwiftUI构建一个Banner轮播图。


image.png

那么,让我们开始吧。

首先,创建一个新项目,命名为SwiftUIBanner

image.png

首先,我们先创建基本的卡片视图CardView。我们可以看到它由一张Image图片卡片和Text文字组成,我们先在Assets.xcassets中导入一批图片作为素材使用。

image.png

然后,我们完成下展示一张Image图片卡片,并在ContentView主视图中预览它。


struct CardView: View {
    var body: some View {
        ZStack {
            GeometryReader { geometry in
                Image("image01")
                    .resizable()
                    .scaledToFill()
                    .frame(width: geometry.size.width, height: geometry.size.height)
                    .cornerRadius(15)
                    .overlay(
                        Text("图片01")
                            .font(.system(.headline, design: .rounded))
                            .fontWeight(.heavy)
                            .padding(10)
                            .background(Color.white)
                            .padding([.bottom, .leading])
                            .opacity(1.0)
                            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .bottomLeading)
                    )
            }
        }
    }
}


image.png


这里科普一个知识点。

我们发现代码和以前学习的不同,我们新增了GeometryReader几何容器,将我们的Image图片和Text文字包裹在里面。而且图片的大小.frame修饰符中,设置的Image图片尺寸是我们GeometryReader几何容器宽高。

GeometryReader几何容器简单来说,就是一个View,但不同的是,它的宽高是通过自动判断你的设备的屏幕尺寸的定的。这样,假设我们有一张4000*4000分辨率的图片的时候,我们就不用再设置它在屏幕中展示的固定大小了,屏幕多少,里面的图片就可以自动设置多大。


//GeometryReader使用方法
GeometryReader { geometry in 
    //代码块
}


我们将CardView卡片视图需要展示的内容的变量抽离出来,它是Image图片和Text文字内的内容,用于之后遍历数组模型使用。


let image: String
let imageName: String


下一步,我们定义好我们的Model部分的内容,我们新建一个Swift文件,命名为ImageModel.swift


和之前的章节内容一样,我们定义好包含可被识别的参数的imageModel,当然还有演示的数据数组imageModels


import Foundation
struct imageModel: Identifiable {
    var id = UUID()
    var image: String
    var imageName: String
}
#if DEBUG
let imageModels = [
    imageModel(image: "image01", imageName: "图片01"),
    imageModel(image: "image02", imageName: "图片02"),
    imageModel(image: "image03", imageName: "图片03"),
    imageModel(image: "image04", imageName: "图片04"),
    imageModel(image: "image05", imageName: "图片05"),
    imageModel(image: "image06", imageName: "图片06"),
    imageModel(image: "image07", imageName: "图片07"),
    imageModel(image: "image08", imageName: "图片08"),
    imageModel(image: "image09", imageName: "图片09")
]
#endif


image.png

还记得之前的章节么?我们使用ForEach循环遍历我们定义好的数组内容。

我们这里也尝试下在ContentView主页中显示所有CardView卡片视图的内容。


struct ContentView: View {
    var body: some View {
        GeometryReader { outerView in
            ScrollView(.horizontal, showsIndicators: false) {
                HStack(alignment: .center) {
                    ForEach(imageModels.indices,id:\.self) { index in
                        GeometryReader { innerView in
                            CardView(image: imageModels[index].image, imageName:imageModels[index].imageName)
                        }
                    }
                    .padding(.horizontal, 20)
                    .frame(width: outerView.size.width, height: outerView.size.height)
                }
            }
            .frame(width: outerView.size.width, height: outerView.size.height, alignment: .leading)
        }
    }
}


image.png

这里科普一个知识点。

和之前引用数据数据不同,Xcode 13.3 RC 版本更新了一个内容,我们使用ForEach循环时,由于View是动态生成的,所以id需要指定为id:\.self


ForEach(imageModels.indices,id:\.self) { index in
    //代码块
}


不然Xcode报错


Non-constant range: argument must be an integer literal


这样改动后不仅不会有警告,而且动态创建的View将会通过id来作为唯一标识,需要动态增加和变化的话,不会重复进行创建。

好,我们看回代码本身的内容。

我们在GeometryReader几何容器中使用ScrollViewHStack创建了一个可以左右滑动的视图,然后通过ForEach循环遍历imageModels数组数据,创建了一个个CardView卡片视图。为了更好地根据屏幕大小控制CardView卡片视图大小,我们使用GeometryReader容器的outerView外部视图获取设备屏幕的大小,和innerView内部视图环绕卡片视图来控制其大小。

我们在模拟器中预览下效果。


image.png

这里我们发现一个问题,虽然我们实现了Banner图片轮播的左右滑动,但是滚动视图可以在任何位置停下,这个Banner图片轮播的设计初衷。


那么我们怎样才能让每一个CardView卡片视图能够左右滑动,而且能每次到达一个CardView卡片视图的分页边界时刚好停下来呢?


我们会在后面的章节一一实现。

快来动手试试吧!



相关文章
|
8月前
|
JavaScript 前端开发
仿百度排列图片预览插件-Simple Lightbox
仿百度排列图片预览插件-Simple Lightbox
34 0
|
12月前
|
移动开发 前端开发 JavaScript
leaflet使用domtoimage插件与h5 canvas实现截图功能并下载
leaflet使用domtoimage插件与h5 canvas实现截图功能并下载
|
Web App开发 JavaScript
Chrome操作指南——入门篇(十四)drawer
Chrome操作指南——入门篇(十四)drawer
Chrome操作指南——入门篇(十四)drawer
|
容器
react-Ant Design框架项目中文字轮播与图片轮播的实现
在react-Ant Design框架项目中实现文字轮播和图片轮播,在这里记录一下,实现过程有一点小坑需要注意
535 0
react-Ant Design框架项目中文字轮播与图片轮播的实现
|
索引
SwiftUI极简教程26:构建一个Banner图片轮播(下)
SwiftUI极简教程26:构建一个Banner图片轮播(下)
584 0
SwiftUI极简教程26:构建一个Banner图片轮播(下)
|
Swift iOS开发
SwiftUI极简教程01:搭建一个新项目&Text文字的使用
SwiftUI极简教程01:搭建一个新项目&Text文字的使用
545 1
SwiftUI极简教程01:搭建一个新项目&Text文字的使用
|
存储 索引
SwiftUI极简教程42:使用MatchedGeometryEffect构建一个导航菜单
在本章中,你将学会使用MatchedGeometryEffect构建一个导航菜单。 在构建SwiftUI应用过程中,我们常常会使用TabView构建底部菜单,但更多的时候会由于我们定制化的需求,需要我们自己绘制底部菜单。 那么本章中,我们就来试试构建一个底部导航菜单。
390 0
SwiftUI极简教程42:使用MatchedGeometryEffect构建一个导航菜单
|
索引
SwiftUI极简教程25:构建一个Banner图片轮播(中)
SwiftUI极简教程25:构建一个Banner图片轮播(中)
349 0
SwiftUI极简教程25:构建一个Banner图片轮播(中)
|
XML JSON 自然语言处理
SAP UI5 初学者教程之十二 - 使用 CSS 类对 UI 进行进一步美化试读版
SAP UI5 初学者教程之十二 - 使用 CSS 类对 UI 进行进一步美化试读版
106 0
SAP UI5 初学者教程之十二 - 使用 CSS 类对 UI 进行进一步美化试读版
|
JavaScript 前端开发 Java
CodeMirror 代码渲染神器的极简入门实例
效果: image.png HTML: 保存 运行 JS 代码示例: // 渲染代码: var editor = CodeMirror.
2599 0