[iOS] Representing analog flip numbers like airport/trainstation displays

Related tags

UI JDFlipNumberView
Overview

JDFlipNumberView & JDFlipImageView

The FlipNumberView is simulating an analog flip display (like those for the departure time on the airport). It's well abstracted and damn easy to use. Please open a Github issue, if you think anything is missing or wrong.

Screenshots

Installation

CocoaPods

  • pod 'JDFlipNumberView' including the default images
  • pod 'JDFlipNumberView/Core' without default images (to use your own images)
  • pod 'JDFlipNumberView/FlipImageView', only the JDFlipImageView (for flipping images)

See Customization below for infos, on how to use your own images.

(For infos on cocoapods, have a look the cocoapods website)

Manually

  1. Add all files from JDFlipNumberView/JDFlipNumberView/*.{h,m} to your project
  2. Add the JDFlipNumberView.bundle, if you want to use the default images
  3. Link against the QuartzCore.framework

Contents

The main classes are

  • JDFlipNumberView
    The Standard FlipNumberView. It shows an integer value as FlipView. It has a choosable amount of digits. Can be animated in any way described in this document.

  • JDFlipImageView
    An Image View with flip animations. Use it like a regular UIImageView, but set new images animated via setImageAnimated:duration:completion:.

For specific usecases you may use on of these:

  • JDDateCountdownFlipView
    A date countdown. Just init with a target date and it will show the remaining days, hours, minutes and seconds until that date.

  • JDFlipClockView
    A digital clock. Displays the hour and minutes of the current time as flipViews. Seconds can also be enabled. Always shows the current time.

  • UIView+JDFlipImageView
    A UIView category that makes it possible to transition between any two views using a flip animation.

Usage

In any case, after installing, you only need to follow some simple steps to get started. Here is a full example usage:

Example: A 4 digit FlipNumberView animating down every second.

// create a new FlipNumberView, set a value, start an animation
JDFlipNumberView *flipNumberView = [[JDFlipNumberView alloc] initWithDigitCount:4];
flipNumberView.value = 1337;
[flipNumberView animateDownWithTimeInterval: 1.0];

// add to view hierarchy and resize
[self.view addSubview: flipNumberView];
flipNumberView.frame = CGRectMake(20,100,300,100);

That's it. This will display a working, flipping, animating countdown view!
See the example project for other examples.

Possible animations

Basic animations (Single Flip):

- (void)setValue:(NSInteger)newValue animated:(BOOL)animated;
- (void)animateToNextNumber;
- (void)animateToPreviousNumber;

Targeted animation over time (Flipping through all numbers, until target is reached):

- (void)animateToValue:(NSInteger)newValue duration:(CGFloat)duration;

Timed animation without target value (Flipping once per timeInterval):

- (void)animateUpWithTimeInterval:(NSTimeInterval)timeInterval;
- (void)animateDownWithTimeInterval:(NSTimeInterval)timeInterval;

Customization

You may use the original .psd file from the gfx folder to create custom numbers.

Digit images

A) Replace original images
Replace the images within the JDFlipNumberView.bundle. (In the Finder just Rightclick > Show Contents to see the images.)

When using Pods, make sure to use pod 'JDFlipNumberView/Core', so the default bundle won't be copied. Just create a bundle named JDFlipNumberView.bundle in your project yourself.

B) Use multiple bundles
Add another graphics bundle to your project. A bundle is nothing else, than a regular folder, but named with .bundle as extension. You need one image per digit. 0.png, 1.png, 2.png, etc. See the next section on how to use multiple bundles.

Implementing a custom bundle

To use your own bundles, create the FlipViews like this:

[JDFlipNumberView initWithDigitCount:<#count#> 
                     imageBundleName:<#imageBundleName#>];

or for a DateCountDown like this:

[JDDateCountdownFlipView initWithDayDigitCount:<#count#>
                               imageBundleName:<#imageBundleName#>];

Twitter

I'm @calimarkus on Twitter. Feel free to post a tweet, if you like the FlipNumberView.

TweetButton

Comments
  • Fixed animation timers being blocked.

    Fixed animation timers being blocked.

    If the flip number view is used in a scroll view, the timers were being blocked during scrolling. To fix this I changed the run loop modes for the NSTimers used to fire the animations.

    opened by guykogus 5
  • JDDateCountdownFlipView: Weird behavior when countdown reaches

    JDDateCountdownFlipView: Weird behavior when countdown reaches "0"

    There seems to be a problem with the countdown: When it gets reached (0 days, 0 hours, 0 minutes, 0 seconds) it restarts to count down with 1 minute left. After that it restarts with 1 hour left.

    The correct behavior would be IMHO to freeze the countdown when it reaches "0".

    opened by friolz 4
  • flipView infinite loop bug ?

    flipView infinite loop bug ?

    i will like the value from 99999 to 1, but the flipview have infinite loop.

    - (void)viewDidLoad
    {
     [self performSelector:@selector(changeCreditValue:) withObject:@"1" afterDelay:3];
    }
    
    - (void)setupCreditBar
    {
        //Credit
        self.flipView = [[JDFlipNumberView alloc] initWithDigitCount:5];
        self.flipView.value = 99999;
        self.flipView.maximumValue = 99999;
        // add to view hierarchy and resize
        [self.view addSubview: self.flipView];
        self.flipView.frame = CGRectMake(190,7,90,50);    
    }
    
    - (void)changeCreditValue:(NSString *)newCreditValue
    {
        NSDate *startDate = [NSDate date];
        NSLog(@"new Credit %@",newCreditValue);
        [self.flipView animateToValue:[newCreditValue intValue] duration:3.5];
    }
    
    bug 
    opened by kohdesmond 4
  • Possible feature : Animating through a set of time within a duration

    Possible feature : Animating through a set of time within a duration

    currently you have "- (void)animateToValue:(NSInteger)newValue duration:(CGFloat)duration;" it might be nice to add animateToValue for time. Like animateTimeFrom to animateTimeTo in duration

    opened by steve21124 3
  • Allow JDFlipViewRelativeMargin to be configured

    Allow JDFlipViewRelativeMargin to be configured

    This value should be configurable someplace in the component to enhance the rendering.

    For instance with my custom design, the views are too close one from each other, I would like to set JDFlipViewRelativeMargin to something like 30%.

    feature 
    opened by cyrilchandelier 3
  • JDFlipNumberViewDelegate seems not working

    JDFlipNumberViewDelegate seems not working

    delegate method "flipNumberView: (JDFlipNumberView*)flipNumberView willChangeToValue: (NSUInteger)newValue" cannot be found and not used in JDFlipNumberView.m.

    bug 
    opened by Aragan123 3
  • NSBundle for `imageBundleName` should be configurable

    NSBundle for `imageBundleName` should be configurable

    JDFlipNumberViewImageFactory.m lines 53 and 96 use [NSBundle mainBundle] as the bundle from which to load the digit images. This causes trouble when trying to use JDFlipNumberView as a framework, with Carthage, or in an IB_DESIGNABLE since the bundle for JDFlipNumberView is not necessarily the same as [NSBundle mainBundle].

    Unfortunately, the fix isn't as simple as just replacing [NSBundle mainBundle] with [NSBundle bundleForClass:[self class]] since the default images JDFlipNumberView.bundle will be in the JDFlipNumberView bundle, but any custom images may be in another bundle.

    Probably the right solution is to allow the option of passing an NSBundle object along with the image bundle name. For example, here are a few methods that would get renamed.

    - (void)generateImagesFromBundleNamed:(NSString*)bundleName;
    

    becomes

    - (void)generateImagesFromImageBundleName:(NSString*)imageBundleName inBundle:(NSBundle*)bundle;
    

    And

    - (void)setImageBundleName:(NSString*)imageBundleName;
    

    becomes

    - (void)setImageBundleName:(NSString*)imageBundleName inBundle:(NSBundle*)bundle;
    

    If necessary, the old methods could stick around for backwards compatibility. They would just call the new methods with [NSBundle mainBundle] for the bundle parameter

    feature 
    opened by johnboiles 2
  • UIView+JDFlipImageView was ignoring flip direction

    UIView+JDFlipImageView was ignoring flip direction

    Thank you for this implementation. It's been a tremendous time saver for me.

    I noticed that the UIView category was ignoring the JDFlipImageViewFlipDirection and always flipping from the top. I only modified the private factory method. The public API remains unchanged. I realize I accidentally included indentation change in this pull request. I'll fix that if you want me to.

    opened by seanwolter 2
  • No pod-2.0.6 tag

    No pod-2.0.6 tag

    I tried updating to the latest version with "pod update" and I'm getting the following error:

    [!] Pod::Executable fetch origin tags/pod-2.0.6 2>&1

    fatal: Couldn't find remote ref tags/pod-2.0.6

    fatal: The remote end hung up unexpectedly

    opened by KristopherGBaker 2
  • Fix intermittent CALayerInvalidGeometry crash after memory warning

    Fix intermittent CALayerInvalidGeometry crash after memory warning

    Fixes #44

    I could reproduce this crash by mashing cmd-shift-m to trigger memory warnings around the time JDFlipNumberView is laying out. This crash was caused by _topImages getting cleared out upon memory warning. Here's the sequence of events:

    1. Memory warning -- _topImages is cleared
    2. JDFlipNumberView layoutSubviews is called
    3. JDFlipNumberDigitView's sizeThatFits: method calls [self imageSize] which calls [factory imageSizeForBundleNamed:self.imageBundleName]
    4. imageSizeForBundleNamed: doesn't recreate _topImages so the size is returned as CGSizeZero
    5. JDFlipNumberDigitView's sizeThatFits: runs the line CGFloat origRatioW = imageSize.width/(imageSize.height*2);, resulting in a NaN (divide by 0)
    6. The NaN is set as the height for the JDFlipNumberDigitView's frame
    7. CALayerInvalidGeometry crash

    This fixes the issue by using topImagesForBundleNamed: instead of accessing topImages directly. topImagesForBundleNamed: recreates the topImages if they're not available.

    opened by johnboiles 1
  • CALayerInvalidGeometry crash in JDFlipNumberDigitView.m

    CALayerInvalidGeometry crash in JDFlipNumberDigitView.m

    I'm seeing an intermittent crash. Here's what it's looks like:

    Fatal Exception: CALayerInvalidGeometry
    CALayer position contains NaN: [32.5 nan]
    
    Thread : Fatal Exception: CALayerInvalidGeometry
    0  CoreFoundation                 6495280712 __exceptionPreprocess
    1  libobjc.A.dylib                6770999524 objc_exception_throw
    2  CoreFoundation                 6495280520 -[NSException initWithCoder:]
    3  QuartzCore                     6563416432 CA::Layer::set_position(CA::Vec2<double> const&, bool)
    4  QuartzCore                     6563416264 -[CALayer setPosition:]
    5  QuartzCore                     6563416152 -[CALayer setFrame:]
    6  UIKit                          6570418116 -[UIView(Geometry) setFrame:]
    7  MyApp                          4297676208 -[JDFlipNumberDigitView setFrame:] (JDFlipNumberDigitView.m:159)
    8  MyApp                          4297690220 -[JDFlipNumberView layoutSubviews] (JDFlipNumberView.m:495)
    9  UIKit                          6570433068 -[UIView(CALayerDelegate) layoutSublayersOfLayer:]
    10 QuartzCore                     6563453332 -[CALayer layoutSublayers]
    11 QuartzCore                     6563431780 CA::Layer::layout_if_needed(CA::Transaction*)
    12 QuartzCore                     6563431432 CA::Layer::layout_and_display_if_needed(CA::Transaction*)
    13 QuartzCore                     6563429384 CA::Context::commit_transaction(CA::Transaction*)
    14 QuartzCore                     6563428748 CA::Transaction::commit()
    15 UIKit                          6570441032 _UIApplicationHandleEventQueue
    16 CoreFoundation                 6494986472 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
    17 CoreFoundation                 6494983052 __CFRunLoopDoSources0
    18 CoreFoundation                 6494975036 __CFRunLoopRun
    

    I've gotten this a handful of times on several devices (iPhone 5s, 6, 6s) on both iOS8 and 9.1. It's super intermittent so I haven't been able to reproduce in the debugger.

    Seems like the things that affect CALayer's position are bounds, anchorPoint, and possibly transform. Though I haven't been able to figure out where a division by zero could have happened for any of those. I'll post here if I make any progress in diagnosing this.

    opened by johnboiles 1
  • imageSnapshotAfterScreenUpdates Problem when flipping different Views on different Screens

    imageSnapshotAfterScreenUpdates Problem when flipping different Views on different Screens

    I'm using the JDFlipImageView flipToView Method to animate 2 Views concurrently. One on an iOS 8 Device and one on a connected Beamer (simply an UIWindow with UIView where an UIImageView is displayed and flipped, same constellation on the iOS Device). The animation is invoked first for the Beamer's View and then for the iOS Device View.

    It's quite simple something like:

      ...
      if(self->secondScreen) {
        UIImageView* beamerLastImageView = self->newBeamerImageView;
        self->newBeamerImageView = [[UIImageView alloc]
    initWithImage:self->beamerImage];
      }
      UIImageView* lastImageView = self->newImageView;
      self->newImageView = [[UIImageView alloc] initWithImage:self->newImage];
      ...
      if(self->secondScreen) {
        [beamerLastImageView flipToView:self->newBeamerImageView
    duration:dur direction:dir completion:^(BOOL finished){ ... }];
      }
      [lastImageView flipToView:self->newImageView duration:dur
    direction:dir completion:^(BOOL finished){ ... }];
    

    The Problem is that shortly before the flip animation an Image appears on the iOS Device View, but not on the Beamer. It is half the Size (may be due to the Beamers windows frame being 1/2 of that of the Devices View) and rotated by 180 degree.

    After few hours of reading my code (can't exactly debug the APP while using a connected display) which is quite short for the animations, I started reading through the code path invoked by flipToView and it seems that imageSnapshotAfterScreenUpdates either makes a wrong Image or somehow mixes things between the 2 screens.

    For now I worked around it by exposing the addFlipViewWithAnimationFromImage and using my own Images directly from the UIImageViews. This works without Problems.

    I couldn't find any Information as to why this Problem occurs.

    bug 
    opened by makadev 2
  • Freeze in some occassion

    Freeze in some occassion

    When I leave a scene during the animation and switch back, the numbers are frozen in a middle state until next one, how to avoid this?

    Thank you in advance. 04a0a88f-e503-4442-959d-7c028462458c

    bug 
    opened by nix1024 8
  • Trainstation animation style [JDClassicFlipNumberView]

    Trainstation animation style [JDClassicFlipNumberView]

    When changing a number, e.g. 3520 to 9250 every digit should animate on its own to the new number iterating over every digit inbetween.

    Means: 3 to 9 (in 6 flips) 5 upwards to 2 (in 7 flips) 2 to 5 (in 3 flips) 0 stays like it is (0 flips)

    Working Title: JDClassicFlipNumberView

    feature 
    opened by calimarkus 3
  • Full support for NSNumberFormatter

    Full support for NSNumberFormatter

    Hi!

    It would be great if your library will support NSNumberFormatter (for example, in our project we're using groupSeparator for NSNumberFormatter, and our numbers looks like "1 000 000", not "1000000")

    Thanks!

    feature 
    opened by bsideup 1
Owner
M Emrich
iOS Engineer (ex: IG/FB)
M Emrich
This widget displays a weight and a label. It can be used in the summary view for a strength assessment.

Strength Assessment Widget - Flutter Modern UI engineering is all about components. When we build components to be reusable, we enable faster iteratio

null 1 Feb 18, 2022
SAHistoryNavigationViewController realizes iOS task manager like UI in UINavigationContoller. Support 3D Touch!

SAHistoryNavigationViewController Support 3D Touch for iOS9!! SAHistoryNavigationViewController realizes iOS task manager like UI in UINavigationConto

Taiki Suzuki 1.6k Dec 29, 2022
Full configurable spreadsheet view user interfaces for iOS applications. With this framework, you can easily create complex layouts like schedule, gantt chart or timetable as if you are using Excel.

kishikawakatsumi/SpreadsheetView has moved! It is being actively maintained at bannzai/SpreadsheetView. This fork was created when the project was mov

Kishikawa Katsumi 34 Sep 26, 2022
Pull up controller with multiple sticky points like in iOS Maps

PullUpController Create your own pull up controller with multiple sticky points like in iOS Maps Features Multiple sticky points Landscape support Scr

Mario Iannotta 1.2k Dec 22, 2022
A fancy hexagonal layout for displaying data like your Apple Watch

Hexacon is a new way to display content in your app like the Apple Watch SpringBoard Highly inspired by the work of lmmenge. Special thanks to zenly f

Gautier Gédoux 340 Dec 4, 2022
A horizontal scroll dial like Instagram.

HorizontalDial Preview Requirements iOS 8.0+ Swift 5 Storyboard support Installation CocoaPods use_frameworks! pod "HorizontalDial" Manually To instal

Lee Sun-Hyoup 210 Nov 22, 2022
You can dismiss modal viewcontroller like Facebook Messenger by pulling scrollview or navigationbar in Swift.

PullToDismiss PullToDismiss provides dismiss modal viewcontroller function like Facebook Messenger by pulling scrollview or navigationbar with smooth

Suguru Kishimoto 479 Dec 5, 2022
RangeSeedSlider provides a customizable range slider like a UISlider.

RangeSeekSlider Overview RangeSeekSlider provides a customizable range slider like a UISlider. This library is based on TomThorpe/TTRangeSlider (Objec

WorldDownTown 644 Dec 12, 2022
🍞 Toast for Swift - Toaster Android-like toast with very simple interface

Toaster Android-like toast with very simple interface. (formerly JLToast) Screenshots Features Queueing: Centralized toast center manages the toast qu

Suyeol Jeon 1.6k Jan 3, 2023
🔍 Awesome fully customize search view like Pinterest written in Swift 5.0 + Realm support!

YNSearch + Realm Support Updates See CHANGELOG for details Intoduction ?? Awesome search view, written in Swift 5.0, appears search view like Pinteres

Kyle Yi 1.2k Dec 17, 2022
A window arrangement manager for macOS like BetterSnapTool and Magnet

A window arrangement manager for macOS like BetterSnapTool and Magnet. You can split the foremost window to the left half of the screen, the left two-thirds, etc.

Takuto NAKAMURA (Kyome) 65 Dec 9, 2022
A SwiftUI bottom-up controller, like in the Maps app. Drag to expand or minimize.

SwiftUI Drawer A SwiftUI bottom-up controller, like in the Maps app. Drag to expand or minimize. Contents Add the Package Basic Usage Examples Credits

Michael Verges 695 Jan 3, 2023
Add the Notch on the menubar like the new MacBook Pro.

iNotch Add the Notch on the menubar like the new MacBook Pro. Installation This app works on macOS 11.0 or later. Download iNotch.zip from releases pa

Takuto NAKAMURA (Kyome) 8 Apr 3, 2022
Fully customizable Facebook reactions like control

Reactions is a fully customizable control to give people more ways to share their reaction in a quick and easy way. Requirements • Usage • Installatio

Yannick Loriot 585 Dec 28, 2022
Snapchat / Instagram Stories like progress indicator

SegmentedProgressBar A simple little control that animates segments like Snapchat or Instagram Stories. Requirements iOS 8.0+ Xcode 8 Installation Dra

Dylan Marriott 442 Dec 25, 2022
React.js like Mixin. More powerful Protocol-Oriented Programming.

Mixin ?? Why? Swift is Protocol-Oriented Programming, and it's more powerful by default implementations of extensions of protocols. You can mixin meth

Wan-Huang Yang 45 Dec 28, 2021
A simple Elm-like Store for SwiftUI, based on ObservableObject

ObservableStore A simple Elm-like Store for SwiftUI, based on ObservableObject.

Gordon Brander 28 Nov 8, 2022
SwiftCrossUI - A cross-platform SwiftUI-like UI framework built on SwiftGtk.

SwiftCrossUI A SwiftUI-like framework for creating cross-platform apps in Swift. It uses SwiftGtk as its backend. This package is still quite a work-i

null 97 Dec 28, 2022