Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

🚨 SwiftUI alerts (and action sheets) done right

NotificationsYou must be signed in to change notification settings

rebeloper/AlertKit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

29 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

swift v5.3platform iOSdeployment target iOS 14

AlertKit is a lightweight library which makesSwiftUI alert and action sheet presentation super easy to use.

💻 Installation

📦 Swift Package Manager

UsingSwift Package Manager, add it as a Swift Package in Xcode 11.0 or later,select File > Swift Packages > Add Package Dependency... and add the repository URL:

https://github.com/rebeloper/AlertKit.git

✊ Manual Installation

Download and include theAlertKit folder and files in your codebase.

📲 Requirements

  • iOS 14+
  • Swift 5

👉 Import

ImportAlertKit into yourView

import AlertKit

🧳 Features

Here's the list of the awesome featuresAlertKit has:

  • programatic way to showAlerts in SwiftUI
  • you don't have to addAlerts as view modifiers any more
  • supportsAction Sheets
  • blends in perfectly with all other SwiftUI functioanlity and principles

😤 The Problem

InSwiftUI alerts are added as view modifiers with a bit of help from@State:

structContentView:View{@StateprivatevarisSwiftUIAlertPresented=falsevarbody:someView{VStack{Button("SwiftUI Alert"){                isSwiftUIAlertPresented=true}.alert(isPresented: $isSwiftUIAlertPresented){Alert(title:Text("SwiftUI Alert"))}Spacer()}}

This will get ugly really quickly if you're trying to add multipleAlerts on a view. Lots of@States withAlerts scattered all around your view 🤭

WithAlertKit you can invoke anAlert as simple as calling:

alertManager.show(dismiss:.success(message:"AlertKit is awesome"))

⚙️ How to use

UsingAlertKit is super simple:

  1. create a@StateObject variable ofAlertManager()
  2. add the.uses(_:) view-modifier
  3. show an alert 🤩
import AlertKitstructContentView:View{        // 1.@StateObjectvaralertManager=AlertManager()varbody:someView{VStack{Button("Show Dismiss Alert"){                // 3.                alertManager.show(dismiss:.success(message:"AlertKit is awesome"))}}.uses(alertManager) // 2.}}

1️⃣ Dismiss Alert

There are two types of alerts inSwiftUI. TheDismiss Alert is one of them. It presents an alert with:

  • title
  • message
  • one button (dismiss)
alertManager.show(dismiss:.success(message:"AlertKit is awesome"))

AlertKit comes with some predifined helpers to make your life easier. In all of the above the only variable is themeassage.Title andbutton(s) are predifined if that is the case. Of course you may override any or all of them if you wish.Important: Make sure that you use thedismiss ones with thedismiss alert and theprimarySeconday with theprimarySecoondary alert.

alertManager.show(dismiss:.custom(title:"AlertKit", message:"AlertKit is awesome", dismissButton:.cancel()))alertManager.show(dismiss:.success(message:"AlertKit is awesome"))alertManager.show(dismiss:.error(message:"AlertKit is awesome"))alertManager.show(dismiss:.warning(message:"AlertKit is awesome"))alertManager.show(dismiss:.info(message:"AlertKit is awesome"))

2️⃣ PrimarySecondary Alert

The second type of alert displayes two buttons (instead of one):

  • title
  • message
  • two buttons (primary and secondary)

Here are the ways you may call it:

alertManager.show(primarySecondary:.custom(title:"AlertKit", message:"AlertKit is awesome", primaryButton:Alert.Button.destructive(Text("OK")), secondaryButton:Alert.Button.cancel()))alertManager.show(primarySecondary:.success(title:"AlertKit", message:"AlertKit is awesome", primaryButton:Alert.Button.destructive(Text("OK")), secondaryButton:Alert.Button.cancel()))alertManager.show(primarySecondary:.error(title:"AlertKit", message:"AlertKit is awesome", primaryButton:Alert.Button.destructive(Text("OK")), secondaryButton:Alert.Button.cancel()))alertManager.show(primarySecondary:.warning(title:"AlertKit", message:"AlertKit is awesome", primaryButton:Alert.Button.destructive(Text("OK")), secondaryButton:Alert.Button.cancel()))alertManager.show(primarySecondary:.info(title:"AlertKit", message:"AlertKit is awesome", primaryButton:Alert.Button.destructive(Text("OK")), secondaryButton:Alert.Button.cancel()))

⬆️ Action Sheet

Wantmore than two buttons on theAlert? Well, you will have to use anAction Sheet:

Button("Show Action Sheet"){letbuttons:[ActionSheet.Button]=[.destructive(Text("Do some work"), action:{fetchData()}),.default(Text("Nothing")),.cancel()]    alertManager.showActionSheet(.custom(title:"Action Sheet", message:"What do you want to do next?", buttons: buttons))}...func fetchData{...}

Note that you can use all of theAlert.Buttons SwiftUI provides. Here I'm using adestructive withaction button and have wrapped the actual work into a seperatefetchData() function. Cleaner code 👌

🤖 View Model

Speaking of clean code... I highly recommend using aview model for your view. Here's mine that is simulating fetching some data by simply letting time pass:

////  ContentViewModel.swift//import SwiftUIclassContentViewModel:ObservableObject{func fetchData(completion:@escaping(Result<Bool,Error>)->()){DispatchQueue.global(qos:.background).asyncAfter(deadline:.now()+4){DispatchQueue.main.async{                // completion(.success(true))completion(.success(false))                // completion(.failure(NSError(domain: "Could not fetch data", code: 404, userInfo: nil)))}}}}

And in myContentView I'm using it like so:

////  ContentView.swift//import SwiftUIimport AlertKitstructContentView:View{@StateObjectvaralertManager=AlertManager()@ObservedObjectprivatevarviewModel=ContentViewModel()varbody:someView{VStack{...}.uses(alertManager).onAppear{fetchData()}}func fetchData(){        // to see all cases please modify the Result in ContentViewModelself.viewModel.fetchData{(result)inswitch result{case.success(let finished):if finished{                    alertManager.show(dismiss:.info(message:"Successfully fetched data", dismissButton:Alert.Button.default(Text("Alright"))))}else{                    alertManager.show(primarySecondary:.error(title:"🤔", message:"Something went wrong", primaryButton:Alert.Button.default(Text("Try again"), action:{fetchData()}), secondaryButton:.cancel()))}case.failure(let err):                alertManager.show(dismiss:.error(message: err.localizedDescription))}}}}

🎨 Custom Alert

Custom alerts are different as they have a few more steps to set up.

  1. Declare one ore moreCustomAlertManagers:
@StateObjectvarcustomAlertManager=CustomAlertManager()@StateObjectvarcustomAlertManager2=CustomAlertManager()

You have to declare one for each custom alert that you want to present.

  1. Optionally, if you are usingTextFields you have to set a@State variable that will hold the text value
@StateprivatevarcustomAlertText:String=""
  1. Set up the custom alert on the root View:
VStack{...}.customAlert(manager: customAlertManager, content:{VStack{Text("Hello Custom Alert").bold()TextField("Enter email", text: $customAlertText).textFieldStyle(RoundedBorderTextFieldStyle())}}, buttons:[.cancel(content:{Text("Cancel").bold()}),.regular(content:{Text("Send")}, action:{print("Sending email:\(customAlertText)")})])

You may add anyView as thecontent of your custom alert. You have two button types:

  • .regular has an action; it dismisses the alert with that action
  • .cancel has only content andno action; it dismisses the alert without any action
.customAlert(manager: customAlertManager2, content:{VStack(spacing:12){Text("Hello Custom Alert 2").bold()Text("Some message here")}}, buttons:[.regular(content:{Text("Go")}, action:{print("Go")}),.cancel(content:{Image(systemName:"bell.slash.fill").resizable().frame(width:33, height:33).foregroundColor(Color(.systemPurple))}),.cancel(content:{Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.").bold()})])

IMPORTANT: You must provide at least one button!

  1. Triger the custom alert(s):
VStack{...Button(action:{        customAlertManager.show()}, label:{Text("Show custom alert")})Button(action:{        customAlertManager2.show()}, label:{Text("Show custom alert 2")})}

🪁 Demo project

For a comprehensive Demo project check out:AlertKitDemo

✍️ Contact

rebeloper.com /YouTube /Shop /Mentoring

📃 License

The MIT License (MIT)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Packages

No packages published

Contributors4

  •  
  •  
  •  
  •  

Languages


[8]ページ先頭

©2009-2026 Movatter.jp