1675617086
Emerge Alert Dialog
An emerge alert dialog package is allows developers to easily create and display alert dialogs with custom animations. Emerge dialogs are used to display important information or messages to the user and often include a call to action, such as a button to confirm or dismiss the dialog.
In the context of the Emerge framework, an Alert Dialog is a type of dialog box that can be used to display an alert message or to prompt the user for a response within the context of an Emerge application.
To use this package :
dependencies:
emerge_alert_dialog: ^0.0.3
Future<void> _showMyDialog(BuildContext context) async {
return showDialog<void>(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return EmergeAlertDialog(
alignment: Alignment.bottomCenter,
emergeAlertDialogOptions: EmergeAlertDialogOptions(
title: const Text("Privacy Info"),
),
);
},
);
}
![]() | ![]() |
Run this command:
With Flutter:
$ flutter pub add emerge_alert_dialog
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
emerge_alert_dialog: ^0.0.3
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:emerge_alert_dialog/emerge_alert_dialog.dart';
import 'package:emerge_pop_up_example/home_screen.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Emerge Alert Dialog',
theme: ThemeData(
primarySwatch: Colors.red,
),
home: const HomeScreen(),
);
}
}
Download Details:
Author: champ96k
Source Code: https://github.com/champ96k/emerge_alert_dialog
1675611607
cool_alert_two
A Flutter package to display animated alert dialogs.
NOTE: this is a forked version of the original cool_alert plugin which was no longer being actively maintained at the time of writing!
Cool Alert Two includes various bug fixes and improvements that I use in my own projects and which I am aiming to maintain as a public fork. Feel free to contribute!
To use this package, add cool_alert_two as a dependency in your pubspec.yaml file. And add this import to your file.
import 'package:cool_alert_two/cool_alert_two.dart';
CoolAlertTwo.show(
context: context,
type: CoolAlertType.success,
text: "Your transaction was successful!",
);
Attribute | Data type | Description | Default Value |
---|---|---|---|
context | BuildContext | @required | Null |
type | CoolAlertType | @required - Type of alert dialog, ex: CoolAlertType.success for success dialogs | Null |
title | String | Set a custom title for dialog | Based on the CoolAlertType selected |
text | String | Set the description text of the dialog. | Null |
widget | Widget | Set any you expect widget of the dialog. | Null |
confirmBtnText | String | Text of confirm button | 'Ok' |
confirmBtnTap | Function | Function that handle click of confirm button | () => Navigator.pop(context) |
confirmBtnColor | Color | Color of confirm Button | Theme.of(context).primaryColor |
cancelBtnText | String | Text of cancel button | 'Cancel' |
cancelBtnTap | Function | Function that handle click of cancel button | () => Navigator.pop(context) |
barrierDismissible | bool | Dismiss dialog on touch overlay | true |
animType | CoolAlertAnimType | Type of dialogue enter animation | CoolAlertAnimType.scale |
backgroundColor | Color | Background color of the animation | Color(0xFF515C6F) |
confirmBtnTextStyle | TextStyle | Confirm button text theme | TextStyle(color: Colors.white, fontWeight:FontWeight.w600,fontSize: 18.0) |
cancelBtnTextStyle | TextStyle | Cancel button text theme | TextStyle(color: Colors.grey, fontWeight:FontWeight.w600,fontSize: 18.0) |
flareAsset | String | Custom flare asset | "animation.flr" |
flareAnimationName | String | The name of the flare animation to play | "play" |
lottieAsset | String | Custom lottie asset | "animation.json" |
autoCloseDuration | Duration | Determines how long the dialog stays open for before closing | Null |
width | double | Dialog width | MediaQuery.of(context).size.width |
loopAnimation | boolean | Determines if the animation should loop or not | false |
Run this command:
With Flutter:
$ flutter pub add cool_alert_two
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
cool_alert_two: ^0.1.0
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:cool_alert_two/cool_alert_two.dart';
import 'package:cool_alert_two/cool_alert_two.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Cool Alert',
theme: ThemeData(
primarySwatch: Colors.blue,
fontFamily: GoogleFonts.poppins().fontFamily,
),
home: MyHomePage(title: 'Cool Alert'),
debugShowCheckedModeBanner: false,
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, this.title}) : super(key: key);
final String? title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
final successAlert = _buildButton(
onTap: () {
CoolAlertTwo.show(
context: context,
type: CoolAlertTwoType.success,
text: 'Transaction completed successfully!',
autoCloseDuration: Duration(seconds: 2),
);
},
text: 'Success',
color: Colors.green,
);
final errorAlert = _buildButton(
onTap: () {
CoolAlertTwo.show(
context: context,
type: CoolAlertTwoType.error,
title: 'Oops...',
text: 'Sorry, something went wrong',
loopAnimation: false,
);
},
text: 'Error',
color: Colors.red,
);
final warningAlert = _buildButton(
onTap: () {
CoolAlertTwo.show(
context: context,
type: CoolAlertTwoType.warning,
text: 'You just broke protocol',
);
},
text: 'Warning',
color: Colors.orange,
);
final infoAlert = _buildButton(
onTap: () {
CoolAlertTwo.show(
context: context,
type: CoolAlertTwoType.info,
text: 'Buy two, get one free',
);
},
text: 'Info',
color: Colors.blue[100],
);
final confirmAlert = _buildButton(
onTap: () {
CoolAlertTwo.show(
context: context,
type: CoolAlertTwoType.confirm,
text: 'Do you want to logout',
confirmBtnText: 'Yes',
cancelBtnText: 'No',
confirmBtnColor: Colors.green,
);
},
text: 'Confirm',
color: Colors.lightGreen,
);
final loadingAlert = _buildButton(
onTap: () {
CoolAlertTwo.show(
context: context,
type: CoolAlertTwoType.loading,
);
},
text: 'Loading',
color: Colors.grey,
);
final customAlert = _buildButton(
onTap: () {
var _message = '';
CoolAlertTwo.show(
context: context,
type: CoolAlertTwoType.custom,
barrierDismissible: true,
confirmBtnText: 'Save',
widget: TextFormField(
decoration: InputDecoration(
hintText: 'Enter Phone Number',
prefixIcon: Icon(
Icons.phone_outlined,
),
),
textInputAction: TextInputAction.next,
keyboardType: TextInputType.phone,
onChanged: (value) => _message = value,
),
onConfirmBtnTap: () async {
if (_message.length < 5) {
await CoolAlertTwo.show(
context: context,
type: CoolAlertTwoType.error,
text: 'Please input something',
);
return;
}
Navigator.pop(context);
await Future.delayed(Duration(milliseconds: 1000));
await CoolAlertTwo.show(
context: context,
type: CoolAlertTwoType.success,
text: "Phone number '$_message' has been saved!.",
);
},
);
},
text: 'Custom',
color: Colors.orange,
);
return Scaffold(
appBar: AppBar(
title: Text(widget.title!),
),
body: SingleChildScrollView(
padding: EdgeInsets.all(20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
successAlert,
errorAlert,
warningAlert,
infoAlert,
confirmAlert,
loadingAlert,
customAlert,
],
),
),
);
}
Widget _buildButton({VoidCallback? onTap, required String text, Color? color}) {
return Padding(
padding: const EdgeInsets.only(bottom: 10.0),
child: MaterialButton(
color: color,
minWidth: double.infinity,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
),
onPressed: onTap,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 15.0),
child: Text(
text,
style: TextStyle(
color: Colors.white,
),
),
),
),
);
}
}
Download Details:
Author: matwright
Source Code: https://github.com/matwright/flutter_cool_alert_two
1673923860
FFPopup is a lightweight library for presenting custom views as a popup.
Support several popup show types
Support several popup dismiss types
Layout the popup in the horizontal direction
Layout the popup in the vertical direction
Controlled whether to allow interaction with the underlying view
Others
Bounce from Top & Bounce to Bottom | Bounce from Top & Bounce to Top | Bounce in & Bounce out | Grow in & Shrink out | Bounce from Bottom & Slide to Bottom | Slide from Bottom & Slide to Bottom |
---|---|---|---|---|---|
![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
To run the FFPopup
project, clone the Repo, and start FFPopup
in Xcode.
$ git clone https://github.com/JonyFang/FFPopup.git
$ cd FFPopup
$ cd Shell && sh install-bundle.sh && sh install-pods.sh && cd ..
$ open FFPopup.xcworkspace
There are three ways to use FFPopup
in your project:
CocoaPods
Carthage
Manually
installCocoaPods is a dependency manager, which automates and simplifies the process of using 3rd-party libraries like FFPopup
in your projects. First, add the following line to your Podfile:
pod 'FFPopup'
If you want to use the latest features of FFPopup
use normal external source dependencies.
pod 'FFPopup', :git => 'https://github.com/JonyFang/FFPopup.git'
This pulls from the master branch directly.
Second, install FFPopup
into your project:
$ pod install
Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.
You can install Carthage with Homebrew using the following command:
$ brew update
$ brew install carthage
To integrate FFPopup
into your Xcode project using Carthage, specify it in your Cartfile
:
github "JonyFang/FFPopup"
Run the following command to build the framework:
$ carthage update
Drag the built FFPopup.framework
binaries from Carthage/Build/iOS
into your application’s Xcode project.
On your application targets’ Build Phases
settings tab, click the + icon
and choose New Run Script Phase
. Create a Run Script
in which you specify your shell (ex: /bin/sh
), add the following contents to the script area below the shell:
/usr/local/bin/carthage copy-frameworks
Add the following paths to the frameworks you want to use under Input Files
.
$(SRCROOT)/Carthage/Build/iOS/FFPopup.framework
For an in depth guide, read on from Adding frameworks to an application
Alternatively you can directly add the FFPopup.h
and FFPopup.m
source files to your project.
FFPopup.h
and FFPopup.m
onto your project (use the "Product Navigator view"
). Make sure to select Copy items
when asked if you extracted the code archive outside of your project.FFPopup
wherever you need it with #import "FFPopup.h"
.Even though FFPopup
is written in Objective-C, it can be used in Swift with no hassle. If you use CocoaPods add the following line to your Podfile:
use_frameworks!
If you added FFPopup
manually, just add a bridging header file to your project with the FFPopup
header included.
Import the library where you want to use it.
#import <FFPopup.h>
- (void)showPopup {
FFPopup *popup = [FFPopup popupWithContentView:self.contentView showType:FFPopupShowType_BounceIn dismissType:FFPopupDismissType_ShrinkOut maskType:FFPopupMaskType_Dimmed dismissOnBackgroundTouch:YES dismissOnContentTouch:NO];
FFPopupLayout layout = FFPopupLayoutMake(FFPopupHorizontalLayout_Center, FFPopupVerticalLayout_Center);
[popup showWithLayout:layout];
}
import FFPopup
func showPopup() {
let popup = FFPopup(contentView: self.contentView, showType: .bounceIn, dismissType: .shrinkOut, maskType: .dimmed, dismissOnBackgroundTouch: true, dismissOnContentTouch: false)
let layout = FFPopupLayout(horizontal: .center, vertical: .center)
popup.show(layout: layout)
}
Animation transition for presenting contentView. Controlled how the popup will be presented.
The default value is FFPopupShowType_BounceInFromTop
.
FFPopupShowType |
---|
FFPopupShowType_None |
FFPopupShowType_FadeIn |
FFPopupShowType_GrowIn |
FFPopupShowType_ShrinkIn |
FFPopupShowType_SlideInFromTop |
FFPopupShowType_SlideInFromBottom |
FFPopupShowType_SlideInFromLeft |
FFPopupShowType_SlideInFromRight |
FFPopupShowType_BounceIn |
FFPopupShowType_BounceInFromTop |
FFPopupShowType_BounceInFromBottom |
FFPopupShowType_BounceInFromLeft |
FFPopupShowType_BounceInFromRight |
Animation transition for dismissing contentView. Controlled how the popup will be dismissed.
The default value is FFPopupDismissType_BounceOutToBottom
.
FFPopupDismissType |
---|
FFPopupDismissType_None |
FFPopupDismissType_FadeOut |
FFPopupDismissType_GrowOut |
FFPopupDismissType_ShrinkOut |
FFPopupDismissType_SlideOutToTop |
FFPopupDismissType_SlideOutToBottom |
FFPopupDismissType_SlideOutToLeft |
FFPopupDismissType_SlideOutToRight |
FFPopupDismissType_BounceOut |
FFPopupDismissType_BounceOutToTop |
FFPopupDismissType_BounceOutToBottom |
FFPopupDismissType_BounceOutToLeft |
FFPopupDismissType_BounceOutToRight |
Mask prevents background touches from passing to underlying views. Controlled whether to allow interaction with the underlying view.
The default value is FFPopupMaskType_Dimmed
.
FFPopupMaskType |
---|
FFPopupMaskType_None |
FFPopupMaskType_Clear |
FFPopupMaskType_Dimmed |
Property Name | Description | Default Value |
---|---|---|
dimmedMaskAlpha | Overrides alpha value for dimmed mask. | 0.5 |
showInDuration | Overrides animation duration for show in. | 0.15 |
dismissOutDuration | Overrides animation duration for dismiss out. | 0.15 |
shouldDismissOnBackgroundTouch | If YES , the popup will dismiss when background is touched. | YES |
shouldDismissOnContentTouch | If YES , the popup will dismiss when content view is touched. | NO |
/**
A block to be executed when showing animation started.
The default value is nil.
*/
@property (nonatomic, copy, nullable) void(^willStartShowingBlock)(void);
/**
A block to be executed when showing animation finished.
The default value is nil.
*/
@property (nonatomic, copy, nullable) void(^didFinishShowingBlock)(void);
/**
A block to be executed when dismissing animation started.
The default value is nil.
*/
@property (nonatomic, copy, nullable) void(^willStartDismissingBlock)(void);
/**
A block to be executed when dismissing animation finished.
The default value is nil.
*/
@property (nonatomic, copy, nullable) void(^didFinishDismissingBlock)(void);
Create a new popup with custom values.
/**
Convenience Initializers
Create a new popup with `contentView`.
*/
+ (FFPopup *)popupWithContentView:(UIView *)contentView;
/**
Convenience Initializers
Create a new popup with custom values.
@param contentView The view you want to appear in popup.
@param showType The default value is `FFPopupShowType_BounceInFromTop`.
@param dismissType The default value is `FFPopupDismissType_BounceOutToBottom`.
@param maskType The default value is `FFPopupMaskType_Dimmed`.
@param shouldDismissOnBackgroundTouch The default value is `YES`.
@param shouldDismissOnContentTouch The default value is `NO`.
*/
+ (FFPopup *)popupWithContentView:(UIView *)contentView
showType:(FFPopupShowType)showType
dismissType:(FFPopupDismissType)dismissType
maskType:(FFPopupMaskType)maskType
dismissOnBackgroundTouch:(BOOL)shouldDismissOnBackgroundTouch
dismissOnContentTouch:(BOOL)shouldDismissOnContentTouch;
/**
Show popup with center layout.
`FFPopupVerticalLayout_Center` & `FFPopupHorizontalLayout_Center`
Showing animation is determined by `showType`.
*/
- (void)show;
/**
Show popup with specified layout.
Showing animation is determined by `showType`.
*/
- (void)showWithLayout:(FFPopupLayout)layout;
/**
Show and then dismiss popup after `duration`.
If duration is `0.0` or `less`, it will be considered infinity.
*/
- (void)showWithDuration:(NSTimeInterval)duration;
/**
Show popup with specified `layout` and then dismissed after `duration`.
If duration is `0.0` or `less`, it will be considered infinity.
*/
- (void)showWithLayout:(FFPopupLayout)layout duration:(NSTimeInterval)duration;
/**
Show popup at point in view's coordinate system.
If view is nil, will use screen base coordinates.
*/
- (void)showAtCenterPoint:(CGPoint)point inView:(UIView *)view;
/**
Show popup at point in view's coordinate system and then dismissed after duration.
If view is nil, will use screen base coordinates.
If duration is `0.0` or `less`, it will be considered infinity.
*/
- (void)showAtCenterPoint:(CGPoint)point inView:(UIView *)view duration:(NSTimeInterval)duration;
/**
Dismiss popup.
Use `dismissType` if animated is `YES`.
*/
- (void)dismissAnimated:(BOOL)animated;
/**
Dismiss all the popups in the app.
*/
+ (void)dismissAllPopups;
/**
Dismiss the popup for contentView.
*/
+ (void)dismissPopupForView:(UIView *)view animated:(BOOL)animated;
/**
Dismiss super popup.
Iterate over superviews until you find a `FFPopup` and dismiss it.
*/
+ (void)dismissSuperPopupIn:(UIView *)view animated:(BOOL)animated;
This is the to-do list for the FFPopup
project. You can join us to become a contributor.
See the CONTRIBUTING file for contributing guidelines.
My app Time Card -Countdown (Never Forget Important Days) is using FFPopup
. You can download it and try it on your multiple devices to experience the effect.
Author: JonyFang
Source Code: https://github.com/JonyFang/FFPopup
License: MIT license
1673653500
StatusAlert is being sponsored by the following tool; please help to support us by takin a look and signing up to a free trial.
StatusAlert is an iOS framework that displays status alerts similar to Apple's system self-hiding alerts. It is well suited for notifying user without interrupting user flow in iOS-like way.
It looks very similar to the alerts displayed in Podcasts, Apple Music and News apps.
To install StatusAlert using CocoaPods, add the following line to your Podfile
:
pod 'StatusAlert', '~> 1.1.1'
To install StatusAlert using Carthage, add the following line to your Cartfile
:
github "LowKostKustomz/StatusAlert" ~> 1.1.1
To install StatusAlert using Swift Package Manager add this to your dependencies in a Package.swift
file:
dependencies: [
.package(url: "https://github.com/LowKostKustomz/StatusAlert.git", .exact("1.1.1"))
]
You can also add this project:
StatusAlert is fully compatible with Objective-C. To import it to your project just add the following line:
@import StatusAlert;
Demo application is included in the StatusAlert
workspace. To run it clone the repo.
// Importing framework
import StatusAlert
// Creating StatusAlert instance
let statusAlert = StatusAlert()
statusAlert.image = UIImage(named: "Some image name")
statusAlert.title = "StatusAlert title"
statusAlert.message = "Message to show beyond title"
statusAlert.canBePickedOrDismissed = isUserInteractionAllowed
// Presenting created instance
statusAlert.showInKeyWindow()
All the alert components (
image
,title
,message
) are optional, but at least one should be present. Otherwiseshow()
method will be ignored.IMPORTANT
The alert must be presented only from the main thread, otherwise application will crash with an appropriate error.
Wiki with more content and examples available
Present alert with any set of image, title and message
Display alert anywhere you want, either on the top, in the center or at the bottom of the view, and with any offset.
You can customize a single alert's appearance via the StatusAlert
's appearance
property or for all alerts at once with StatusAlert.Appearance
's common
property
var titleFont: UIFont
var messageFont: UIFont
var tintColor: UIColor
var backgroundColor: UIColor
var blurStyle: UIBlurEffect.Style
Alert will hide itself after 2 seconds timeout.
You can change alert showing duration by setting alertShowingDuration
property. You also can set canBePickedOrDismissed
property to true
. After that you will be able to dismiss the alert manually by tapping it and delay dismissal by long tapping the alert.
Feel free to submit pull request if you are using this framework in your apps.
Author: LowKostKustomz
Source Code: https://github.com/LowKostKustomz/StatusAlert
License: MIT license
1673170080
A library to present popovers.
.popover
.Menu
that works on iOS 13.Alert | Color | Menu | Tip | Standard |
![]() | ![]() | ![]() | ![]() | ![]() |
Tutorial | Picture-in-Picture | Notification | ||
![]() | ![]() | ![]() |
Includes ~20 popover examples. Download
Requires iOS 13+. Popovers can be installed through the Swift Package Manager (recommended) or Cocoapods.
Swift Package Manager Add the Package URL: | Cocoapods Add this to your Podfile: |
|
|
To present a popover in SwiftUI, use the .popover(present:attributes:view)
modifier. By default, the popover uses its parent view as the source frame.
import SwiftUI
import Popovers
struct ContentView: View {
@State var present = false
var body: some View {
Button("Present popover!") {
present = true
}
.popover(present: $present) { /// here!
Text("Hi, I'm a popover.")
.padding()
.foregroundColor(.white)
.background(.blue)
.cornerRadius(16)
}
}
}
In UIKit, create a Popover
instance, then present with UIViewController.present(_:)
. You should also set the source frame.
import SwiftUI
import Popovers
class ViewController: UIViewController {
@IBOutlet weak var button: UIButton!
@IBAction func buttonPressed(_ sender: Any) {
var popover = Popover { PopoverView() }
popover.attributes.sourceFrame = { [weak button] in
button.windowFrame()
}
present(popover) /// here!
}
}
struct PopoverView: View {
var body: some View {
Text("Hi, I'm a popover.")
.padding()
.foregroundColor(.white)
.background(.blue)
.cornerRadius(16)
}
}
Customize popovers through the Attributes
struct. Pretty much everything is customizable, including positioning, animations, and dismissal behavior.
SwiftUI Configure in the attributes parameter. | UIKit Modify the attributes property. |
|
|
AnyHashable?
Tag popovers to access them later from anywhere. This is useful for updating existing popovers.
/// Set the tag.
$0.tag = "Your Tag"
/// Access it later.
let popover = popover(tagged: "Your Tag") /// Where `self` is a `UIView` or `UIViewController`.
/// If inside a SwiftUI View, use a `WindowReader`:
WindowReader { window in
let popover = window.popover(tagged: "Your Tag")
}
Note: When you use the .popover(selection:tag:attributes:view:)
modifier, this tag
is automatically set to what you provide in the parameter.
Position
The popover's position can either be .absolute
(attached to a view) or .relative
(picture-in-picture). The enum's associated value additionally configures which sides and corners are used.
Anchor
s represent sides and corners..absolute
, provide the origin anchor and popover anchor..relative
, provide the popover anchors. If there's multiple, the user will be able to drag between them like a PIP.Anchor Reference | .absolute(originAnchor: .bottom, popoverAnchor: .topLeft) | .relative(popoverAnchors: [.right]) |
---|---|---|
![]() | ![]() | ![]() |
(() -> CGRect)
This is the frame that the popover attaches to or is placed within, depending on its position. This must be in global window coordinates. Because frames are can change so often, this property is a closure. Whenever the device rotates or some other bounds update happens, the closure will be called.
SwiftUI By default, the source frame is automatically set to the parent view. Setting this will override it. | UIKit It's highly recommended to provide a source frame, otherwise the popover will appear in the top-left of the screen. |
|
|
UIEdgeInsets
Edge insets to apply to the source frame. Positive values inset the frame, negative values expand it.
UIEdgeInsets
Global insets for all popovers to prevent them from overflowing off the screen. Kind of like a safe area. Default value is UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)
.
Presentation
This property stores the animation and transition that's applied when the popover appears.
/// Default values:
$0.presentation.animation = .easeInOut
$0.presentation.transition = .opacity
Dismissal
This property stores the popover's dismissal behavior. There's a couple sub-properties here.
/// Same thing as `Presentation`.
$0.dismissal.animation = .easeInOut
$0.dismissal.transition = .opacity
/// Advanced stuff! Here's their default values:
$0.dismissal.mode = .tapOutside
$0.dismissal.tapOutsideIncludesOtherPopovers = false
$0.dismissal.excludedFrames = { [] }
$0.dismissal.dragMovesPopoverOffScreen = true
$0.dismissal.dragDismissalProximity = CGFloat(0.25)
Mode: Configure how the popover should auto-dismiss. You can have multiple at the same time!
.tapOutside
- dismiss the popover when the user taps outside it..dragDown
- dismiss the popover when the user drags it down..dragUp
- dismiss the popover when the user drags it up..none
- don't automatically dismiss the popover.Tap Outside Includes Other Popovers: Only applies when mode
is .tapOutside
. If this is enabled, the popover will be dismissed when the user taps outside, even when another presented popover is what's tapped. Normally when you tap another popover that's presented, the current one will not dismiss.
Excluded Frames: Only applies when mode
is .tapOutside
. When the user taps outside the popover, but the tap lands on one of these frames, the popover will stay presented. If you want multiple popovers, you should set the source frames of your other popovers as the excluded frames.
/// Set one popover's source frame as the other's excluded frame.
/// This prevents the the current popover from being dismissed before animating to the other one.
let popover1 = Popover { Text("Hello") }
popover1.attributes.sourceFrame = { [weak button1] in button1.windowFrame() }
popover1.attributes.dismissal.excludedFrames = { [weak button2] in [ button2.windowFrame() ] }
let popover2 = Popover { Text("Hello") }
popover2.attributes.sourceFrame = { [weak button2] in button2.windowFrame() }
popover2.attributes.dismissal.excludedFrames = { [weak button1] in [ button1.windowFrame() ] }
Drag Moves Popover Off Screen: Only applies when mode
is .dragDown
or .dragUp
. If this is enabled, the popover will continue moving off the screen after the user drags.
Drag Dismissal Proximity: Only applies when mode
is .dragDown
or .dragUp
. Represents the point on the screen that the drag must reach in order to auto-dismiss. This property is multiplied by the screen's height.
RubberBandingMode
Configures which axes the popover can "rubber-band" on when dragged. The default is [.xAxis, .yAxis]
.
.xAxis
- enable rubber banding on the x-axis..yAxis
- enable rubber banding on the y-axis..none
- disable rubber banding.Bool
Set this to true to prevent underlying views from being pressed.
Accessibility
• v1.2.0
Popovers is fully accessible! The Accessibility
struct provides additional options for how VoiceOver should read out content.
/// Default values:
$0.accessibility.shiftFocus = true
$0.accessibility.dismissButtonLabel = defaultDismissButtonLabel /// An X icon wrapped in `AnyView?`
Shift Focus: If enabled, VoiceOver will focus the popover as soon as it's presented.
Dismiss Button Label: A button next to the popover that appears when VoiceOver is on. By default, this is an X circle.
![]() |
---|
Tip: You can also use the accessibility escape gesture (a 2-fingered Z-shape swipe) to dismiss all popovers.
(() -> Void)?
A closure that's called whenever the user taps outside the popover.
(() -> Void)?
A closure that's called when the popover is dismissed.
((Context) -> Void)?
A closure that's called whenever the context changed. The context contains the popover's attributes, current frame, and other visible traits.
Popovers comes with some features to make your life easier.
New in v1.3.0! The template Menu
looks and behaves pretty much exactly like the system menu, but also works on iOS 13. It's also extremely customizable with support for manual presentation and custom views.
![]() |
---|
SwiftUI (Basic)
struct ContentView: View {
var body: some View {
Templates.Menu {
Templates.MenuButton(title: "Button 1", systemImage: "1.circle.fill") { print("Button 1 pressed") }
Templates.MenuButton(title: "Button 2", systemImage: "2.circle.fill") { print("Button 2 pressed") }
} label: { fade in
Text("Present Menu!")
.opacity(fade ? 0.5 : 1)
}
}
}
SwiftUI (Customized)
Templates.Menu(
configuration: {
$0.width = 360
$0.backgroundColor = .blue.opacity(0.2)
}
) {
Text("Hi, I'm a menu!")
.padding()
Templates.MenuDivider()
Templates.MenuItem {
print("Item tapped")
} label: { fade in
Color.clear.overlay(
AsyncImage(url: URL(string: "https://getfind.app/image.png")) {
$0.resizable().aspectRatio(contentMode: .fill)
} placeholder: {
Color.clear
}
)
.frame(height: 180)
.clipped()
.opacity(fade ? 0.5 : 1)
}
} label: { fade in
Text("Present Menu!")
.opacity(fade ? 0.5 : 1)
}
SwiftUI (Manual Presentation)
struct ContentView: View {
@State var present = false
var body: some View {
VStack {
Toggle("Activate", isOn: $present)
.padding()
.background(.regularMaterial)
.cornerRadius(12)
.padding()
Templates.Menu(present: $present) {
Templates.MenuButton(title: "Button 1", systemImage: "1.circle.fill") { print("Button 1 pressed") }
Templates.MenuButton(title: "Button 2", systemImage: "2.circle.fill") { print("Button 2 pressed") }
} label: { fade in
Text("Present Menu!")
.opacity(fade ? 0.5 : 1)
}
}
}
}
UIKit (Basic)
class ViewController: UIViewController {
@IBOutlet var label: UILabel!
lazy var menu = Templates.UIKitMenu(sourceView: label) {
Templates.MenuButton(title: "Button 1", systemImage: "1.circle.fill") { print("Button 1 pressed") }
Templates.MenuButton(title: "Button 2", systemImage: "2.circle.fill") { print("Button 2 pressed") }
} fadeLabel: { [weak self] fade in
self?.label.alpha = fade ? 0.5 : 1
}
override func viewDidLoad() {
super.viewDidLoad()
_ = menu /// Create the menu.
}
}
UIKit (Customized)
class ViewController: UIViewController {
@IBOutlet var label: UILabel!
lazy var menu = Templates.UIKitMenu(
sourceView: label,
configuration: {
$0.width = 360
$0.backgroundColor = .blue.opacity(0.2)
}
) {
Text("Hi, I'm a menu!")
.padding()
Templates.MenuDivider()
Templates.MenuItem {
print("Item tapped")
} label: { fade in
Color.clear.overlay(
AsyncImage(url: URL(string: "https://getfind.app/image.png")) {
$0.resizable().aspectRatio(contentMode: .fill)
} placeholder: {
Color.clear
}
)
.frame(height: 180)
.clipped()
.opacity(fade ? 0.5 : 1)
}
} fadeLabel: { [weak self] fade in
UIView.animate(withDuration: 0.15) {
self?.label.alpha = fade ? 0.5 : 1
}
}
override func viewDidLoad() {
super.viewDidLoad()
_ = menu /// Create the menu.
}
}
UIKit (Manual Presentation)
class ViewController: UIViewController {
/// ...
@IBAction func switchPressed(_ sender: UISwitch) {
if menu.isPresented {
menu.dismiss()
} else {
menu.present()
}
}
}
As long as the view structure is the same, you can smoothly transition from one popover to another.
SwiftUI Use the .popover(selection:tag:attributes:view:) modifier. | UIKit Get the existing popover using UIResponder.popover(tagged:) , then call UIResponder.replace(_:with:) . |
|
|
![]() |
---|
You can put anything in a popover's background.
SwiftUI Use the .popover(present:attributes:view:background:) modifier. | UIKit Use the Popover(attributes:view:background:) initializer. |
|
|
This reads the popover's context, which contains its frame, window, attributes, and various other properties. It's kind of like GeometryReader
, but cooler. You can put it in the popover's view or its background.
.popover(present: $present) {
PopoverView()
} background: {
PopoverReader { context in
Path {
$0.move(to: context.frame.point(at: .bottom))
$0.addLine(to: context.windowBounds.point(at: .bottom))
}
.stroke(Color.blue, lineWidth: 4)
}
}
![]() |
---|
Popovers includes a mechanism for tagging and reading SwiftUI view frames. You can use this to provide a popover's sourceFrame
or excludedFrames
. Also works great when combined with PopoverReader
, for connecting lines with anchor views.
Text("This is a view")
.frameTag("Your Tag Name") /// Adds a tag inside the window.
/// ...
WindowReader { window in
Text("Click me!")
.popover(
present: $present,
attributes: {
$0.sourceFrame = window.frameTagged("Your Tag Name") /// Retrieves a tag from the window.
}
)
}
Get started quickly with some templates. All of them are inside Templates
with example usage in the example app.
AlertButtonStyle
- a button style resembling a system alert.VisualEffectView
- lets you use UIKit blurs in SwiftUI.Container
- a wrapper view for the BackgroundWithArrow
shape.Shadow
- an easier way to apply shadows.BackgroundWithArrow
- a shape with an arrow that looks like the system popover.CurveConnector
- an animatable shape with endpoints that you can set.Menu
- the system menu, but built from scratch.If you directly pass a variable down to the popover's view, it might not update. Instead, move the view into its own struct and pass down a Binding
.
Yes The popover's view is in a separate struct, with $string passed down. | No The button is directly inside the view parameter and receives string . |
|
|
v1.1.0
Popovers comes with built-in support for multiple screens, but retrieving frame tags requires a reference to the hosting window. You can get this via WindowReader
or PopoverReader
's context.
WindowReader { window in
}
/// If inside a popover's `view` or `background`, use `PopoverReader` instead.
PopoverReader { context in
let window = context.window
}
Manage a popover's z-axis level by attaching .zIndex(_:)
to its view. A higher index will bring it forwards.
Author | Contributing | Need Help? |
---|---|---|
Popovers is made by aheze. | All contributions are welcome. Just fork the repo, then make a pull request. | Open an issue or join the Discord server. You can also ping me on Twitter. Or read the source code — there's lots of comments. |
Find is an app that lets you find text in real life. Popovers is used for the quick tips and as a replacements for menus — download to check it out!
If you have an app that uses Popovers, just make a PR or message me.
Author: aheze
Source Code: https://github.com/aheze/Popovers
License: MIT license
1668134460
Currently in SwiftUI, the only way to inform the user about some process that finished for example, is by using Alert
. Sometimes, you just want to pop a message that tells the user that something completed, or his message was sent. Apple doesn't provide any other method rather than using Alert
even though Apple using all kinds of different pop-ups. The results are poor UX where the user would need to tap "OK/Dismiss" for every little information that he should be notified about.
Alert Toast is an open-source library in Github to use with SwiftUI. It allows you to present popups that don't need any user action to dismiss or to validate. Some great usage examples: Message Sent
, Poor Network Connection
, Profile Updated
, Logged In/Out
, Favorited
, Loading
and so on…
Alert
(pop at the center), HUD
(drop from the top) and Banner
(pop/slide from the bottom).Complete
, Error
SystemImage
, Image
, Loading
, and Regular
(Only Text).put star 🌟
.CocoaPods is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate AlertToast
into your Xcode project using CocoaPods, specify it in your Podfile:
pod 'AlertToast'
The Swift Package Manager is a tool for managing the distribution of Swift code. It’s integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies.
To integrate AlertToast
into your Xcode project using Xcode 12, specify it in File > Swift Packages > Add Package Dependency...
:
https://github.com/elai950/AlertToast.git, :branch="master"
For Xcode 13, please refer this article to install AlertToast
If you prefer not to use any of dependency managers, you can integrate AlertToast
into your project manually. Put Sources/AlertToast
folder in your Xcode project. Make sure to enable Copy items if needed
and Create groups
.
First, add import AlertToast
on every swift
file you would like to use AlertToast
.
Then, use the .toast
view modifier:
Parameters:
isPresenting
: (MUST) assign a Binding<Bool>
to show or dismiss alert.duration
: default is 2, set 0 to disable auto dismiss.tapToDismiss
: default is true
, set false
to disable.alert
: (MUST) expects AlertToast
.import AlertToast
import SwiftUI
struct ContentView: View{
@State private var showToast = false
var body: some View{
VStack{
Button("Show Toast"){
showToast.toggle()
}
}
.toast(isPresenting: $showToast){
// `.alert` is the default displayMode
AlertToast(type: .regular, title: "Message Sent!")
//Choose .hud to toast alert from the top of the screen
//AlertToast(displayMode: .hud, type: .regular, title: "Message Sent!")
//Choose .banner to slide/pop alert from the bottom of the screen
//AlertToast(displayMode: .banner(.slide), type: .regular, title: "Message Sent!")
}
}
}
.toast(isPresenting: $showAlert, duration: 2, tapToDismiss: true, alert: {
//AlertToast goes here
}, onTap: {
//onTap would call either if `tapToDismis` is true/false
//If tapToDismiss is true, onTap would call and then dismis the alert
}, completion: {
//Completion block after dismiss
})
AlertToast(displayMode: DisplayMode,
type: AlertType,
title: Optional(String),
subTitle: Optional(String),
style: Optional(AlertStyle))
//This is the available customizations parameters:
AlertStyle(backgroundColor: Color?,
titleColor: Color?,
subTitleColor: Color?,
titleFont: Font?,
subTitleFont: Font?)
SFSymbols
..toast(isPresenting: Binding<Bool>, duration: Double = 2, tapToDismiss: true, alert: () -> AlertToast , onTap: () -> (), completion: () -> () )
AlertToast(type: .regular, title: Optional(String), subTitle: Optional(String))
AlertToast(type: .complete(Color)/.error(Color), title: Optional(String), subTitle: Optional(String))
AlertToast(type: .systemImage(String, Color), title: Optional(String), subTitle: Optional(String))
AlertToast(type: .image(String), title: Optional(String), subTitle: Optional(String))
//When using loading, duration won't auto dismiss and tapToDismiss is set to false
AlertToast(type: .loading, title: Optional(String), subTitle: Optional(String))
You can add many .toast
on a single view.
I wrote an article that contains more usage examples.
Medium - How to toast an alert in SwiftUI
All issue reports, feature requests, pull requests and GitHub stars are welcomed and much appreciated.
Author: elai950
Source Code: https://github.com/elai950/AlertToast
License: MIT license
1667135220
Popup from Apple Music & Feedback in AppStore. Contains Done
, Heart
, Error
and other. Supports Dark Mode and SwiftUI
. I tried to recreate Apple's alerts as much as possible. You can find these alerts in the AppStore after feedback and after you add a song to your library in Apple Music.
For get alert from switch silent mode, check library SPIndicator.
Ready for use on iOS 11+.
The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into the swift
compiler. It’s integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies.
Once you have your Swift package set up, adding as a dependency is as easy as adding it to the dependencies
value of your Package.swift
.
dependencies: [
.package(url: "https://github.com/ivanvorobei/SPAlert", .upToNextMajor(from: "4.2.0"))
]
CocoaPods is a dependency manager. For usage and installation instructions, visit their website. To integrate using CocoaPods, specify it in your Podfile
:
pod 'SPAlert'
If you prefer not to use any of the dependency managers, you can integrate manually. Put Sources/SPAlert
folder in your Xcode project. Make sure to enable Copy items if needed
and Create groups
.
For the best experience, I recommend presenting alerts by calling the class functions SPAlert
. These functions are updated regularly and show the alerts as Apple way:
SPAlert.present(title: "Added to Library", preset: .done)
For using a custom image:
SPAlert.present(title: "Love", message: "We'll recommend more like this in For You", preset: .custom(UIImage.init(named: "heart")!))
For showing a simple text message:
SPAlert.present(message: "Something going wrong", haptic: .error)
To change the duration of present time, create an alert view and call present
method with custom duration:
let alertView = SPAlertView(title: "Complete", preset: .done)
alertView.duration = 4
alertView.present()
If you don't want to dismiss alert in time, disable dismissInTime
. After it, duration
property will be ignored.
alertView.dismissInTime = false
In this case, you should dismiss the alert manually.
If you tap the alert, it will disappear. This can be disabled:
alertView.dismissByTap = false
Also, you can manually dismiss all alerts, simply call this:
SPAlert.dismiss()
For customise layout and margins, use layout
property. You can manage margins for each side, icon size and space between image and titles:
alertView.layout.iconSize = .init(width: 24, height: 24)
alertView.layout.margins.top = 12
alertView.layout.spaceBetweenIconAndTitle = 8
To manage haptic, you should pass it in present method:
alertView.present(duration: 1.5, haptic: .success, completion: nil)
You can remove duration and completion, because they have default values.
I added the preset .spinner
, to use it simply call this:
let alertView = SPAlertView(title: "Please, wait", preset: .spinner)
alertView.present()
By default this preset dismissInTime
is disabled and the alert needs to be manually dismissed. You can do it only for one view or dismiss all alerts:
// For one alert
alertView.dismiss()
// For all alerts
SPAlert.dismiss()
For change color of icon, simple set tint color for any preset:
alertView.iconView?.tintColor = .systemRed
//If you set custom image, don't forget set rendering mode:
UIImage(systemName: "pencil.and.outline")!.withRenderingMode(.alwaysTemplate)
Also you can change some default values for alerts. For example you can change default duration and corner radius for alert with next code:
SPAlertView.appearance().duration = 2
SPAlertView.appearance().cornerRadius = 12
It will apply to all alerts. I recommend setting it in the app delegate, but you can change it in runtime.
Use like system alert only show message tips:
Button("Show alert") {
showAlert = true
}.SPAlert(isPresent: $showAlert, message: "this is message only")
or show message, title, image and other configuration:
Button("Show alert") {
showAlert = true
}.SPAlert(
isPresent: $showAlert,
title: "Alert title",
message: "Alert message",
duration: 2.0,
dismissOnTap: false,
preset: .custom(UIImage(systemName: "heart")!),
haptic: .success,
layout: .init(),
completion: {
print("Alert is destory")
})
Я веду телеграм-канал, там публикую новости и туториалы.
С проблемой помогут в чате.
Видео-туториалы выклыдываю на YouTube:
Author: ivanvorobei
Source Code: https://github.com/ivanvorobei/SPAlert
License: MIT license
1666763880
PMAlertController is a small library that allows you to substitute Apple's uncustomizable UIAlertController
, with a beautiful and totally customizable alert that you can use in your iOS app. Enjoy!
CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:
$ gem install cocoapods
To integrate PMAlertController into your Xcode project using CocoaPods, specify it in your Podfile
:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '9.0'
use_frameworks!
pod 'PMAlertController'
Then, run the following command:
$ pod install
Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.
You can install Carthage with Homebrew using the following command:
$ brew update
$ brew install carthage
To integrate PMAlertController into your Xcode project using Carthage, specify it in your Cartfile
:
github "pmusolino/PMAlertController"
Run carthage update
to build the framework and drag the built PMAlertController.framework
into your Xcode project.
/Library
folder in your project.The usage is very similar to UIAlertController
. PMAlertController
has two styles: Alert & Walkthrough.
Alert Style: with this style, the alert has the width of 270 points, like Apple's UIAlertController
.
Walkthrough Style: with walkthrough, the alert has the width of the screen minus 18 points from the left and the right bounds. This mode is intended to be used before authorization requests like the ones for location, push notifications and more.
//This code works with Swift 5
let alertVC = PMAlertController(title: "A Title", description: "My Description", image: UIImage(named: "img.png"), style: .alert)
alertVC.addAction(PMAlertAction(title: "Cancel", style: .cancel, action: { () -> Void in
print("Capture action Cancel")
}))
alertVC.addAction(PMAlertAction(title: "OK", style: .default, action: { () in
print("Capture action OK")
}))
alertVC.addTextField { (textField) in
textField?.placeholder = "Location..."
}
self.present(alertVC, animated: true, completion: nil)
If you use Swift 5.0 or higher, you can use the latest release.
If you use Swift 4, you can use the release 3.5.0.
If you use Swift 3, you can use the release 2.1.3.
If you use Swift 2.3, you can use the release 1.1.0
If you use Swift 2.2, you can use the release 1.0.5
You may now use this library with React Native via the module here
Made with ❤️ by Paolo Musolino.
Follow me on:
Author: pmusolino
Source Code: https://github.com/pmusolino/PMAlertController
License: MIT license
1666228680
Siren checks a user's currently installed version of your iOS app against the version that is currently available in the App Store.
If a new version is available, a language localized alert can be presented to the user informing them of the newer version, and giving them the option to update the application. Alternatively, Siren can notify your app through alternative means, such as a custom user interface.
Siren is built to work with the Semantic Versioning system.
Rules.AlertType
enum.Installation and Integration
Swift Version | Branch Name | Will Continue to Receive Updates? |
---|---|---|
5.5+ | master | Yes |
5.1-5.4 | swift5.4 | No |
5.0 | swift5.0 | No |
4.2 | swift4.2 | No |
4.1 | swift4.1 | No |
3.2 | swift3.2 | No |
3.1 | swift3.1 | No |
2.3 | swift2.3 | No |
pod 'Siren' # Swift 5.5+
pod 'Siren', :git => 'https://github.com/ArtSabintsev/Siren.git', :branch => 'swift5.4' # Swift 5.1-5.4
pod 'Siren', :git => 'https://github.com/ArtSabintsev/Siren.git', :branch => 'swift5.0' # Swift 5.0
pod 'Siren', :git => 'https://github.com/ArtSabintsev/Siren.git', :branch => 'swift4.2' # Swift 4.2
pod 'Siren', :git => 'https://github.com/ArtSabintsev/Siren.git', :branch => 'swift4.1' # Swift 4.1
pod 'Siren', :git => 'https://github.com/ArtSabintsev/Siren.git', :branch => 'swift3.2' # Swift 3.2
pod 'Siren', :git => 'https://github.com/ArtSabintsev/Siren.git', :branch => 'swift3.1' # Swift 3.1
pod 'Siren', :git => 'https://github.com/ArtSabintsev/Siren.git', :branch => 'swift2.3' # Swift 2.3
.Package(url: "https://github.com/ArtSabintsev/Siren.git", majorVersion: 6)
Implementing Siren is as easy as adding two lines of code to your app in either AppDelegate.swift
or SceneDelegate.swift
:
import Siren // Line 1
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
window?.makeKeyAndVisible()
Siren.shared.wail() // Line 2
return true
}
}
import Siren // Line 1
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
window?.makeKeyAndVisible()
Siren.shared.wail() // Line 2
return true
}
}
Siren also has plenty of customization options. All examples can be found in the Example Project's AppDelegate file. Uncomment the example you'd like to test.
Device-Specific Checks
Siren is localized for the following languages:
Arabic, Armenian, Basque, Chinese (Simplified and Traditional), Croatian, Czech, Danish, Dutch, English, Estonian, Finnish, French, German, Greek, Hebrew, Hungarian, Indonesian, Italian, Japanese, Korean, Latvian, Lithuanian, Malay, Norwegian (Bokmål), Persian (Afghanistan, Iran, Persian), Polish, Portuguese (Brazil and Portugal), Romanian, Russian, Serbian (Cyrillic and Latin), Slovenian, Spanish, Swedish, Thai, Turkish, Ukrainian, Urdu, Vietnamese
If your user's device is set to one of the supported locales, an update message will appear in that language. If a locale is not supported, than the message will appear in English.
You may want the update dialog to always appear in a certain language, ignoring the user's device-specific setting. You can enable it like so:
// In this example, we force the `Russian` language.
Siren.shared.presentationManager = PresentationManager(forceLanguageLocalization: .russian)
If an app update is available, Siren checks to make sure that the version of iOS on the user's device is compatible with the one that is required by the app update. For example, if a user has iOS 11 installed on their device, but the app update requires iOS 12, an alert will not be shown. This takes care of the false positive case regarding app updating.
Testing
Temporarily change the version string in Xcode (within the .xcodeproj
file) to an older version than the one that's currently available in the App Store. Afterwards, build and run your app, and you should see the alert.
If you currently don't have an app in the store, change your bundleID to one that is already in the store. In the sample app packaged with this library, we use Facebook's Bundle ID: com.facebook.Facebook
.
Occasionally, the iTunes JSON will update faster than the App Store CDN, meaning the JSON may state that the new version of the app has been released, while no new binary is made available for download via the App Store. It is for this reason that Siren will, by default, wait 1 day (24 hours) after the JSON has been updated to prompt the user to update. To change the default setting, please modify the value of showAlertAfterCurrentVersionHasBeenReleasedForDays
.
App Submission
The App Store reviewer will not see the alert. The version in the App Store will always be older than the version being reviewed.
In 2017, Apple announced the ability to rollout app updates gradually (a.k.a. Phased Releases). Siren will continue to work as it has in the past, presenting an update modal to all users. If you opt-in to a phased rollout for a specific version, you have a few choices:
showAlertAfterCurrentVersionHasBeenReleasedForDays
to 7
, and Siren will not prompt any users until the latest version is 7 days old, after the phased rollout is complete.Attribution
A massive shout-out and thank you goes to the following folks:
Author: ArtSabintsev
Source Code: https://github.com/ArtSabintsev/Siren
License: MIT license
1665917567
flutter_platform_alert
2021 and onwards © Weizhong Yang a.k.a zonble.
A simple plugin to present native alerts, including playing alert sounds and showing alert dialogs on various platforms including iOS, Android, Windows, macOS and Linux.
It uses following API to show play alert sound.
It uses following API to show alert dialogs.
The package was developed and tested on
flutter pub add flutter_platform_alert
.flutter pub get
.To play platform alert sound.
import 'package:flutter_platform_alert/flutter_platform_alert.dart';
await FlutterPlatformAlert.playAlertSound();
To show a platform alert dialog.
import 'package:flutter_platform_alert/flutter_platform_alert.dart';
await FlutterPlatformAlert.playAlertSound();
final clickedButton = await FlutterPlatformAlert.showAlert(
windowTitle: 'This ia title',
text: 'This is body',
alertStyle: AlertButtonStyle.yesNoCancel,
iconStyle: IconStyle.information,
);
To show an alert dialog with custom button titles:
import 'package:flutter_platform_alert/flutter_platform_alert.dart';
await FlutterPlatformAlert.playAlertSound();
final clickedButton = await FlutterPlatformAlert.showCustomAlert(
windowTitle: 'This ia title',
text: 'This is body',
positiveButtonTitle: "Positive",
negativeButtonTitle: "Negative",
neutralButtonTitle: "Neutral",
additionalWindowTitleOnWindows: 'Window title',
showAsLinksOnWindows: true);
When calling showCustomAlert
, you can assign any button titles and use up to three buttons. Once there is no button title specified, it falls back to only an "OK" button.
When calling showAlert
, you can specify the buttons listed in the alert dialog by passing alertStyle
argument. The package follows the API design on Windows (see the reference of MessageBox win32 API), and it provides following styles:
Since each platform has its own conventions, the order of these buttons are not guaranteed to be the same.
The package also follow the API design of MessageBox on Windows to add icons to the alert dialogs (see the link above). There are several different icons styles but actually four:
Please note that these icons are not available on iOS and Android.
On iOS and macOS, the alert dialogs follows the dark/light mode settings on users' system. On Linux, the alert dialogs are rendered with current GTK theme. On Windows, they are always in light mode even you choose to use dark mode on Windows 10 and Windows 11.
On Android, the alert dialog uses the default theme of Material design (as Theme.Material.Dialog.Alert).
Since the plugin calls native API, if you want to localize buttons like "OK", "Cancel" and so on on Platforms like iOS, macOS and Linux, you have to do some works in your app.
Android apps embeds resources for localized strings. The localized strings files for the project are located under android/src/main/res. Once you need to add new languages, just fork the project and put your files under the folder.
On Windows, the buttons on the message boxes will be in the Windows system language.
The package in released under MIT License.
iOS 15 in Simulator
Android 11 on Samsung phone
macOS 12 Monterey
Windows 10 with MessageBox API
Windows 11 with TaskDialogIndirect API
Windows 11 with TaskDialogIndirect API that shows buttons as links
Ubuntu 21.10
Run this command:
With Flutter:
$ flutter pub add flutter_platform_alert
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
flutter_platform_alert: ^0.3.0
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:flutter_platform_alert/flutter_platform_alert.dart';
// ignore_for_file: avoid_print
import 'dart:io';
import 'package:flutter/material.dart' hide MenuItem;
import 'package:flutter_platform_alert/flutter_platform_alert.dart';
import 'package:tray_manager/tray_manager.dart';
import 'package:window_manager/window_manager.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
if (Platform.isWindows || Platform.isMacOS || Platform.isLinux) {
await windowManager.ensureInitialized();
}
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with TrayListener, WindowListener {
@override
void initState() {
if (Platform.isWindows || Platform.isMacOS || Platform.isLinux) {
// These are not supported on iOS and Android.
trayManager.addListener(this);
windowManager.addListener(this);
_init();
}
super.initState();
}
@override
void dispose() {
trayManager.removeListener(this);
windowManager.removeListener(this);
super.dispose();
}
void _init() async {
await trayManager.setIcon(
Platform.isWindows
? 'images/tray_icon_original.ico'
: 'images/tray_icon_original.png',
);
List<MenuItem> items = [
MenuItem(
key: 'show_window',
label: 'Show Window',
),
MenuItem(
key: 'hide_window',
label: 'Hide Window',
),
MenuItem(
key: 'show_alert_ok',
label: 'Show OK',
),
MenuItem.separator(),
MenuItem(
key: 'exit_app',
label: 'Exit App',
),
];
final menu = Menu(items: items);
await trayManager.setContextMenu(menu);
setState(() {});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Flutter Platform Alert')),
body: ListView(children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Text('Play Alert Sounds',
style: Theme.of(context).textTheme.headline6),
),
ListTile(
onTap: () async {
await FlutterPlatformAlert.playAlertSound();
},
title: const Text('Play Alert Sound (Default)')),
ListTile(
onTap: () async {
await FlutterPlatformAlert.playAlertSound(
iconStyle: IconStyle.exclamation,
);
},
title: const Text('Play Alert Sound (exclamation)')),
ListTile(
onTap: () async {
await FlutterPlatformAlert.playAlertSound(
iconStyle: IconStyle.error,
);
},
title: const Text('Play Alert Sound (error)')),
const Divider(),
Padding(
padding: const EdgeInsets.all(14.0),
child: Text('Standard Alert with Styles',
style: Theme.of(context).textTheme.headline6),
),
ListTile(
onTap: () async {
final result = await FlutterPlatformAlert.showAlert(
windowTitle: '白日依山盡 黃河入海流',
text: '芋頭西米露 保力達蠻牛',
iconStyle: IconStyle.exclamation,
alertStyle: AlertButtonStyle.abortRetryIgnore,
options: FlutterPlatformAlertOption(
preferMessageBoxOnWindows: true,
),
);
print(result);
},
title: const Text('Show non-ascii characters')),
const Divider(),
ListTile(
onTap: () async {
final result = await FlutterPlatformAlert.showAlert(
windowTitle: 'This ia title',
text: 'This is body',
iconStyle: IconStyle.warning,
);
print(result);
},
title: const Text('Show warning style')),
ListTile(
onTap: () async {
final result = await FlutterPlatformAlert.showAlert(
windowTitle: 'This ia title',
text: 'This is body',
iconStyle: IconStyle.information,
);
print(result);
},
title: const Text('Show information style')),
ListTile(
onTap: () async {
final result = await FlutterPlatformAlert.showAlert(
windowTitle: 'This ia title',
text: 'This is body',
iconStyle: IconStyle.error,
);
print(result);
},
title: const Text('Show error style')),
const Divider(),
ListTile(
onTap: () async {
final result = await FlutterPlatformAlert.showAlert(
windowTitle: 'This ia title', text: 'This is body');
print(result);
},
title: const Text('Show OK')),
ListTile(
onTap: () async {
final result = await FlutterPlatformAlert.showAlert(
windowTitle: 'This ia title',
text: 'This is body',
alertStyle: AlertButtonStyle.okCancel);
print(result);
},
title: const Text('Show OK/Cancel')),
ListTile(
onTap: () async {
final result = await FlutterPlatformAlert.showAlert(
windowTitle: 'This ia title',
text: 'This is body',
alertStyle: AlertButtonStyle.abortRetryIgnore);
print(result);
},
title: const Text('Show Abort/Retry/Ignore')),
ListTile(
onTap: () async {
final result = await FlutterPlatformAlert.showAlert(
windowTitle: 'This ia title',
text: 'This is body',
alertStyle: AlertButtonStyle.cancelTryContinue);
print(result);
},
title: const Text('Show Cancel/Try/Continue')),
ListTile(
onTap: () async {
final result = await FlutterPlatformAlert.showAlert(
windowTitle: 'This ia title',
text: 'This is body',
alertStyle: AlertButtonStyle.retryCancel);
print(result);
},
title: const Text('Show Retry/Cancel')),
ListTile(
onTap: () async {
final result = await FlutterPlatformAlert.showAlert(
windowTitle: 'This ia title',
text: 'This is body',
alertStyle: AlertButtonStyle.yesNo);
print(result);
},
title: const Text('Show Yes/No')),
ListTile(
onTap: () async {
final result = await FlutterPlatformAlert.showAlert(
windowTitle: 'This ia title',
text: 'This is body',
alertStyle: AlertButtonStyle.yesNoCancel);
print(result);
},
title: const Text('Show Yes/No/Cancel')),
const Divider(),
Padding(
padding: const EdgeInsets.all(16.0),
child: Text('Custom Alerts',
style: Theme.of(context).textTheme.headline6),
),
ListTile(
onTap: () async {
final result = await FlutterPlatformAlert.showCustomAlert(
windowTitle: 'This ia title',
text: 'This is body',
positiveButtonTitle: "Positive",
negativeButtonTitle: "Negative",
neutralButtonTitle: "Neutral",
iconPath: Platform.isWindows
? 'images/tray_icon_original.ico'
: 'images/tray_icon_original.png',
options: FlutterPlatformAlertOption(
additionalWindowTitleOnWindows: 'Window title',
showAsLinksOnWindows: false),
);
print(result);
},
title: const Text('Show Positive/Negative/Neutral')),
ListTile(
onTap: () async {
final result = await FlutterPlatformAlert.showCustomAlert(
windowTitle: 'This ia title',
text: 'This is body',
positiveButtonTitle: "Positive",
negativeButtonTitle: "Negative",
neutralButtonTitle: "Neutral",
options: FlutterPlatformAlertOption(
additionalWindowTitleOnWindows: 'Window title',
showAsLinksOnWindows: true),
);
print(result);
},
title: const Text(
'Show Positive/Negative/Neutral (as links on windows)')),
])));
}
@override
void onTrayMenuItemClick(MenuItem menuItem) async {
switch (menuItem.key) {
case 'show_window':
await windowManager.show();
await windowManager.setSkipTaskbar(false);
break;
case 'hide_window':
await windowManager.hide();
await windowManager.setSkipTaskbar(true);
break;
case 'show_alert_ok':
final result = await FlutterPlatformAlert.showAlert(
windowTitle: 'This ia title', text: 'This is body');
print(result);
break;
default:
break;
}
}
@override
void onTrayIconMouseDown() {
trayManager.popUpContextMenu();
}
}
Download Details:
Author: zonble
Source Code: https://github.com/zonble/flutter_platform_alert
1604278800
The North Korean advanced persistent threat (APT) group known as Kimsuky is actively attacking commercial-sector businesses, often by posing as South Korean reporters, according to an alert from the U.S. Cybersecurity and Infrastructure Security Agency (CISA).
Kimsuky (a.k.a. Hidden Cobra) has been operating as a cyberespionage group since 2012 under the auspices of the regime in Pyongyang. Its mission is global intelligence gathering, CISA noted, which usually starts with spearphishing emails, watering-hole attacks, torrent shares and malicious browser extensions, in order to gain an initial foothold in target networks.
Primary targets include think-tanks, and diplomatic and high-level organizations in Japan, South Korea and the United States, with a focus on foreign policy and national-security issues related to the Korean peninsula, nuclear policy and sanctions, CISA added. It also targets the cryptocurrency industry.
In recent campaigns seen over the summer, the group ultimately sent malicious attachments embedded in spearphishing emails to gain initial access to victim organizations, according to an analysis, published on Tuesday. But the malicious content was deployed only after several initial exchanges with the target meant to build trust.
“Posing as South Korean reporters, Kimsuky exchanged several benign interview-themed emails with their intended target to ostensibly arrange an interview date and possibly build rapport,” according to CISA. “The emails contained the subject line, ‘Skype Interview requests of [redacted TV show] in Seoul,’ and began with a request to have the recipient appear as a guest on the show. The APT group invited the targets to a Skype interview on the topic of inter-Korean issues and denuclearization negotiations on the Korean Peninsula.”
After a recipient agreed to an interview, Kimsuky sent a subsequent email with a malicious document. And when the date of the interview got closer, the purported “reporter” sent an email canceling the interview.
After obtaining initial access, the APT group ultimately deployed the BabyShark malware and PowerShell or the Windows Command Shell for execution.
“This is another example of the seriousness of the modern cybercrime world and the resources behind them,” said Erich Kron, security awareness advocate at KnowBe4, via email. “With billions of dollars at stake every year and with warfare expanding to the digital realm in such a large way, it is no surprise that nation-states are involved. The days of thick manila envelopes full of papers, traditional dossiers on people or stealthy microfilm cameras whisking away our information are gone. Now, it is all a bunch of ones and zeros in easily searched databases.”
#government #malware #web security #active campaigns #alert #analysis #babyshark #cisa #espionage #hidden cobra #kimsuky #malware #north korea #reporters #south korea #spyware
1602968400
U.S. government officials have warned that advanced persistent threat actors (APTs) are now leveraging Microsoft’s severe privilege-escalation flaw, dubbed “Zerologon,” to target elections support systems.
Days after Microsoft sounded the alarm that an Iranian nation-state actor was actively exploiting the flaw (CVE-2020-1472), the Cybersecurity Infrastructure Security Agency (CISA) and the Federal Bureau of Investigation (FBI) published a joint advisory warning of further attacks.
The advisory details how attackers are chaining together various vulnerabilities and exploits – including using VPN vulnerabilities to gain initial access and then Zerologon as a post-exploitation method – to compromise government networks.
“This recent malicious activity has often, but not exclusively, been directed at federal and state, local, tribal and territorial (SLTT) government networks,” according to the security advisory. “Although it does not appear these targets are being selected because of their proximity to elections information, there may be some risk to elections information housed on government networks.”
With the U.S. November presidential elections around the corner – and cybercriminal activity subsequently ramping up to target election infrastructure and presidential campaigns – election security is top of mind. While the CISA and FBI’s advisory did not detail what type of elections systems were targeted, it did note that there is no evidence to support that the “integrity of elections data has been compromised.”
Microsoft released a patch for the Zerologon vulnerability as part of its August 11, 2020 Patch Tuesday security updates. Exploiting the bug allows an unauthenticated attacker, with network access to a domain controller, to completely compromise all Active Directory identity services, according to Microsoft.
Despite a patch being issued, many companies have not yet applied the patches to their systems – and cybercriminals are taking advantage of that in a recent slew of government-targeted attacks.
The CISA and FBI warned that various APT actors are commonly using a Fortinet vulnerability to gain initial access to companies. That flaw (CVE-2018-13379) is a path-traversal glitch in Fortinet’s FortiOS Secure Socket Layer (SSL) virtual private network (VPN) solution. While the flaw was patched in April 2019, exploitation details were publicized in August 2019, opening the door for attackers to exploit the error.
Other initial vulnerabilities being targeted in the attacks include ones in Citrix NetScaler (CVE-2019-19781), MobileIron (CVE-2020-15505), Pulse Secure (CVE-2019-11510), Palo Alto Networks (CVE-2020-2021) and F5 BIG-IP (CVE-2020-5902).
After exploiting an initial flaw, attackers are then leveraging the Zerologon flaw to escalate privileges, researchers said. They then use legitimate credentials to log in via VPN or remote-access services, in order to maintain persistence.
#critical infrastructure #vulnerabilities #web security #alert #apts #chaining #cisa #citrix netscaler #cve-2018-13379 #cve-2019-11510 #cve-2019-19781 #cve-2020-1472 #cve-2020-15505 #cve-2020-2021 #cve-2020-5902 #election security #election systems #exploit chain #f5 big-ip #fbi #government attacks #microsoft #mobileiron #palo alto networks #pulse secure #vpn #warning #zerologon
1598884238
https://www.youtube.com/watch?v=xXwSJGYqeIQ
How to create modal dialogs with the alert, confirm and prompt commands in JavaScript
#javascript #modal #alert #confirm #prompt #web-development
1597683600
The U.S. National Security Agency (NSA) and the Cybersecurity and Infrastructure Security Agency (CISA) have issued an alert warning that adversaries could be targeting critical infrastructure across the U.S.
Separately, ICS-CERT issued an advisory on a critical security bug in the Schneider Electric Triconex TriStation and Tricon Communication Module. These safety instrumented system (SIS) controllers are responsible for shutting down plant operations in the event of a problem and act as an automated safety defense for industrial facilities, designed to prevent equipment failure and catastrophic incidents such as explosions or fire. They’ve been targeted in the past, in the TRITON attack of 2017.
“Over recent months, cyber-actors have demonstrated their continued willingness to conduct malicious cyber-activity against critical infrastructure (CI) by exploiting internet-accessible operational technology (OT) assets,” said the NSA/CISA joint advisory, released on Thursday. “Due to the increase in adversary capabilities and activity, the criticality to U.S. national security and way of life and the vulnerability of OT systems, civilian infrastructure makes attractive targets for foreign powers attempting to do harm to U.S. interests or retaliate for perceived U.S. aggression.”
The advisory goes on to point out that OT systems often consist of legacy equipment that was never designed to be connected to the internet nor defend against malicious cyberactivities. At the same time, more and more utilities, petrochemical installations, factories and so on are looking to increase remote operations. This means conducting various activities over the web using an IT network to connect to the OT side, enabling monitoring, instrumentation and control, OT asset management/maintenance, and in some cases, process operations and maintenance.
Generally, adversaries are using spearphishing efforts to obtain initial access to the organization’s IT network, before pivoting to the OT network, the advisory added.
“Combined with readily available information that identifies OT assets connected via the internet (e.g., Shodan, Kamerka), are creating a ‘perfect storm’ of easy access to unsecured assets, use of common, open-source information about devices, and an extensive list of exploits deployable via common exploit frameworks,” the agencies warned.
The NSA/CISA advisory also detailed that in the wild, several cyberattack attempts have been observed. These include attempts to: Deploy of commodity ransomware on both IT and OT networks; communicate with controllers and downloading modified control logic; use vendor engineering software and program downloads; and modify control logic and parameters on programmable logic controllers (PLCs). PLCs are responsible for directly reading and manipulating physical processes in industrial environments.
If successful, these efforts could result in an OT network going down, a partial loss of view for human operators, lost productivity and revenue, or, in the worst-case scenario, adversary control and disruption to physical processes.
“Cyber campaigns are an ideal way for nation-states to apply pressure on the global stage, because they offer the advantage of plausible deniability plus the rules of engagement are undefined,” Phil Neray, vice president of industrial cybersecurity at CyberX, said via email. “This NSA/CISA advisory is particularly interesting because it appears to be tied to ongoing campaigns targeting industrial control systems, and it explicitly mentions the need for organizations to protect against sophisticated living-off-the-land tactics such as modifying the control logic in process controllers, which is exactly what we saw in the TRITON attack.”
Two partial-loss-of-view incidents have been recorded in the U.S. before: One was a ransomware attack on a pipeline in February that knocked it offline for two days; and the other was an attack on a wind-and-solar power plant last November. Loss of view means that the organization loses the ability to monitor the current status of its physical systems.
Neray said in an interview with Threatpost at the time that “if an attacker wanted to shut down parts of the grid, one of their first steps might be precisely this loss-of-view step, because it would leave utility operators ‘blind’ to subsequent disruptive actions the attackers would take, such as switching relays off to halt the flow of electricity.”
#critical infrastructure #government #hacks #vulnerabilities #advisory #alert #cisa #critical security vulnerability #cve-2020-7491 #cyberattacks #factories #foreign adversaries #ics-cert #industrial control systems #nsa #oil and gas refineries #power plants #schneider #triconex #warning
1582622710
Before you Turn Off the Alerts know that AMBER Alerts are an incredible tool for the Government to attain out to its Responsible Citizens in instances of Natural Disasters and in case of abduction. Turning them off may cost little treasured lives. But these messages can act as outstanding distractions while you’re riding or attending a vital commercial enterprise meeting.
Amber indicators are supposed to warn mobile smartphone users of approximate kidnappings inside the area. They are part of Wireless Emergency Alerts (WEA), designed via the United States government to alert the public of emergencies such as severe weather situations and presidential announcements concerning emergencies.
As an awful lot as no damage was intended in developing with this approach of indicators, at times we can’t help however sense that the government is pushing the idea down our throats. No one will ever ask in your opinion on whether or no longer you would like to obtain the alerts.
It’s essential to be aware that AMBER indicators are one of a kind from other emergency alerts. For example, in past due 2018 the government examined a new so-called “Presidential Alert,” which can’t become off.
For iOS gadgets, amber indicators and emergency signals are grouped as Government signals.
You will notice that there are variations within the Interface of Android telephones. The “Settings” essential to alter your Amber signals are positioned in a unique vicinity for every Android smartphone.
We shall provide tenet to comply with turning off amber indicators in different Android phones.
In Stock Android
First Step
Tap on the Settings app to open it. This app is discovered on the home screen.
second Step
Scroll to the bottom and faucet on Sound. You will need to locate the Cell Broadcasts menu. Tap on “More”, observed by way of “Emergency broadcasts”.
third Step
On the Cell Broadcast settings page, uncheck the box to show off amber alerts. Tap on it another time to disable it.
Additionally, you can disable indicators for “Severe threats”.
Also, Read
Some Android gadgets have a separate app specifically for Emergency Alerts. It is from this source that you may disable the indicators. Tap on the app to open it.
You then choose “Menu” and head over to “Settings”. From the listing displayed, choose “Receive alerts”. Finally, uncheck the signals that you want to prevent receiving.
Apart from the iPhones and Androids, there are ways of turning off those signals in other telephones as well. We shall briefly guide you through the steps.
Read more info from Android Online Training
#android #androidapp #ios #alert