GithubHelp home page GithubHelp logo

stonesam92 / sssnackbar Goto Github PK

View Code? Open in Web Editor NEW
107.0 6.0 29.0 238 KB

An iOS implementation of the Snackbar concept, as used extensively in Android as well as some Google iOS apps such as Gmail

License: MIT License

Ruby 1.10% Objective-C 89.28% C 0.77% Shell 8.85%

sssnackbar's Introduction

SSSnackbar

Version License Platform

Author

Sam Stone, [email protected]

About

Snackbars are a Android UI component which present a stylish, actionable alert to the user. Google also uses their own iOS snackbar implementation in some of their iOS apps, such as Gmail.

Snackbar's are useful for presenting a brief message to the user which they can then act on. A common usage pattern is to display a snackbar after a user has performed some destructive action, providing the user with a grace period during which they can undo this action.

This use-case is demonstrated in the iOS Google Gmail app: Gmail implementation

Below is a demonstration of the snackbar as realized by this project: SSSnackbar implementation

Example Project

The included example project provides a demonstration of SSSnackbar. It displays a tableView containing a shopping list. When an item is deleted from the shopping list, a snackbar is presented allowing the user to undo that deletion.

The shopping list is divided into two sections:

  • Normal Examples: deleting items from this sections demonstrates the standard use of a snackbar, with which the action block (executed when the user presses the snackbar's button), is executed on the main thread.
  • Long-Running Action Examples: deleting items from this section demonstrates the use of a snackbar object with a long-running action block which is executed in the background.

To run the example project, clone the repo, and run pod install from the Example directory first.

Installation

This project is available via CocoaPods. In order to install, simply add "SSSnackbar" to your Podfile.

You can also integrate SSSnackbar manually by downloading SSSnackbar.h and SSSnackbar.m and adding them to your project.

Usage

This project contains a single class: SSSnackbar.

SSSnackbar objects cannot be "stacked" on-screen. If you display a snackbar while another is on-screen, the currently shown snackbar will be replaced, and it will act as though it had been dismissed after being on-screen for its configured length of time.

All messages sent to SSSnackbar objects should be sent from the main thread.

Creating instances of SSSnackbar

New snackbar objects can be created using the following methods:

- (instancetype)initWithMessage:(NSString *)message
                 actionText:(NSString *)actionText
                   duration:(NSTimeInterval)duration
                actionBlock:(void (^)(SSSnackbar *sender))actionBlock
             dismissalBlock:(void (^)(SSSnackbar *sender))dismissalBlock
             
+ (instancetype)snackbarWithMessage:(NSString *)message
                     actionText:(NSString *)actionText
                       duration:(NSTimeInterval)duration
                    actionBlock:(void (^)(SSSnackbar *sender))actionBlock
                 dismissalBlock:(void (^)(SSSnackbar *sender))dismissalBlock 
  • message is the text to be displayed on the snackbar's text label.
  • actionText is the text to be used as the title for the snackbar's button.
  • duration is the length of time for which the snackbar should remain on the screen before it is dismissed
  • actionBlock is a block to be called if the user presses the snackbar's button. Unless the snackbar object is configured otherwise, this block is executed on the main thread.
  • dismissalBlock is a block to be called when the snackbar is dismissed from the screen without having its action button pressed. This can be used to finalize any action the user has taken, since at this poin the user's grace period to undo the change is over.

Configuring SSSnackbar instances.

The properties set wusing the initialiser method can be changed after the object is created, but should not be altered once the snackbar has been presented on-screen.

By default, actionBlock is executed on the main thread. If the block will take significant time to execute, then it can be run on a background thread by setting the snackbar's actionIsLongRunning property to YES.

In this case, the block will be executed on a background thread and a UIActivityIndicator will replace the snackbar's action button.

Displaying SSSnackbar instances to the user

Once created and configured, a snackbar object can be shown on the screen by sending it the show message.

Dismissing SSSnackbar instances

Snackbar objects dismiss themselves either after they have remained on-screen for their configured duration of time, or if the user presses the snackbar's button and the snackbar's action block has finished executing.

It is sometimes necessary however, to dismiss a snackbar object manually. This can be done by sending the object either the dismiss or dismissAnimated:(BOOL)animated messages.

sssnackbar's People

Contributors

stonesam92 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

sssnackbar's Issues

Crash at Launch

I have some code that may attempt to display SSSnackbar at launch from -applicationDidFinishLaunching:. I'm OK with it not being able to display a message here, but instead it crashes. The problem is that in -show it assumes there's a rootViewController:

    UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;

If this is nil, bad things happen. I think it just needs a check for nil here. It could return without displaying anything.

Add ability to showInView

It would be nice to be able to choose the position and/or show the snackbar in a particular view rather than the topViewController.

Crash on quickly presenting / dismissing / re-presenting...

I have a snackbar show on a modal view controller, it was meant to provide a heads up (with an action) on initial view. I find that if I present the VC but quick (during testing) drop it, and re-raise it, I get a crash. It appears to be attempting to clear up the previous snackbar, which I assume (from the crash) has been deallocated.

  • (void)dismissAnimated:(BOOL)animated {
    [self invalidateTimer];
    [self.superview removeConstraints:self.visibleVerticalLayoutConstraints];
    [self.superview addConstraints:self.hiddenVerticalLayoutConstraints];
    currentlyVisibleSnackbar = nil;

    if (!animated) {
    if (!self.actionBlockDispatched) <--- Crashes here...
    [self executeDismissalBlock];
    [self removeFromSuperview];
    }

called from show:

       [currentlyVisibleSnackbar dismissAnimated:NO];

I am using this from Swift, and my Objective C is already getting rusty, but I wonder if this should be __weak so it nils on cleanup?

   static SSSnackbar *currentlyVisibleSnackbar = nil;

Crash

  • created an instance of snackbar and show it
  • create another instance and show it while the previous is still on the screen
  • create one more and more and more

as the result - the app will crash here

if (!animated) {
    if (!self.actionBlockDispatched)
        [self executeDismissalBlock];
    [self removeFromSuperview];
}

on if (!self.actionBlockDispatched)

Snackbar on main VC, then Snackbar on modal VC, crash on cleanup as returns to main VC

I've had a pretty awkward to debug (i.e. no useful stack trace) issue which I think I've tracked down to my usage SSSnackbar. I love the view, I like how it allows me to message the user w/o getting in the way, so I use it a lot. I'd not put two and two together, at first, but I have this:

  • Main view does a SSSnackbar on startup of VC saying something.
  • Optionally a user presents a modal view (on iPhone, over whole window) and that VC uses a SSSnackbar to message.
  • If the user exits the modal before the second SSSnackbar is done (I think this is important) and returns to the main view (that raises a snackbar) then the app crashes on the code to cleanup the SSSnackbar.

I know I'll get a little less snackbar happy (it was just initial code and I'd not realized how it works in reality) but I think this is the issue:

  • Modal creates a SSSnackbar (so a different VC hierarchy?)
  • Modal goes away (tearing down SSSnackbar but it not clearing currentlyVisibleSnackbar)
  • Main VC tries to show and tries to replace existing SSSnackbar, but crashes on accessing currentlyVisibleSnackbar.

Even though my case might be a bit noisy, I can imagine this scenario occurring in some cases (where user is bounding around.)

Any thoughts on how to debug this, and what the best approach to fix this is? I know there have been tweaks / fixes for the modal VC hierarchy before, and wonder if another is possible / needed.

Thanks in advance, and I can supply more details if needed.

Color

Hi,

thank you for your project!
Could you please add an option to change color of the Snackbar?

Best regards,

Snackbar with no action

Is there a way to show this with no action, so it's basically just an info notification (like the android counterpart?)

Bar not showed properly on "modal" presented viewcontrollers.

I've found this issue trying to show the sssnackBar in a navigationViewController showed modally. After some research I've found that maybe it is happening when trying to get the superview in the show () method.

I've replace your:
"...
UIView *superview = [UIApplication sharedApplication].delegate.window.rootViewController.view;

..."

With this:

"...

UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;

while (topController.presentedViewController) {
    topController = topController.presentedViewController;
}

superview = topController.view;

..."

And it seems to work.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.