A customizable 🍞 toast notification library for iOS, built with Swift!
- Show beautiful toast messages in your app!
- Highly customizable: colors, fonts, padding, corner radius, button, and more 🎨
- Supports positioning: top, center, or bottom 🧭
- Add a button for user interaction (optional) 🖱️
- Easy animation and auto-dismissal ⏰
- Built with UIKit, supports iOS 15+ 📱
Add ToastKit to your project using Swift Package Manager:
dependencies: [
.package(url: "https://github.com/lcaxgg/ToastKit.git", from: "1.0.0")
]Or use Xcode:
- Go to File > Add Packages...
- Enter:
https://github.com/lcaxgg/ToastKit - Add the package to your project!
let attributes = ToastAttributes(
layout: .init(contentInsets: UIEdgeInsets(top: 12.5, left: 15.0, bottom: 12.5, right: 15.0),
hStackSpacing: 16),
text: .init(message: .init(value: "message here",
font: UIFont.systemFont(ofSize: 14),
kern: 0.2,
lineBreakMode: .byTruncatingTail,
numberOfLines: 2,
minimumLineHeight: 19,
maximumLineHeight: 19)),
button: .init(text: "Button text here",
font: UIFont.systemFont(ofSize: 13),
minimumLineHeight: 19,
maximumLineHeight: 19,
isVisible: true),
timing: .init(animationDuration: 0.2,
dismissalDeadline: 3)
)
view.showToastMessage(
with: attributes,
onButtonTap: {
// do some thing here
},
onDismiss: {
// do some thing here
}
)| Simple Toast | Toast with Button |
|---|---|
|
|
private var stackingToast: StackingToastView?
func showStackingToast(message: String) {
if stackingToast == nil {
let attributes = ToastAttributes(
layout: .init(contentInsets: UIEdgeInsets(top: 12.5, left: 15, bottom: 12.5, right: 15),
hStackSpacing: 16),
text: .init(message: .init(value: message,
font: UIFont.systemFont(ofSize: 15),
kern: 0.2,
lineBreakMode: .byTruncatingTail,
numberOfLines: 2,
minimumLineHeight: 19,
maximumLineHeight: 19)),
button: .init(text: "View",
font: UIFont.systemFont(ofSize: 13.5),
minimumLineHeight: 19,
maximumLineHeight: 19,
isVisible: true),
timing: .init(animationDuration: 0.2,
dismissalDeadline: 3),
stacking: .init(count: 3,
shouldSlideOnRemoval: true,
shouldDismissAllOnButtonTap: true)
)
stackingToast = StackingToastView.make(
in: view,
attributes: attributes
)
} else {
stackingToast?.attributes.text.message.value = message
}
stackingToast?.addToast(onButtonTap: {
// do some thing here
})
stackingToast?.onDismiss = { [weak self] didRemoveAllToasts in
guard didRemoveAllToasts else { return }
self?.stackingToast = nil
}
}
showStackingToast(message: "dynamic value")| Truncated | Full |
|---|---|
|
|
Contributions, issues, and feature requests are welcome!
Feel free to check issues page.



