Say Hello to MegaX
有的时候会有很多想法和点子,开了很多的项目,发现很多代码都是重复的,比如每个项目中我都会创建一个 if-else
的 View Modifier、BlurView 这些,最近我对于 CameraView 的使用也更加频繁了。
So, why not create a framework that gathers everything we will need in our development proccess?
Sure. We can.
于是,我和自己一拍即合,就开始找寻自己曾经开发过的一些可以复用的组件,对其改造甚至是重写,使其可以适用于不同的场景。
321,上链接:https://github.com/LiYanan2004/MegaX
So, what should we call it?
Well, that brings us to our legendary crack marketing team.
Sorry,串台了。
CameraView
在过年期间,我花了一个礼拜时间写了一个 System-like CameraView,用于拍摄静态图片,相信也是一个很常见的需求。
支持快速快门优先的响应式拍摄。
这里是一个简单的例子。
1 | import SwiftUI |
这里需要额外在 App 入口增加一个 AppOrientationDelegate
是因为在 iPhone 上需要限制在 CameraView
内只能以 portait
显示,从而保证 UI 能够始终保持在原地。
当完成拍摄、完成处理后会调用闭包,你可以在这里处理后续的保存、处理的任务。
AsyncButton
有时候,我们会在 Button
中使用异步操作来执行耗时任务,同时伴随需要展示 ProgressView
使用 MegaX 后,一切都变得简单起来。
1 | AsyncButton("Download", systemName: "arrow.down.circle") { |
你可以像使用 Button
一样创建一个 AsyncButton
也可以额外创建自定义的 ProgressView Placeholder,默认就是:ProgressView()
Backdrop Blur Layer
这应该是一个重磅功能了。
SwiftUI 提供了原生的 Material
材质,但是除了模糊层之外还包含了CubedLuminanceMappingLayer
(一种可以自适应深浅色模式的光照映射层)
在 MegaX 中,我通过大量实验(thanks to SwiftUI Preview)找到了一种很强大的调节方案,极大程度上的抵消掉了 CubedLuminanceMappingLayer
,同时可以适应不同的背景
这样,我们就获得了”纯粹的“ Backdrop-Blur Layer
我知道 CAFilter 里有一个高斯模糊的滤镜,但是 CAFilter 是 Private API,无法完全确定是否可以通过审核。
MagaX 提供了纯粹的 SwiftUI 的解决方案,100% 过审核
1 | YourView() |
这样会在视图下方增加一层模糊,模糊的内容是 YourView
下方的内容,而不是 YourView
本身
这是和 blur(radius:opaque:)
的本质区别
如果你正在构建一个 NavigationBar,你可以还需要处理 bar 和 content 之间的过度,这时候你可以使用 smoothEdges
1 | CustomNavigationBar() |
这样就会在模糊层底部增加一个从 opaque 到 transparent 的蒙板
LongPressGesture with Location
我们很熟悉 SpatialTapGesture
和 onTapGesture(action: (CGPoint) -> Void)
API.
可惜的是,在我做 CameraView
时需要实现长按锁定对焦,也需要获取到点按的位置,于是就有了 SpatialLongPressGesture
[!Tip] 但是这里有一点需要特别注意:你需要使用 onChanged 来获取到争取的状态,而不是 onEnded
1 | YourView() |
也可以使用 View Modifier 的版本:onLongPressGesture(minimumDuration:maximumDistance:coordinateSpace:perform:)
1 | YourView() |
More
if-else
modifier请谨慎地使用这个修改器,因为它会导致性能问题以及奇怪的动画。
当且仅当
condition
值在整个 View LifeCycle 内不会变化时使用该修改器。举个栗子:在 iPad 环境中额外需要添加一个 padding
1
2
3
4
5
6
7
8import MegaX
var deviceType (\.deviceType)
YourView()
.if(deviceType == .pad) { content in
content.padding()
}在这个例子中,在整个 View LifeCycle 中,deviceType 不会变化,可以放心使用这个修改器。
DeviceType
environment value.mac
、tv
、vision
、watch
基本都是在编译期(Native)就确定了iPad、iPhone、CarPlay、Mac Catalyst 会在运行时获取(
UIDevice.current.userInterfaceIdiom
)需要注意的是,
mac
和Mac Catalyst
是两种DeviceType
Ending
这个库目前还是 WIP 状态,会不断迭代更新,希望它可以帮助到正在使用 SwiftUI 开发的开发者们。
Say Hello to MegaX