在SwiftUI中构建"祝wine 词"非常简单,而且很有趣!
让我们开始吧!
struct Toast<Presenting>: View where Presenting: View {
/// The binding that decides the appropriate drawing in the body.
@Binding var isShowing: Bool
/// The view that will be "presenting" this toast
let presenting: () -> Presenting
/// The text to show
let text: Text
var body: some View {
GeometryReader { geometry in
ZStack(alignment: .center) {
self.presenting()
.blur(radius: self.isShowing ? 1 : 0)
VStack {
self.text
}
.frame(width: geometry.size.width / 2,
height: geometry.size.height / 5)
.background(Color.secondary.colorInvert())
.foregroundColor(Color.primary)
.cornerRadius(20)
.transition(.slide)
.opacity(self.isShowing ? 1 : 0)
}
}
}
}
对尸体的解释:
GeometryReader
为我们提供了superview的首选尺寸,从而为我们的Toast
提供了完美的尺寸.
ZStack
个视图堆叠在一起.
- 逻辑很简单:如果不应该看到烤面包(
isShowing == false
),那么我们渲染presenting
视图.如果必须呈现祝wine 词(isShowing == true
),那么我们用一点模糊来渲染presenting
视图——因为我们可以——然后我们接下来创建祝wine 词.
- toast只有
VStack
和Text
,有定制的框架尺寸,一些设计铃铛和口哨( colored颜色 和角半径),以及默认的slide
过渡.
我在View
上添加了这个方法,以简化Toast
的创建:
extension View {
func toast(isShowing: Binding<Bool>, text: Text) -> some View {
Toast(isShowing: isShowing,
presenting: { self },
text: text)
}
}
还有一个关于如何使用它的小演示:
struct ContentView: View {
@State var showToast: Bool = false
var body: some View {
NavigationView {
List(0..<100) { item in
Text("\(item)")
}
.navigationBarTitle(Text("A List"), displayMode: .large)
.navigationBarItems(trailing: Button(action: {
withAnimation {
self.showToast.toggle()
}
}){
Text("Toggle toast")
})
}
.toast(isShowing: $showToast, text: Text("Hello toast!"))
}
}
我用了一个NavigationView
来确保整个屏幕都是视图,所以Toast
的大小和位置都是正确的.
withAnimation
块确保应用Toast
转换.
How it looks:
借助SwiftUI DSL的强大功能,很容易扩展Toast
.
Text
号wine 店很容易变成@ViewBuilder
号的封闭式建筑,以容纳最奢华的布局.
To add it to your content view:
struct ContentView : View {
@State private var liked: Bool = false
var body: some View {
VStack {
LikeButton(liked: $liked)
}
// make it bigger by using "frame" or wrapping it in "NavigationView"
.toast(isShowing: $liked, text: Text("Hello toast!"))
}
}
How to hide the toast afte 2 seconds (as requested):
在toast VStack
中的.transition(.slide)
后面追加此代码.
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
withAnimation {
self.isShowing = false
}
}
}
Tested on Xcode 11.1