• Stars
    star
    278
  • Rank 148,454 (Top 3 %)
  • Language
    Swift
  • License
    MIT License
  • Created over 4 years ago
  • Updated over 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Moving numbers effect in SwiftUI

MovingNumbersView

Moving numbers effect in SwiftUI.

Demo

Custom element:

emojidemo

Also used in the Robinhood-like line plot library RHLinePlot.

Features ✨

  • Smooth digit transition
  • Custom digit view builder
  • Dynamic decimal places
  • Support integer (just set to 0 decimal place)
  • Support commas
  • Support negative numbers

Requirements

  • iOS 13, macOS 10.15
  • Swift 5.1
  • Xcode 11

Installation

Cocoapods

pod install MovingNumbersView

Swift Package Manager

Go to File → Swift Packages → Add Package Dependency then put the repo URL (https://github.com/aunnnn/MovingNumbersView.git).

Usage

Initialize it with number, numberOfDecimalPlaces, and trailing closure elementBuilder:

import MovingNumbersView

MovingNumbersView(
    number: 123.456,
    numberOfDecimalPlaces: 3) { str in
        // How to build each character
        Text(str)
            .font(.largeTitle)
}

To display whole numbers, just set numberOfDecimalPlaces to 0.

The elementBuilder: (String) -> some View will be used by the library to build each visual element such as digits, dots, and commas. You can return any View, so the text style is fully customizable.

Optional Parameters

Optional parameters are fixedWidth*, verticalDigitSpacing, and animationDuration. verticalDigitSpacing allows you to control the spacing between digits in the vertical digit stack, and animationDuration is the duration for the vertical digit stack to move up and down.

fixedWidth: CGFloat? is optional but important. It will give a fixed width to the label to give space for digit transitioning. Without it, when the last few digits are moving in and out, the label frame shrinks faster that the transition so you could see trailing digits getting cropped out:

notfixedwidth

Setting fixed width will prevent the frame to shrink, and makes the transition/animation effect looks better:

fixedwidth

This will also leading align the digits. With the default value (nil), the MovingNumbersView will shrink and expand at its own center, since its size depends on the number of current visual elements and make the transitioning weird. While this could be fixed by using extra VStack with leading alignment, the former cropping problem is still there.

P.S. Another way to solve it is to put a couple of invisible digit(s) at the end, so it has some extra space to transition out. It kind of work, but probably won't scale if multiple digits are gone simultaneously (like 1,234,567 -> 0).

Blurring out top and bottom edges

gradientdemo

To have the top and bottom edges look blurry, simply apply a gradient mask on the MovingNumbersView:

MovingNumbersView(...)
    .mask(LinearGradient(
        gradient: Gradient(stops: [
            Gradient.Stop(color: .clear, location: 0),
            Gradient.Stop(color: .black, location: 0.2),
            Gradient.Stop(color: .black, location: 0.8),
            Gradient.Stop(color: .clear, location: 1.0)]),
        startPoint: .top,
        endPoint: .bottom))

How it was done

Basically there are one view for each digit, comma, dot, and minus sign, all centered in a HStack by default. Check out VisualElementType enum.

Graph

To show a number, we move only the vertical digit stack up and down to the right offset. Try removing the mask and see it in action:

How

The digit is represented as 10-digit stack, and it's being moving up and down via VerticalShift geometry effect, which just offsets the digit stack by the current digit presented. (I believe the normal transform/offset might work too.)

The assigned ids are important. Each visual element is assigned a number relative to its significance. We use a multiple of 10s for digit, a negative multiple of 10s for decimal places, 0 for dot and 1 is for minus sign. Comma has the id of next digit plus 5.

For example, -1,234.56 -> ids = [1(-), 40, 35(,), 30, 20, 10, 0(.), -10, -20].

This scheme allows SwiftUI to calculate the right insertion/removal transitioning. Moving from 9 to 19 is moving from ids = [10("9")] to ids = [20("1"), 10("9")]. That is, we don't animate 9 to 1, but simply bring in a new 1.

More Repositories

1

AppStoreiOS11InteractiveTransition

iOS 11 App Store Transition
Swift
441
star
2

RHLinePlot

Line plot like in Robinhood app in SwiftUI
Swift
269
star
3

TableHeaderViewWithAutoLayout

Example of how to use AutoLayout with table header view.
Swift
78
star
4

AppStoreiOS11InteractiveTransition_old

App Store's Card Interactive Transition
Swift
51
star
5

SwiftyLocalization

A simple localization solution for iOS. Google spreadsheets ~> Localizable.strings ~> Swift's struct.
Python
40
star
6

daily-p5

p5.js development gallery using React
JavaScript
36
star
7

NestedDecodable

Decode deeply nested model with keyPath
Swift
15
star
8

TestButtonOnTabBar

Example of how to create button at the center of UITabBar like Facebook Messenger
Swift
12
star
9

next-p5-template

p5.js template built with Next.js
JavaScript
11
star
10

WirelessParking

iOS UDP broadcast using CocoaAsyncSocket
Swift
11
star
11

ViewElements_Old

Build UITableView declaratively by composing elements.
Swift
6
star
12

CreativeSwift

Creative coding for iOS in Swift
Swift
5
star
13

simple-http-server

Build a Simple HTTP Server in Python
Python
5
star
14

cse120pa4tests

CSE120 PA4 Tests
C
5
star
15

CORSaliency

Corner-based Saliency Model
Python
4
star
16

ViewElements

Build page in iOS apps declaratively
Swift
4
star
17

cse120pa3tests

Testing utilities for PA3
C
3
star
18

EarlGrey-Convenience

Convenience functions for EarlGrey UI testing
Swift
3
star
19

EmojiFaces

Replace faces in a photo with emoji.
JavaScript
3
star
20

open-ideas

A place to talk
JavaScript
2
star
21

FindBundit-iOS

The iOS app to find graduate's location.
Swift
2
star
22

Oreo

Cryptocurrency Portfolio in iOS
Swift
2
star
23

Just

A lightweight URLSession wrapper that does only GET and POST
Swift
2
star
24

SecurityUtil

HMAC with SHA256 and AES-256 CBC for Swift (compatible with PHP)
Swift
1
star
25

hackernews-react-apollo

Made from doing https://www.howtographql.com/ tutorial
JavaScript
1
star
26

platonos

JavaScript
1
star
27

os-tutorial

My study on "Writing a Simple Operating System from Scratch" by Nick Blundell
Assembly
1
star
28

AnimatableStatusBarViewController

A UIViewController base class to enable status bar animation
Swift
1
star
29

shills.lol

The place to shill
JavaScript
1
star
30

vanilla-rnn-pytorch

Build Vanilla RNN in PyTorch
Jupyter Notebook
1
star
31

siteleaf-demo

1
star
32

study-kernel-perceptron-svm

Study on kernel perceptron, multi-class perceptron
Jupyter Notebook
1
star
33

RxViewElementsExperiment

Expermenting ViewElements+RxSwift for data-driven UI
Swift
1
star
34

Resume

1
star