exyte / popupview Goto Github PK
View Code? Open in Web Editor NEWToasts and popups library written with SwiftUI
License: MIT License
Toasts and popups library written with SwiftUI
License: MIT License
Hi, Thanks for your works on this cool project, I have question that when we enable closeOnTapOutside
, how can enable prevent the outside view object receiving the tap event?
Hello there!
I modified the source code, and fixed these issues:
1、Wrong layout in presented view(present via sheet)
2、NavigationBarItem bounce when pull down a presented view(view.isModalInPresentation = true)
3、Popup block ColorPicker tap gesture when popup view is invisible.
Which I didn't implement:
1、Have not implement drag gesture
2、Have not test on Mac、Watch、TV
Apologize for no time to pull a request.
Thanks for your open source.
// Usage
struct TestPage: View {
@State var show: Bool = false
var body: some View {
VStack {
Text("1")
.onTapGesture {
show.toggle()
}
Spacer()
}
.em_popup(isPresented: $show,
position: .top(padding: 44),
duration: 2,
animation: .spring(),
ignoreEdges: nil,
closeOnTap: true,
closeOnTapOutside: true,
popupContent: {
Color.red.frame(width: 200, height: 100)
}, onDismiss: {
print("dismissed")
})
}
}
// Source Code
import SwiftUI
extension View {
public func em_popup<EMPopupContent: View>(isPresented: Binding<Bool>,
position: EMPopupPosition,
duration: Double? = nil,
animation: Animation? = .spring(),
ignoreEdges: Edge.Set?,
closeOnTap: Bool = true,
closeOnTapOutside: Bool = true,
popupContent: @escaping () -> EMPopupContent,
onDismiss: @escaping() -> ()) -> some View {
self.modifier(
EMPopupView(isPresented: isPresented,
position: position,
duration: duration,
animation: animation,
ignoreEdges: ignoreEdges,
closeOnTap: closeOnTap,
closeOnTapOutside: closeOnTapOutside,
popupContent: popupContent,
onDismiss: onDismiss)
)
}
@ViewBuilder
func em_apply_if<T: View>(_ condition: Bool, apply: (Self) -> T) -> some View {
if condition {
apply(self)
} else {
self
}
}
}
public enum EMPopupPosition: Equatable {
case top(padding: CGFloat = 0)
case bottom(padding: CGFloat = 0)
var padding: CGFloat {
switch self {
case let .top(padding):
return padding
case let .bottom(padding):
return padding
}
}
static public func == (lhs: EMPopupPosition, rhs: EMPopupPosition) -> Bool {
switch lhs {
case .top:
switch rhs {
case .top:
return true
case .bottom:
return false
}
case .bottom:
switch rhs {
case .top:
return false
case .bottom:
return true
}
}
}
}
public struct EMPopupView<EMPopupContent: View>: ViewModifier {
@Binding var isPresented: Bool
var position: EMPopupPosition
var duration: Double?
var animation: Animation?
var ignoreEdges: Edge.Set?
var closeOnTap: Bool
var closeOnTapOutside: Bool
var popupContent: () -> EMPopupContent
var onDismiss: () -> ()
@State private var presenterContentRect: CGRect = .zero
@State private var popupContentRect: CGRect = .zero
@State private var topPadding: CGFloat = 0
private var dispatchWorkHolder: DispatchWorkHolder = DispatchWorkHolder()
// Handle dispatch capture self
private var isPresentedRef: ClassReference<Binding<Bool>>?
private var hideOffset: CGFloat {
if case EMPopupPosition.top(_) = position {
return -popupContentRect.height
} else {
return presenterContentRect.height
}
}
init(isPresented: Binding<Bool>,
position: EMPopupPosition,
duration: Double?,
animation: Animation?,
ignoreEdges: Edge.Set?,
closeOnTap: Bool,
closeOnTapOutside: Bool,
popupContent: @escaping () -> EMPopupContent,
onDismiss: @escaping() -> ()) {
self._isPresented = isPresented
self.position = position
self.duration = duration
self.animation = animation
self.ignoreEdges = ignoreEdges
self.closeOnTap = closeOnTap
self.closeOnTapOutside = closeOnTapOutside
self.popupContent = popupContent
self.onDismiss = onDismiss
self.isPresentedRef = ClassReference(self.$isPresented)
}
public func body(content: Content) -> some View {
content
.background(
// get presenter' rect
GeometryReader { proxy -> AnyView in
let rect = proxy.frame(in: .global)
if rect.integral != self.presenterContentRect.integral {
DispatchQueue.main.async {
self.presenterContentRect = rect
}
}
return AnyView(EmptyView())
}
)
.overlay(makePopupContent())
}
private func makePopupContent() -> some View {
if duration != nil {
dispatchWorkHolder.work?.cancel()
dispatchWorkHolder.work = DispatchWorkItem(block: { [weak isPresentedRef] in
isPresentedRef?.value.wrappedValue = false
onDismiss()
})
if isPresented && dispatchWorkHolder.work != nil {
DispatchQueue.main.asyncAfter(deadline: .now() + duration!, execute: dispatchWorkHolder.work!)
}
}
let popup = ZStack {
// background
Color.clear
.onTapGesture {
if closeOnTapOutside {
self.dispatchWorkHolder.work?.cancel()
isPresented = false
self.onDismiss()
}
}
// pop up content
VStack(spacing: 0) {
if position == EMPopupPosition.bottom(padding: 0) { Spacer() }
HStack(spacing: 0) {
popupContent()
.padding(.top, position == EMPopupPosition.top(padding: 0) ? position.padding : 0)
.padding(.bottom, position == EMPopupPosition.bottom(padding: 0) ? position.padding : 0)
.background(
GeometryReader { proxy -> AnyView in
let rect = proxy.frame(in: .global)
if rect.integral != self.popupContentRect.integral {
DispatchQueue.main.async {
self.popupContentRect = rect
}
}
return AnyView(EmptyView().frame(width: popupContentRect.width).animation(.none))
}
)
.onTapGesture {
if closeOnTap {
self.dispatchWorkHolder.work?.cancel()
isPresented = false
self.onDismiss()
}
}
}
if position == EMPopupPosition.top(padding: 0) { Spacer() }
}
}
.em_apply_if(ignoreEdges != nil, apply: { view in
view.edgesIgnoringSafeArea(ignoreEdges!)
})
.opacity(isPresented ? 1 : 0)
.offset(y: isPresented ? 0 : hideOffset)
.animation(animation)
return popup
}
}
// Handle dispatch capture self
fileprivate class DispatchWorkHolder {
var work: DispatchWorkItem?
}
// Handle dispatch capture self
fileprivate final class ClassReference<T> {
var value: T
init(_ value: T) {
self.value = value
}
}
Hi,
I have found that if the view being presented by PopupView
contains a SegmentedPicker
view and closeOnTapOutside
is true
, the SegmentedPicker
does not respond to changes with the usual tap gesture, only to long presses and dragging of segments across it. I believe there are issues with the TapGesture
responsible for closeOnTapOutside
.
Example with closeOnTapOutside
set to true
https://user-images.githubusercontent.com/17231825/127427851-838b4b1c-99ce-490a-9085-29199ddb0b19.mov
Example with closeOnTapOutside
set to false
I've tested the Popup with this simple View
import SwiftUI
import PopupView
struct ContentView: View {
@State var name: String = ""
@State var isPopupPresented = false
var body: some View {
NavigationView {
ZStack {
Text("Test")
.padding()
.overlay(RoundedRectangle(cornerRadius: 8).stroke().foregroundColor(.green))
}.popup(isPresented: $isPopupPresented, view: {
HStack {
Text("The popup")
}
.frame(width: 200, height: 60)
.background(Color(red: 0.85, green: 0.8, blue: 0.95))
.cornerRadius(30.0)
})
.navigationBarTitle("Large Title")
}
}
}
but as soon as I deploy it on the simulator the view crashes with this log
2020-06-11 12:07:41.661664+0200 Test[2114:73858] precondition failure: invalid input index: 4
(lldb)
The popup is not working anymore, it doesn't appear 🤔 this code was working in v0.0.3 but not on the latest v0.0.4
struct ContentView: View {
@State var name: String = ""
@State var isPopupPresented = false
var body: some View {
ZStack {
VStack {
Text("Test")
.padding()
.overlay(RoundedRectangle(cornerRadius: 8).stroke().foregroundColor(.green))
Button(action: {
self.isPopupPresented.toggle()
}, label: { Text("Deploy").padding() })
}.padding()
}.popup(isPresented: $isPopupPresented, type: .toast, autohideIn: 3.0, view: {
HStack {
Text("The popup")
}
.frame(width: 200, height: 60)
.background(Color(red: 0.85, green: 0.8, blue: 0.95))
.cornerRadius(8.0)
.padding(.bottom, 25)
})
}
}
When I use the type .floater(verticalPadding:)
in case of a NavigationView
and the position is top
, the popup view appears on top of the notch in iPhone X and later, which requires me to calculate safeAreaInsets.top
and then add it to the padding, this can be done using GeometryReader
which's not suitable in some situations and has side effects.
I believe adding a default value for the padding to include top safe area insets would be a good idea.
The default popup is displayed, so it may be that the toast exists further down than the ipad's sheet display area.
Xcode 13.2.1
iPadOS 15.2
`
//MasterView.swift
import SwiftUI
import CoreData
import Foundation
class DataCenter: ObservableObject {
@published var toastPopupView:AnyView = AnyView(EmptyView())
@published var showtoastPopup:Bool = false
}
struct ContentView: View {
@StateObject var dataCenter = DataCenter()
@State var isLoading:Bool = false
var body: some View {
ZStack{
Color("launchScreenBackgroundColor").ignoresSafeArea()
NavigationView{
MainView(selectedView: ShowView()).environmentObject(dataCenter)
}.navigationViewStyle(StackNavigationViewStyle())
dataCenter.toastPopupView
}.navigationBarHidden(true)
.navigationBarBackButtonHidden(true)
}
}
`
`
//ChildView.swift
import SwiftUI
struct DashboardS: View {
var body: some View {
ZStack(alignment:.top){
Color("launchScreenBackgroundColor2").ignoresSafeArea()
}.navigationBarHidden(true)
.navigationBarBackButtonHidden(true)
.onAppear {
]
dataCenter.showtoastPopup = false
dataCenter.toastPopupView = AnyView(
ZStack{
}.frame(maxWidth: .infinity)
.frame(height:120)
.popup(isPresented: $dataCenter.showtoastPopup, type: .toast, position: .bottom, animation: .default, autohideIn: 2, dragToDismiss: true, closeOnTap: true, closeOnTapOutside: true) {
HStack {
Text("TEST").foregroundColor(Color.white)
}
.frame(maxWidth: .infinity)
.frame(height:120)
.background(Color.red)
.shadow(color: .black, radius: 2)
}.frame(maxWidth: .infinity)
.frame(height:120)
)
DispatchQueue.main.async {
dataCenter.showtoastPopup = true
}
// DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
// dataCenter.showtoastPopup = false. // this turning to false also not working
//// dataCenter.toastPopupView = AnyView(EmptyView())
// }
}
}
}
`
this is a short example
but from main to a child there are several views that loads for bottom navigation.
popup comes, drag to close work but tap to close, outside tap to close and autohide not working.
Thanks
First off I'm happy with the library, it made showing a popup easy. I'd very much like to queue them and have found that to be somewhat cumbersome on my end. Any chance you could add either some kind of dismiss callback, make the binding value passed in set to false when autohide happens, or just build some nice API for queuing popups?
Here is an example
The current implemention is even showSystemAlertNotification
= false, popup body is still executed. This could bring some problems in reality:
data
struct is set a valid value only if showSystemAlertNotification= true. Since it's not lazy-loaded, a crash happens since self.systemAlertNotification = nil
.popup(isPresented: $showSystemAlertNotification, type: .floater(), position: .top, animation: Animation.spring()) {
SystemAlert(alert: self.data!)
}
Hello, thanks for this useful pod :)
I recommend if you add a feature for hiding modal when users click to the outside of modals, it will be so useful :)
Thanks in advance.
I'm using this view like this:
var body: some View {
ZStack {
VStack(alignment: .center, spacing: 0, content: {
Text("Hello")
Spacer().frame(height: 50)
Text("Another Text")
Spacer().frame(height: 30)
SomeOtherComponent()
Button("Next") {
print("Button clicked")
}
Spacer()
Image("Official-Logo")
.resizable()
.scaledToFit()
.padding(.vertical, 10)
.padding(.horizontal, 15)
.frame(
minWidth: 0,
maxWidth: .infinity
)
}).padding(.top, 50)
}.popup(isPresented: $showingMessage, closeOnTapOutside: true) {
VStack(alignment: .leading, spacing: 5, content: {
Text("Information?")
.padding(EdgeInsets(top: 10, leading: 10, bottom: 5, trailing: 10))
Text("Lorem Ipsum Dolor.")
.padding(EdgeInsets(top: 5, leading: 10, bottom: 20, trailing: 10))
})
.frame(width: 320, height: 250)
.background(Color("darkGray"))
.cornerRadius(5.0)
}
}
So in this view, whenever I click outside the popup esp. in the spacers it just fails to dismiss the popup.
There's a need to pass information to the toast UI. SwiftUI handles this for various views by providing an item
variant for view modifiers:
public func popover<Item, Content>(item: Binding<Item?>, attachmentAnchor: PopoverAttachmentAnchor = .rect(.bounds), arrowEdge: Edge = .top, @ViewBuilder content: @escaping (Item) -> Content) -> some View where Item : Identifiable, Content : View
I'm looking at your code and wondering how hard it would be to add the same thing, but I don't quite understand everything you're doing in yours.
Hey all, I have Button which calls a ScannerView and receives the scanned barcode. I would like to pass the scanned String to a popup view and can't figure out how to do it properly. The pop up is always empty
That's my simplified code
struct WorkflowView: View {
@State private var isShowingScanner = false
@State private var scannedCode: String?
@State private var isShowingScannerBanner = false
var body: some View {
ZStack{ //need to trigger pop up views
VStack {
Button(action: {
self.isShowingScanner = true
}, label: {
Text("Scan barcode")
.font(.title)
.padding(5)
.background(Color.orange)
.cornerRadius(10)
})
}
.sheet(isPresented: $isShowingScanner) {
CodeScannerView(codeTypes: [.ean8, .ean13, .upce, .code39, .code93, .code128, .code39Mod43, .interleaved2of5, .qr]) { response in
if case let .success(result) = response {
scannedCode = result.string
isShowingScanner = false
isShowingScannerBanner = true
}
}
}
}
.popup(isPresented: $isShowingScannerBanner, type: .floater(verticalPadding: 90), position: .top, autohideIn: 2) {
createSuccessBanner(message: scannedCode ?? "")
}
}
.popup(isPresented: $showAlert, type: .floater() ,position: .top, animation: Animation.spring(), autohideIn: 2) {
HStack(spacing: 10) {
Image(systemName: "xmark.circle.fill")
.foregroundColor(.white)
.font(.system(size: 20))
Text("No data".localized)
.font(.headline)
.foregroundColor(.white)
}
.frame(width: 150, height: 40)
.background(Color.red)
.cornerRadius(30.0)
.shadow(radius: 5)
}
First, thanks for your PopupView library❤️.
ContentView's @StateObject variable never deinit
class Test: ObservableObject {
var loadState: EMLoadState = .loading
var groupEntityArr: [ListGroupEntity] = []
var groupStructArr: [ListGroupStruct] = []
@Published var groupUIArr: [ListGroupUI] = []
deinit {
print("deinit will never be executed") // 《=========
}
}
struct TestView: View {
@StateObject var viewModel = Test()
@State var show: Bool = false
@State var text: String = ""
var body: some View {
ZStack {
}
.popup(isPresented: $show, autohideIn: 2, dismissCallback: {
temp()
}, view: {
Text(text)
})
}
func temp() {
print(self.text)
}
}
if let autohideIn = autohideIn {
dispatchWorkHolder.work?.cancel()
let block = dismissCallback // add this code
dispatchWorkHolder.work = DispatchWorkItem(block: { [weak isPresentedRef] in
isPresentedRef?.value.wrappedValue = false
dismissCallback() // remove this code, which cause @StateObject never deinit
block() // add this code
})
if isPresented, let work = dispatchWorkHolder.work {
DispatchQueue.main.asyncAfter(deadline: .now() + autohideIn, execute: work)
}
}
I've implemented a queue of toasts, using PopupView
for presentation. The issue I'm running into is that when a toast is dismissed via tap and I present the next toast in queue, it gets auto-hidden early. It looks like this is the code with the bug.
if let autohideIn = autohideIn {
dispatchWorkHolder.work?.cancel()
dispatchWorkHolder.work = DispatchWorkItem(block: {
self.isPresented = false
})
if isPresented, let work = dispatchWorkHolder.work {
DispatchQueue.main.asyncAfter(deadline: .now() + autohideIn, execute: work)
}
}
It seems that since dispatchWorkHolder
is a class, it's work
property is being passed by reference. Therefore, when I present a second toast, the work
property is set to a new DispatchWorkItem
that has not been cancelled. So at the time the previously scheduled asyncAfter
executes, it is not a cancelled item.
Hi ! Thanks for your work and for sharing with us this library. I'm coming with a suggestion for improving the UX regarding the options that a user has in order to dismiss the popup. It would be cool if the user would be able to dismiss it by dragging down. Thanks a lot !
dragToDismiss = false not working
Currently, when I go for a toast or a float, if I pass .top, it animates from the top bot goes all the way to the bottom. If I pass in .bottom, it animates from the bottom but goes all the way to the top
Hey everyone,
I was wondering if anybody could point me in the right direction on how to modify the PopupView.swift
file to add a background blur and a dropshadow to the popup window. I have been trying to adjust the file but I'm unable to blur the view below the popup.
Thanks for your help!
Is it possible to defer invoking the view closure until after the popup state changes and needs to be displayed?
Is there a way to show a optional grey background mask as what a normal modal/alert/action sheet does?
Hi there. Thanks for this library. Could we also get a position .center? Thanks!
Hello ,Thanks for sharing with us this library. My only issues is ,when i tap on the popup it dismissed automaticly ,eny solution to stop that plz.
Is there a way for the popup to dismiss itself when it doesn't have access to the presentation state variable? Something like self.presentationMode.wrappedValue.dismiss()
?
Hi,
Many thanks for this great package :)
I found an issue (or so I think): the dragToDismiss parameter is not been considered. I believe it should be changed in the bellow function:
/// This is the builder for the sheet content
func sheet() -> some View {
// if needed, dispatch autohide and cancel previous one
if let autohideIn = autohideIn {
dispatchWorkHolder.work?.cancel()
// Weak reference to avoid the work item capturing the struct,
// which would create a retain cycle with the work holder itself.
dispatchWorkHolder.work = DispatchWorkItem(block: { [weak isPresentedRef] in
isPresentedRef?.value.wrappedValue = false
dismissCallback()
})
if isPresented, let work = dispatchWorkHolder.work {
DispatchQueue.main.asyncAfter(deadline: .now() + autohideIn, execute: work)
}
}
let sheet = ZStack {
Group {
VStack {
VStack {
self.view()
.addTapIfNotTV(if: closeOnTap) {
self.dispatchWorkHolder.work?.cancel()
self.isPresented = false
self.dismissCallback()
}
.background(
GeometryReader { proxy -> AnyView in
let rect = proxy.frame(in: .global)
// This avoids an infinite layout loop
if rect.integral != self.sheetContentRect.integral {
DispatchQueue.main.async {
self.sheetContentRect = rect
}
}
return AnyView(EmptyView())
}
)
}
}
.frame(width: screenSize.width)
.offset(x: 0, y: currentOffset)
.animation(animation)
}
}
// It should return the view if dragToDismiss is false
if (!dargToDismiss) { return sheet }
#if !os(tvOS)
let drag = DragGesture()
.updating($dragState) { drag, state, _ in
state = .dragging(translation: drag.translation)
}
.onEnded(onDragEnded)
return sheet
.offset(y: dragOffset())
.simultaneousGesture(drag)
#else
return sheet
#endif
}
Many thanks in advance.
In this code:
.popup(isPresented: .constant(true),
type: .toast,
position: .bottom,
dragToDismiss: true,
closeOnTap: false,
closeOnTapOutside: true,
dismissCallback: {
// on dismiss
}) {
CardView { ... }
PopupView
bases the appearAction on isPresented
changing:
.valueChanged(value: isPresented) { isPresented in
appearAction(isPresented: isPresented)
}
But if the binding is a .constant(true)
since PopupView's inception, it doesn't appear.
Ideally we'd like to be able to display a toast and it appear no matter if there was a modal on the screen or not. Right now if there is a modal the toast appears underneath it. We could add the view modifier onto this modal view, but then the toast would go down once the view was dismissed. Is this something that is possible?
Xcode. 13.1
iOS 15.0
At the end of a long list I want to trigger a popup view. When the user triggers it the scrollview is reset to beginning.
struct ChildView: View {
@Binding var show: Bool
let text: String
var body: some View {
ScrollView(.vertical, showsIndicators: false) {
ForEach(0..<50) { _ in
Text("Hello World")
.padding()
}
VStack {
Button {
show.toggle()
} label: {
Text(text)
}
}
}
.clipped()
}
}
struct TabsView: View {
@State var show = false
var body: some View {
ZStack {
TabView {
ChildView(show: $show, text: "FirstView")
.tabItem({
Label("First", systemImage: "greetingcard")
})
}
}
.popup(isPresented: $show, type: .default, dragToDismiss: true, closeOnTap: false, closeOnTapOutside: true, backgroundColor: .black.opacity(0.5)) {
VStack {
Text("👻")
Text("Hello World.")
Button {
show.toggle()
} label: {
Text("Dismiss ")
}
}
.padding(.vertical, 20)
.padding(.horizontal, 40)
.frame(width: 300, height: 300)
.background(.red)
.cornerRadius(10)
}
}
}
I want to react differently when popup is dismissed because of a tap or because of a drag.
Here is the changes I've made to accomplish this 👇
Is there another way of achieving what I want ?
I tried adding a click on my view but it doesn't work well since it doesn't take into account your drag handling code.
Do you think that can interest other users ? Do you want me to do a pull request ?
Hello there.
I want to show pop ups on tabbar page. I want to show the views I have created in subpages but. I want to send views via shared class ObservableObject. I couldn't solve it anyway. Can you help me with this?
class sharedValues: ObservableObject {
@Published var selectedItemIndex : Int = 1
@Published var showTabBar : Bool = true
@Published var blurTabBar : Bool = false
@Published var showingPopup = false
var sharePopupView ?
}
struct TabPage: View {
@EnvironmentObject var share : sharedValues
var body: some View {
VStack(spacing:0) {
NavigationView{
switch share.selectedItemIndex {
case 0: Shop()
case 1: ConversationsView()
case 2: GameHome()
case 3: GameHome()
default: GameHome()
}
}
Tabbar()
}
.popup(isPresented: $share.showingPopup, type: .`default`,animation: .spring(), closeOnTapOutside: true) {
share.sharePopupView
}
}
}
struct ConversationsView: View {
@ViewBuilder private func sunpage1() -> some View {
HStack(){
Button(action: {
share.showingPopup = true
share.sharePopupView = {
Some view items ????
}
}) {
VStack {
Image(systemName: "trash.slash")
Text("delete all")
}
}
}
}
Changing how the view is shown would prevent reloading of the content.
public func body(content: Content) -> some View {
Group {
main(content: content)
}
.valueChanged(value: isPresented) { isPresented in
appearAction(isPresented: isPresented)
}
}
private func main(content: Content) -> some View {
ZStack {
content
.frameGetter($presenterContentRect)
if showContent {
backgroundColor
.applyIf(closeOnTapOutside) { view in
view.contentShape(Rectangle())
}
.addTapIfNotTV(if: closeOnTapOutside) {
dismiss()
}
.edgesIgnoringSafeArea(.all)
.opacity(currentBackgroundOpacity)
.animation(animation)
}
}
.overlay(sheet())
}
When dismissing the popup view, got error message often, anyone know how to resolve it?
2021-04-14 12:51:35.864282+0800 gikiapp[923:160335] [SwiftUI] Invalid frame dimension (negative or non-finite).
2021-04-14 12:51:35.883202+0800 gikiapp[923:160335] [SwiftUI] Invalid frame dimension (negative or non-finite).
...
If set to show on the bottom the view moves up the screen when dismissed. Tried increasing the hiddenOffset to no avail. https://drive.google.com/file/d/1w3eB-60w5Ua6J-ulJKLbeGxRyFhEJYpG/view?usp=sharing
When using this library with a List and Navigation links, you have to hold the list cell to activate the navigation link or swipe to delete.
Here is the code I'm using to set up the toast:
.popup(isPresented: $showCopiedToast,
type: .toast,
position: .bottom,
autohideIn: 2,
closeOnTap: false) {
HStack {
Text(self.toastText)
}
.frame(width: 200, height: 60)
.background(Color(red: 0.85, green: 0.8, blue: 0.95))
.cornerRadius(30.0)
.padding(15)
}
My guess is the simultaneousGesture
stuff is messing with the list view. A workaround or fix would be appreciated.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.