Section 11 : Drag Progress and Tap Background

Section 11 : Drag Progress and Tap Background - 拖拽进程和点击背景 (7’44")

Use the drag values and use them as a progress to animate views in SwiftUI.

在 SwiftUI 中利用拖拽值控制视图的动画过程。

1. 解决上一节的遗留问题

(1)在 Home.swift 中给 ZStack 中的 MenuView 添加背景

MenuView()
	.background(Color.black.opacity(0.01))		// 透明度是为了不显示但是能点击交互

(2)如果将透明度改为 1,会发现偏移的还不够,所以修改偏移量

.offset(y: showProfile ? 0 : 1000)	

这个 1000 是硬编码,下一节我们会调整为按屏幕尺寸计算,这样无论多大的屏幕都能正常偏移了。

(3)给背景加上手势,这样就可以关闭 MenuView 了。

MenuView()
    .background(Color.black.opacity(0.001))  // 透明度是为了不显示但是能点击交互
    .offset(y: showProfile ? 0 : 1000)
    .animation(.spring(response: 0.5, dampingFraction: 0.6, blendDuration: 0))
    .onTapGesture {
        self.showProfile.toggle()			// 关闭视图
}

视频的本意是,单击上面旋转后的 VStack 来关闭,但是这样写的结果是,几乎单击任何地方都关闭。另外,如果那个背景的透明度改成了 0 ,那么点击将不再起作用了。

2. 创建 MenuView 的拖动进程动画

(1)还记得前面做拖动卡片组的做法吗?对,要有个状态来协助一下。所以,增加一个状态先。

@State var viewState = CGSize.zero		// 视图位置的状态,用来协助 MenuView 的拖动

(2)在 MenuView 组件的最后加上拖动手势,再增加一个偏移修饰让卡片能随手势移动。在手势结束时,检查移动量,超过 50 的时候,关闭 MenuView 组件。

MenuView()
    .background(Color.black.opacity(0.01))  // 透明度是为了不显示但是能点击交互
    .offset(y: showProfile ? 0 : 1000)      // showProfile 为 false 时隐藏
    .offset(y: viewState.height)            // 跟随拖动改变偏移
    .animation(.spring(response: 0.5, dampingFraction: 0.6, blendDuration: 0))
    .onTapGesture {
        self.showProfile.toggle()           // 关闭视图
}
.gesture(
    DragGesture().onChanged { value in		// 拖动手势,参见第 5 节
        self.viewState = value.translation
    }
    .onEnded { value in
		if self.viewState.height > 50 {     // 向下拖动超过 50 时,关闭组件
            self.showProfile = false
        }
        self.viewState = .zero
    }

(3)修改 VStack 的 3D 旋转效果来响应 MenuView 的拖动

.rotation3DEffect(Angle(degrees: showProfile ? (Double(viewState.height) / 10  - 10) : 0), axis: (x: 10, 	 y: 0, z: 0))

小窍门:了解返回值类型

按照键点击需要查看的部分,如果有帮助显示出来,看上面 后面的内容就是类型。如:

var height: CGFloat

说明返回值的类型是 CGFloat

这里首先要注意的是,viewState.height 的值类型是 CGFloat。而 showProfile 需要的类型是 Double,所以必须将 height 的类型强制转换后才能使用(Swift 规定不同类型的值不能进行运算!!!)。另外就是这个 rotation3DEffect()是 View 的一个方法,文档超级简单,没有参数说明。也许人家都说英语的就不用写了,但是大叔看不懂啊~~~囧😳。只好祭出无敌大法——猜!

当然不能瞎猜,结合实验就能了解更多。

我也留个 Challenge,修改动画,让画面看起来是这样的:

  • 向下拖动,VStack 会跟随向下平移
  • 向上拖动,VStack 沿着屏幕上边界旋转,但下沿始终和被拖动的 MenuView 的上沿保持一个相同的距离。好像是被 MenuView 挤上去的一样。

本节小结

本节代码请参见 GitHub码云

  • 巧用透明度设置点击交互区域
  • 再次使用拖动手势加上状态变量形成动画
  • 不同类型的数值不能一起运算,需要先将它们转换成统一的类型。注意并非所有类型都可以相互转换。
  • rotation3DEffect 方法的应用
接下来

现在屏幕上堆叠了大量的视图,下一节将介绍创建组件,绑定状态。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值