项目布景

和往常相同的下午,午后的阳光洒在身上,感觉有些舒畅。突然脑海里闪过一个念头,小步快跑,动身,双手举起,目视前方,挥手投篮,唰………最近一款APP简直引起了一切男孩子的兴趣,这便是空气投篮。

想起年少时和一群朋友走在路上,男孩子们都或多或少做过这种“傻傻的”动作,那是芳华的味道。

而竟然有家公司将它做了出来,一时间立刻下载、装置…….额…….这…….需求AppleWatch才能用。好吧,竟然没有办法体会空气投篮,不如就用用自己的特长,画画iOS端的页面吧。

项目建立

首要打开Xcode,创立一个新的SwiftUI项目,命名为AirBall,如下图所示:

实战编程刻在男人DNA里的浪漫,空气投篮(一)

空气投篮分为iOS端和Watch,本章咱们先来完结iOS的相关页面。iOS端页面操作及其流程如下图所示:

实战编程刻在男人DNA里的浪漫,空气投篮(一)

实战编程

预备游戏视图

首要是预备游戏视图,简略剖析可知,它由文字Text和图片Image组成,布景色彩填充为黑色。Image图片部分,需求导入一张SVG适量图片,使得其很好地与布景融合。如下图所示:

实战编程刻在男人DNA里的浪漫,空气投篮(一)

导入完结后,咱们来构建页面部分。在ContentView文件中,咱们键入以下代码:

// 预备游戏
func prepareView() -> some View {
	VStack(alignment: .center, spacing: 80) {
		Spacer()
		Text("请确认你已启用Apple Watch上的空气投篮App")
		.font(.system(size: 17))
		.foregroundColor(.white)
		.lineLimit(2)
		.lineSpacing(15)
		.multilineTextAlignment(.center)
		Image("watch_application")
		.resizable()
		.aspectRatio(contentMode: .fit)
		Spacer()
		Spacer()
	}.frame(maxWidth: Constants.screenWidth / 2)
}

上述代码中,咱们创立了一个新的View视图prepareView预备开端游戏视图。

在prepareView视图中,文字Text和Image图片运用VStack笔直布局容器包裹,并设置其对齐方法为居中对齐,容器内容元素距离为80。

Text文字部分的处理为设置font字体为17号字,设置foregroundColor填充色为白色,因为文字过长或许导致页面无法展现的原因,这儿设置lineLimit文字显现行数为2行,并设置换行时multilineTextAlignment文字对齐方法为居中对齐。

Image图片部分,设置resizable图片缩放,并设置aspectRatio保持原本的宽高比防止变形。

最后运用frame设置VStack笔直布局容器的宽度,为屏幕宽度的一半。为了增强用户体会,在VStack笔直布局容器中运用Spacer占位符,下方设置2个,上方设置一个,这个视觉元素就会展现在屏幕上部分2/3的方位,又是一个小技巧。

完结后,咱们在Body中展现,如下代码所示:

ZStack {
	Color(.black).edgesIgnoringSafeArea(.all)
	prepareView()
}

实战编程刻在男人DNA里的浪漫,空气投篮(一)

上述代码中,咱们运用ZStack叠加视图,将prepareView预备游戏视图和Color色彩叠加,色彩部分运用edgesIgnoringSafeArea疏忽全部安全区域,便可让黑色布景铺满整个屏幕。

游戏列表视图

打开App,进入预备游戏视图,此时需求与Watch端联动,在Watch端确认后,iOS端将进入至游戏列表页面。

实战编程刻在男人DNA里的浪漫,空气投篮(一)

游戏列表页面的交互逻辑是,点击游戏卡片则进入到游戏中,在游戏列表页左右滑动可切换游戏。

咱们先来完结单张游戏卡片的规划。剖析得知,单张游戏卡片的内容包含3块内容:游戏项目、游戏阐明、游戏封面。

咱们创立一个新的视图,代码如下所示:

// MARK: 游戏项
struct gameRowView: View {
    var gameName: String
    var gameHelpText: String
    var gameImage: String
    var body: some View {
        VStack(alignment: .center, spacing: 60) {
            Text(gameName)
                .font(.system(size: 48))
                .bold()
                .foregroundColor(.white)
            VStack(alignment: .center, spacing: 10) {
                Text(gameHelpText)
                    .font(.system(size: 17))
                    .foregroundColor(.white)
                Image(gameImage)
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(maxHeight:UIScreen.main.bounds.size.width - 20)
            }
        }
    }
}

上述代码中,咱们创立了一个新的结构体gameRowView游戏项视图。

之所以创立一个新的结构体,而没有和上面prepareView预备游戏视图相同直接界说View视图,是因为咱们需求将gameRowView游戏项视图作为“母版”,然后依照单个gameRowView游戏项视图构建多个相同款式的游戏卡片。

