Technology Stack: Swift / JAVA / JS / React / HTML / CSS / C++
- 🔭 Currently working as an iOS Mobile Developer in the biggest mobility company in my country.
- ⚡ Hobby: Unreal Engine Game Development.
Create Apple-like alerts & toasts using SwiftUI
Home Page: https://elai950.github.io/AlertToast/
License: MIT License
Technology Stack: Swift / JAVA / JS / React / HTML / CSS / C++
Describe the bug
When using a long Subtitle and in DisplayMode "hub" or "banner" the subtitle doesn't wrap correctly and cuts off on both sides left and right
To Reproduce
Steps to reproduce the behavior:
The following code will demonstrate the issue
AlertToast(displayMode: .alert,
type: .regular,
title: "Sample Message",
subTitle: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec gravida eleifend scelerisque. Donec ornare malesuada orci, nec tempus massa lacinia non.\n\nMaecenas sit amet convallis orci. Aenean malesuada lacus sed odio pulvinar elementum non a tellus. Etiam cursus erat sed fermentum lobortis. Phasellus feugiat euismod orci. Donec ultrices fringilla fringilla.")
Expected behavior
The text should be displayed the same way it does with DisplayMode "alert".
Screenshots
This is the toast using "alert"
Smartphon:
Describe the bug
When presenting AlertToast in SwiftUI view with Inline Navigation view, AlertToast with display mode (.hud) hides behind the navigation view.
To Reproduce
Steps to reproduce the behavior:
import SwiftUI
import AlertToast
struct ContentView: View {
@State var isPresenting = true
var body: some View {
NavigationView {
ZStack {
VStack{
Text("Hello, world!")
.padding()
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.toast(isPresenting: $isPresenting, duration: 2.0, tapToDismiss: true, alert: {
return AlertToast(displayMode: .hud, type: .complete(.white), title: "Testing Alert Toast")
})
}
.navigationTitle("Navigation Title")
.navigationBarTitleDisplayMode(.inline)
}
}
}
Expected behavior
AlertToast should present in front of the navigation view.
Smartphone (please complete the following information):
I tried this in my project, where Im using some views in sheets. I need some global error handling, so I used this on top level view. It cant work, because this implementation uses simple overlay over content view. Unfortunately I didnt look into the source codes before trying to integrate it... 😞
Describe the bug
I assume it is a bug and not intention. I cannot present a message that is longer than X characters.
I am using a Banner
type but it seems to behave similar with HUD
too.
My assumption was that using a subtitle, it would show multiple lines and the banner would grow bigger in vertical size.
Expected behavior
A clear and concise description of what you expected to happen.
Smartphone (please complete the following information):
I would like to be able to increase the size of the toast windows under MacOS so that the entire text can be read, either by stipulating the size of the window or having the window size automatically to the text provided.
The window is fixed-size (small) with the text truncated and replaced with "...".
This does not occur with the iOS version of my app.
Describe the bug
I expect to display loading alert. Once Published variable changes to different value then I'd expect new alert to display only 2 seconds, not infinite. Also tap to dismiss does not work in this case
Expected behavior
.toast(isPresenting: $showToast) { if viewModel.sendMessageResponse == .successfullySent { return AlertToast(type: .complete(.green), title: "Message Sent!", custom: .custom(backgroundColor: Color.customYellow)) } else if viewModel.sendMessageResponse == .errornousResponse { return AlertToast(type: .error(.red), title: "Unable to send message!", custom: .custom(backgroundColor: Color.customYellow)) } else { return AlertToast(displayMode: .alert, type: .loading, custom: .custom(backgroundColor: Color.customYellow)) }
Steps
Let me give an example in a real case.
Ideally, .toast(isPresenting: $showToast){
should be mounted under any view and presented on the screen, even that view is a small button/view. The current situation is it has to be mounted under the page(screen)
After updating to package version. 1.3.1 i'm getting the following error in Xcode 13
''AlertToast' initializer is inaccessible due to 'internal' protection level'
Please advise.
Here is the video of my problem. It's pretty simple. I realized that when I use displayMode: .alert
everything works fine, but with any other displayMode it messes up navigation and navigation doesn't work properly. It's like it reopens the same screen and just displays toast.
I cannot figure out why. If you need further explanation I can give it to you :)
Video: https://vimeo.com/663400646
Getting this error message in Xcode 13.
Invalid frame dimension (negative or non-finite).
It's happening on this line
.frame(maxWidth: .infinity, maxHeight: alert().displayMode == .alert ? .infinity : -hostRect.midY / 2, alignment: .center)
Is your feature request related to a problem? Please describe.
It's not really a problem but I'm just porting my iOS app to tvOS and I was surprised that this library doesn't work on tvOS. Is there any specific reason for that?
Describe the solution you'd like
To be able to use this lib on tvOS apps.
Describe alternatives you've considered
Only other solution is to not use AlertToast on tvOS and build the view in a different way.
Additional context
I just finished porting my Android app to iOS so some of the Apple stuff is still new to me. If it is obvious why this lib can't work on tvOS I'm sorry for creating this ticket.
Describe the bug
Showing the toast after it starts fading out causes it to become stuck open.
To Reproduce
Steps to reproduce the behavior:
isPresented
to a button.Expected behavior
The toast fades back in and automatically fades back out at the end of the expected show duration.
Actual behavior
The toast fades back in and remains shown until it is manually dismissed by tapping it.
Additional context
The issue is caused by the dismiss delay being set in onAppear
, which is not called unless the view has completely faded out before it fades back in.
I was able to solve the issue in iOS 14/macOS 11 using onChange(of:)
instead of onAppear
(see this commit). However, onChange(of:)
is not available in iOS 13 so I am not sure this is the solution you would want to use.
Sample Code
struct ContentView: View {
@State var showToast = false
var body: some View {
Text("Hello, world!")
.padding()
.toast(isPresenting: $showToast) {
AlertToast(type: .complete(.green))
}
Spacer()
.frame(height: 150)
Button(action: { showToast = true }) {
Text("Press Me!")
}
}
}
Describe the bug
Using .hud
in a popover causes the top of it to be cut off.
To Reproduce
struct ContentView: View {
@State var showPopover = false
@State var showToast = false
var body: some View {
Button("Show Popover") {
self.showPopover.toggle()
}
.popover(isPresented: self.$showPopover) {
List {
Button("Show Toast") {
self.showToast.toggle()
}
}
.toast(isPresenting: self.$showToast) {
AlertToast(displayMode: .hud, type: .regular, title: "Test")
}
}
}
}
Expected behaviour
The toast to be visible.
Describe the bug
I'm not sure if that's possible to achieve, but when showing a toast alert while a keyboard is shown the toast renders behind it.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
I'd expect the toast to render in front of the keyboard, still I'm not sure if that's possible to achieve.
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
Smartphone (please complete the following information):
Additional context
Add any other context about the problem here.
Still thank you for the nice library.
How to prevent it and make it modal? At least have it dim the background. or is this a feature request since it is not available?
Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
I would very like to have an blurred background
Describe the solution you'd like
A clear and concise description of what you want to happen.
When displayMode is set to .hud, the background of the complete view should be blurred
Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
Making a manual blur
Additional context
Add any other context or screenshots about the feature request here.
Updated to version 1.3.5 and still seeing this error message in Xcode 13.
'AlertToast' initializer is inaccessible due to 'internal' protection level
.toast(isPresenting: $showToast){
AlertToast(displayMode: .hud, type: .systemImage(toastImage!, toastImageColor!), title: toastTitle, subTitle: toastSubTitle)
}
whenever I use AlertStyle Xcode throw "Cannot find 'AlertStyle' in scope"
I'm using 1.3.7
I tried to switch to master and decrease the version
I even tried AlertCustom and not worked
I checked this issue but nothing was helpful for my case
Describe the bug
Xcode shows an issue when certain alerts are displayed
Screenshots
If applicable, add screenshots to help explain your problem.
Smartphone (please complete the following information):
Additional context
Problem occurs in AlertToast/AlertToast/line 439
.
Is there an easy way to detect a tap on the banner in order to take an action if it was tapped or not.
When configure AlertToast same like follow, the image not showed:
AlertToast(displayMode: .banner(.slide),
type: .image("icon_warning", Color.white),
title: "Messages may span more than one line,.",
style: AlertToast.AlertStyle.style(backgroundColor: Color.defaultOrangeColor,
titleColor: Color.white,
titleFont: Font.regular16))
You need to add .renderingMode(.template)
when set .foregroundColor(color)
to the Image in your banner
view
Describe the bug
The Loading Toast, cannot be dismissed by Clicking on The Toast but can be dismissed using the button from which the toast is popped up. All Other Toasts can be dismissed by clicking on the toast.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
I want to dismiss the loading toast by clicking on the spinner like in other toasts.
Screenshots
Sorry, No Screenshots are available at this point of time. You can ask for them later.
Desktop (please complete the following information):
Smartphone (please complete the following information):
Additional context
N/A
Describe the bug
The width of the toasts seems to be fixed. When using the default toast with the default text, there is space to show only 3 characters. The width does not expand depending on text size.
To Reproduce
import SwiftUI
import AlertToast
struct ContentView: View {
@State private var showToast = false
var body: some View{
VStack{
Button("Show Toast"){
showToast.toggle()
}
}
.toast(isPresenting: $showToast){
AlertToast(type: .regular, title: "Message sent!")
}
}
}
Expected behavior
The toast should show "Message sent!".
Screenshots
See this image
Smartphone (please complete the following information):
Additional context
Semi-fixed the problem on the HUD view by adding:
///HUD View
public var hud: some View{
Group{
HStack(spacing: 16){
switch type{
case .complete(let color):
Image(systemName: "checkmark")
.hudModifier()
.foregroundColor(color)
case .error(let color):
Image(systemName: "xmark")
.hudModifier()
.foregroundColor(color)
case .systemImage(let name, let color):
Image(systemName: name)
.hudModifier()
.foregroundColor(color)
case .image(let name, let color):
Image(name)
.hudModifier()
.foregroundColor(color)
case .loading:
ActivityIndicator()
case .regular:
EmptyView()
}
if title != nil || subTitle != nil{
VStack(alignment: type == .regular ? .center : .leading, spacing: 2){
if title != nil{
Text(LocalizedStringKey(title ?? ""))
.font(style?.titleFont ?? Font.body.bold())
.multilineTextAlignment(.center)
.textColor(style?.titleColor ?? nil)
}
if subTitle != nil{
Text(LocalizedStringKey(subTitle ?? ""))
.font(style?.subTitleFont ?? Font.footnote)
.opacity(0.7)
.multilineTextAlignment(.center)
.textColor(style?.subtitleColor ?? nil)
}
}
}
}
.padding(.horizontal, 24)
.padding(.vertical, 8)
// ===========================================
// Adding a minWidth of 200, but it is still not auto sizing depending on text size.
// ===========================================
.frame(minWidth: 200, minHeight: 50)
.alertBackground(style?.backgroundColor ?? nil)
.clipShape(Capsule())
.overlay(Capsule().stroke(Color.gray.opacity(0.2), lineWidth: 1))
.shadow(color: Color.black.opacity(0.1), radius: 5, x: 0, y: 6)
.compositingGroup()
}
.padding(.top)
}
Is your feature request related to a problem? Please describe.
At the moment it is only possible to dismiss a toast by tapping on it.
Describe the solution you'd like
It would be nice if we could dismiss it by swiping (up|down) depending on where it is located on the screen.
I am trying to add a custom background to a loading alert and I am getting these errors
Cannot find 'AlertCustom' in scope
and Extra argument 'custom' in call
import AlertToast
...
let alertCustomisation = AlertCustom(
backgroundColor: Color("primary"),
titleColor: Color.red,
subTitleColor: Color.red
)
@Published var loading = AlertToast(type: .loading, title: "", custom: alertCustomisation)
Description
When the initial call to AlertToast is made, it does not clear after the default 2 seconds. Subsequent calls to AlertToast do properly clear after the duration.
This is only a problem when using the .hud
and .banner
display modes, setting displayMode: .alert
works fine.
To Reproduce
Smartphone:
Code
final class SessionManager: ObservableObject {
...
@Published var toastShow = false
@Published var toaster = AlertToast(type: .regular) {
didSet{ toastShow.toggle() }
}
...
func signIn(email: String, password: String) {
Amplify.Auth.signIn(username: email, password: password)
.resultPublisher
.sink {
if case let .failure(authError) = $0 {
DispatchQueue.main.async {
self.toaster = AlertToast(
displayMode: .hud,
type: .error(.red),
title: "Login Error",
subTitle: authError.errorDescription
)
}
}
}
....
}
@main
struct Auth2App: App {
@StateObject var sessionManager = SessionManager.shared
var body: some Scene {
WindowGroup {
switch sessionManager.authState {
case .signIn:
LoginView()
.environmentObject(sessionManager)
.toast(isPresenting: $sessionManager.toastShow){
sessionManager.toaster
}
...
}
The swiftUI default Menu style is very restrict, it is hard to custom the content style. And I find that all the open source toast don't have it.
I am a product manager learning swiftUI, so is it possible to add custom view for menu like style, and click the button shows the content view.
My thinking is pass the location of the clicked button and show the toast with the location in the toast?
Thank you so much.
when Swift Package Manager install this Package
that keep fetching for all day
other Package can installed smoothly
just this Package can't
thank you
Describe the bug
When presenting a .toast
with AlertToast.AlertType.loading
on macOS Monterey, an app crashes
To Reproduce
Steps to reproduce the behavior:
.toast
modifier to a fewtype
property to AlertToast.AlertType.loading
and title
to a string of choiceExpected behavior
I expected the above steps to produce a toast that shows a loading indicator, like on iOS and iPadOS
Desktop (please complete the following information):
I try to install manually AlertToast as per instructions, but I got error "No such module AlertToast" in Xcode 12.4.
Is there way to fix this?
This is a really cool framework but I am having problem dismissing the alert if I set duration greater than 2.0. Default setting works as expected.
This works perfectly (view diasappears after 2 seconds):
.toast(isPresenting: RM.$pendingNotifications) {
AlertToast(displayMode: .hud, type: .systemImage("exclamationmark.triangle.fill", Color.orange), title: "alert alert alert")
}
The code below does not work. With any duration above 2.0 the view appears and never disappears. It stays on top of the screen. Tap to dismiss also does not work. I also cannot influence anything with tapToDismiss:
.toast(isPresenting: RM.$pendingNotifications, duration: 3.0) {
AlertToast(displayMode: .hud, type: .systemImage("exclamationmark.triangle.fill", Color.orange), title: "alert alert alert")
}
RM is an observable object exposed to the environment and pendingNotifications is @published variable.
Describe the bug
When using AlertToast in a package, displaying a toast of displayMode type .alert neither a systemImage or Image are displayed.
To Reproduce
Steps to reproduce the behavior:
.toast(isPresenting: $showToast) {
AlertToast(displayMode: .alert, type: .systemImage("pause.circle", .red), style: .style(backgroundColor: .black))
}
Expected behavior
System image should be visible.
Screenshots
Using .hud
Desktop (please complete the following information):
Verified this works when displaying in a SwiftUI view in app not in a package.
Describe the bug
A clear and concise description of what the bug is.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
A clear and concise description of what you expected to happen.
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
Smartphone (please complete the following information):
Additional context
Add any other context about the problem here.
I'm using Swift 5.5, SwiftUI with iOS 15 and getting the following warning:
AlertToast.swift: runtime: SwiftUI: Invalid frame dimension (negative or non-finite).
This is how I have it defined:
.toast(isPresenting: $showAlert, duration: 3, alert: {
AlertToast(displayMode: .hud, type: .regular, title: self.loginMessage)
})
How can I get rid of that warning?
Describe the bug
Toast will show in wrong position with hud display mode when using it in sheet. This bug appears only in iOS
To Reproduce
Steps to reproduce the behavior:
Expected behavior
The Y Position of Toast should be much more below or even below the NavigationView (if is defined)
Smartphone:
Sample code:
import SwiftUI
import AlertToast
struct ContentView: View {
@State private var showingDetail = false
var body: some View {
Button("Show Detail") {
showingDetail.toggle()
}
.sheet(isPresented: $showingDetail) {
NextView()
}
}
}
struct NextView: View {
@State var showToast = false
var body: some View {
ScrollView {
Button("Show Detail") {
showToast.toggle()
}
.padding()
}.toast(isPresenting: $showToast, duration: 3, tapToDismiss: true, alert: {
AlertToast(
displayMode: .hud,
type: .systemImage("checkmark.circle.fill", .green),
title: "Test",
subTitle: "Some message")
})
}
}
Describe the bug
Toast truncated when it is presented from a sheet when using swiftui
To Reproduce
Steps to reproduce the behavior:
Expected behavior
Full toast must be visible
Desktop (please complete the following information):
Smartphone (please complete the following information):
Describe the bug
Invalid frame dimension (negative or non-finite).
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
Smartphone (please complete the following information):
I am able to add the package and build/run my application without errors.
Once I add the package and try to build, I get "153 issues" which are all Swift Compiler Errors
Is your feature request related to a problem? Please describe.
No
Describe the solution you'd like
I required to set my View should dim background when AlertToast type hud presented.
Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
iOS 15.5 removed the alert<Item>(item: Binding<Item?>, content: (Item) -> Alert)
modifier which was super useful to construct an Alert based on the item wrapped by the Binding.
the replacement alert(isPresented: Bool)
variants are not as powerful.
It would be really cool to add the item based modifier to AlertToast to enable a straight forward replacement. I can attempt to build it if there is interest and nobody else is working on it.
Describe the bug
A clear and concise description of what the bug is.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
A clear and concise description of what you expected to happen.
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
Smartphone (please complete the following information):
Additional context
Add any other context about the problem here.
Describe the bug
Banner subtitle line goes off the screen instead of wrapping to the next line on iOS
To Reproduce
Steps to reproduce the behavior:
Expected behavior
The subtitle should wrap to the next line
Smartphone (please complete the following information):
Is your feature request related to a problem? Please describe.
There is only a toast(isPresenting: Binding<Bool>...)
function. It is cumbersome to add multiple messages and/or multiple message types.
Describe the solution you'd like
There should be a toast<Item>(item: Binding<Item?>...)
function that allows defining the message in the item. This would be similar to several SwiftUI apis like alert(item:..). When the item changes the alert is displayed.
Describe alternatives you've considered
If we want to add multiple messages and/or have multiple message type, we must have multiple calls of toast(), or some other redundancy to allow this.
Describe the bug
If there is a navigation bar item that has a long text, the .alert toast will be displayed behind it
To Reproduce
Steps to reproduce the behavior:
Expected behavior
The AlertToast should be on top of the navigation bar items
Smartphone:
Describe the bug
A clear and concise description of what the bug is.
'animation' was deprecated in macOS 12.0: Use withAnimation or animation(_:value:) instead.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
A clear and concise description of what you expected to happen.
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
Smartphone (please complete the following information):
Additional context
Add any other context about the problem here.
I checked both article and project. No example project. I would recommend adding project used to create demo screens.
How i show the alert without using swift UI?
Describe the bug
Line overflow, so not display full text.
Code in ContentView.swift
import SwiftUI
import AlertToast
struct ContentView: View{
@State private var showToast = false
var body: some View{
VStack{
Button("Show Toast"){
showAlert.toggle()
}
}
.toast(isPresenting: $showToast){
AlertToast(type: .regular, title: "Message Sent!")
}
}
}
Then not display full text in simulator, only "Mes..." and "Hello ..."
To Reproduce
Steps to reproduce the behavior:
Expected behavior
Show full text , example "Message Sent!" and "Hello World!"
Desktop (please complete the following information):
Simulator (please complete the following information):
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.