在gameRowView游戏项视图中,咱们声明晰3个String类型的变量:gameName游戏称号、gameHelpText游戏阐明、gameImage游戏封面。

然后在其Body中创立款式,因为游戏称号的Text和其余两块在页面上还是有些距离,这儿运用了2个VStack笔直布局容器,将游戏阐明和游戏封面放在一个容器中,它们直接的距离为10,而再用一个VStack笔直布局容器再把游戏标题包裹在一起,距离为60。

这儿额定再补充一个知识点。

便是游戏封面运用frame设置其巨细的问题,因为咱们导入的游戏封面图片或许存在巨细不一致的问题,因而如果需求让这个游戏卡片看起来元素方位保持一致,因为运用了VStack笔直布局容器,因而,可以设置图片maxHeight高度为屏幕width宽度,再减去20留点边距。

这样做,无论图片尺寸是多少,每个游戏卡片展现的游戏称号、游戏阐明、游戏封面的方位就保持一致了。

咱们导入两张SVG格局的游戏图片作为资料运用,如下图所示:

实战编程刻在男人DNA里的浪漫,空气投篮(一)

游戏卡片是左右滑动切换的交互,这时咱们就可以在ContentView视图中再创立一个View视图构建它,如下代码所示:

// 游戏列表
func gameListView() -> some View {
	TabView {
			gameRowView(gameName: "投篮", gameHelpText: "手举球开端游戏", gameImage: "basketball")
			gameRowView(gameName: "打棒球", gameHelpText: "双手挥动开端游戏", gameImage: "baseball")
		}
	.tabViewStyle(PageTabViewStyle())
}

实战编程刻在男人DNA里的浪漫,空气投篮(一)

实战编程刻在男人DNA里的浪漫,空气投篮(一)

上述代码中,咱们创立了一个游戏列表视图gameListView。

然后运用TabView翻滚视图容器包裹了2个gameRowView游戏项视图,游戏项视图中咱们给声明的变量赋值以显现内容。最后设置TabView翻滚视图的款式,为PageTabViewStyle分页翻滚类型,如此便完结了横向切换游戏卡片的交互。

本章代码

为方便学习,本章完整代码如下所示:

import SwiftUI
struct ContentView: View {
    var body: some View {
        ZStack {
            Color(.black).edgesIgnoringSafeArea(.all)
            gameListView()
        }
    }
    // 预备游戏
    func prepareView() -> some View {
        VStack(alignment: .center, spacing: 80) {
            Spacer()
            Text("请确认你已启用Apple Watch上的空气投篮App")
                .font(.system(size: 17))
                .foregroundColor(.white)
                .lineLimit(2)
                .lineSpacing(15)
                .multilineTextAlignment(.center)
            Image("watch_application")
                .resizable()
                .aspectRatio(contentMode: .fit)
            Spacer()
            Spacer()
        }.frame(maxWidth: UIScreen.main.bounds.size.width / 2)
    }
    // 游戏列表
    func gameListView() -> some View {
        TabView {
            gameRowView(gameName: "投篮", gameHelpText: "手举球开端游戏", gameImage: "basketball")
            gameRowView(gameName: "打棒球", gameHelpText: "双手挥动开端游戏", gameImage: "baseball")
        }
        .tabViewStyle(PageTabViewStyle())
    }
}
// MARK: 游戏项
struct gameRowView: View {
    var gameName: String
    var gameHelpText: String
    var gameImage: String
    var body: some View {
        VStack(alignment: .center, spacing: 60) {
            Text(gameName)
                .font(.system(size: 48))
                .bold()
                .foregroundColor(.white)
            VStack(alignment: .center, spacing: 10) {
                Text(gameHelpText)
                    .font(.system(size: 17))
                    .foregroundColor(.white)
                Image(gameImage)
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(maxHeight: UIScreen.main.bounds.size.width - 20)
            }
        }
    }
}
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

本章小结

首要恭喜你,完结了本章的介绍的一切内容!

空气投篮iOS端的页面现在咱们只完结了前2张,接下来,咱们将持续完结其余的页面及其交互,以及后面也会切换到Watch端,完结空气投篮Watch端的相关页面规划。

总的来说,空气投篮App的页面及其交互并不复杂。

这个项目很小,却实实在在戳中了很多用户的内心。仿佛某些个人“很傻”的小习气被大众所认知、所承受,这种满足感刚好影响到了某个痛点,很小,但很痛。

这或许便是一款好的产品的象征,也应该是每个供给产品服务的企业所追求的。

望共勉之~

版权声明

本文为稀土技术社区首发签约文章,14天内制止转载,14天后未获授权制止转载,侵权必究!