Animated RxCocoa bindings

Overview

RxAnimated - animated bindings

CI Status Version License Platform

RxAnimated provides animation interface to RxCocoa's bindings.

It comes with few predefined animation bindings, and provides a flexible mechanism for you to add your own predefined animations and use them when binding with RxCocoa.

Usage

Built-in animations

When binding values with RxCocoa you write something like:

textObservable
  .bind(to: labelFlip.rx.text)

This updates the label's text each time the observable emits a new string value. But this happens abruptly and without any transition. With RxAnimated you can use the animated extension to bind values with animations, like so:

textObservable
  .bind(animated: labelFlip.rx.animated.flip(.top, duration: 0.33).text)

The "difference" is that you use bind(animated:) instead of bind(to:) and you insert animated.flip(.top, duration: 0.33) (or one of the other provided or custom animation methods) between rx and the property sink you want to use, e.g. text in the example above.

The same built-in fade and flip animations work on any UIView element. And also on specific properties like UILabel.rx.text or UIImageView.rx.image.

Animation List

List of built-in animated sinks:

UIView.rx.animated...isHidden
UIView.rx.animated...alpha
UILabel.rx.animated...text
UILabel.rx.animated...attributedText
UIControl.rx.animated...isEnabled
UIControl.rx.animated...isSelected
UIButton.rx.animated...title
UIButton.rx.animated...image
UIButton.rx.animated...backgroundImage
UIImageView.rx.animated...image
NSLayoutConstraint.rx.animated...constant
NSLayoutConstraint.rx.animated...isActive

List of the built-in animations:

UIView.rx.animated.fade(duration: TimeInterval)
UIView.rx.animated.flip(FlipDirection, duration: TimeInterval)
UIView.rx.animated.tick(FlipDirection, duration: TimeInterval)
UIView.rx.animated.animation(duration: TimeInterval, animations: ()->Void)
NSLayoutConstraint.rx.animated.layout(duration: TimeInterval)

Check the demo app for a number of examples.

Custom animations

You can easily add your custom bind animations to match the visual style of your app.

I. (Optional) If you are animating a new binding sink that has no animated binding (e.g. UIImageView.rx.image, UILabel.rx.text and more are already included but you need another property)

// This is your class `UILabel`
extension AnimatedSink where Base: UILabel { 
    // This is your property name `text` and value type `String`
    public var text: Binder<String> { 
        let animation = self.type!
        return Binder(self.base) { label, text in
            animation.animate(view: label, block: {
                guard let label = label as? UILabel else { return }
                // Here you update the property
                label.text = text 
            })
        }
    }
}

II. Add your new animation method:

// This is your class `UIView`
extension AnimatedSink where Base: UIView { 
    // This is your animation name `tick`
    public func tick(_ direction: FlipDirection = .right, duration: TimeInterval) -> AnimatedSink<Base> { 
        // use one of the animation types and provide `setup` and `animation` blocks
        let type = AnimationType<Base>(type: RxAnimationType.spring(damping: 0.33, velocity: 0), duration: duration, setup: { view in
            view.alpha = 0
            view.transform = CGAffineTransform(rotationAngle: direction == .right ?  -0.3 : 0.3)
        }, animations: { view in
            view.alpha = 1
            view.transform = CGAffineTransform.identity
        })
        
        //return AnimatedSink
        return AnimatedSink<Base>(base: self.base, type: type) 
    }
}

III. Now you can use your new animation to bind subscriptions. Here's how usually binding UIImageView.rx.image looks like:

imageObservable
    .bind(to: imageView.rx.image)

And the result is non-animated binding:

If you use your new custom animation binding like so:

imageObservable
    .bind(to: imageView.rx.animated.tick(.right, duration: 0.33).image)

The effect will be:

And if you use the same animation on a UILabel:

textObservable
    .bind(to: labelCustom.rx.animated.tick(.left, duration: 0.75).text)

The sky is the limit! (And good taste.)

Example

The demo app shows few animations in action, download the repo and give it a try.

Installation

RxAnimated depends on RxSwift 5+.

RxAnimated is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod "RxAnimated"

License

RxAnimated is available under the MIT license. See the LICENSE file for more info.

Comments
  • Yet another Carthage support

    Yet another Carthage support

    There are some PRs trying to add Carthage support (#7 or #28). But all of them are stale and I can no see any progress for a long time.

    So I created a yet another Carthage support PR.

    opened by mickamy 6
  • Problem with Custom AnimatedSink

    Problem with Custom AnimatedSink

    While trying to add an AnimatedSink for UIEdgeInsets for an CollectionView. Compiler is complaining that self.type and self.baseare inaccessibble due to internal protection level. Why are they specifically marked internal?

    extension AnimatedSink where Base: UICollectionView {
        var contentInsets: Binder<UIEdgeInsets> {
            let animation = self.type
            return Binder(self.base) { collectionView, insets in
                self.type.animate(view: collectionView, binding: {
                    guard let collectionView = collectionView as? UICollectionView else { return }
                    collectionView.contentInsets = insets
                })
            }
        }
    }
    
    opened by vander2675 4
  •  Unexpectedly found nil while implicitly unwrapping an Optional value

    Unexpectedly found nil while implicitly unwrapping an Optional value

    I am trying to show/hide a view with animation. When I use rx.isHidden it is working. But rx.animated.isHidden occurs crash.

    My Code:

    someObservable. // Observable<Bool>
                .bind(animated: toggleView.rx.animated.isHidden)
                .disposed(by: rx.disposeBag)
    

    Crash from Pod:

    extension AnimatedSink where Base: UIView {
        public var isHidden: Binder<Bool> {
            return Binder(self.base) { view, hidden in
                self.type.animate(view: view) {   //  Unexpectedly found nil while implicitly unwrapping an Optional value
                    view.isHidden = hidden
                }
            }
        }
    }
    

    What am I missing?

    opened by berkakkerman 2
  • add animation argument 'delay'

    add animation argument 'delay'

    Change animation argument 'delay' 0 to valiable. This is a sample code.

    textObservable
      .bind(animated: labelFlip.rx.animated.flip(.top, duration: 0.33, delay: 0.5).text)
    
    opened by Yoshiatsu-Irei 1
  • Custom animations support

    Custom animations support

    Currently It's unavailable to make an extension to AnimatedSink with custom animation like this:

    extension AnimatedSink where Base: MyView {
       public func customAnimation() -> AnimatedSink<Base> {
            let type = AnimationType<Base>(duration: duration, setup: { view in
                //...
            }, animations: { view in
                //...
            })
            return AnimatedSink<Base>(base: self.base, type: type)
        }
    }
    

    because AnimationType and AnimatedSink initializers and AnimatedSink base variable has internal protection level.

    opened by subbotkin 1
  • Add

    Add "standard" animations

    Gonna need something beyond flip and cross-fade for the initial version. Think has already been included as an example for how to create custom animations but would be nice to have a list of optional extra animations for people to use.

    • [ ] ?
    opened by icanzilb 1
  • Info.plist missing

    Info.plist missing

    While updating RxAnimated to 0.9.0 via Carthage, an error has been occurred and build was failed.

    xcodebuild log says

    error: Build input file cannot be found: 'path/to/project/Carthage/Checkouts/RxAnimated/Sources/RxAnimated/Info.plist' (in target 'RxAnimated' from project 'RxAnimated')
    
    opened by 417-72KI 0
  • Memory leak

    Memory leak

    Hi, I used v0.9.0 with RxSwift 6.2 on latest xCode.

    i have a memory leak by using:

    Observable
       .combineLatest(
          foo1.asObservable(),
          foo2.asObservable()
       )
       .map { string in
          NSMutableAttributedString(string: string)
       }
       .bind(to: rx.animated.fade(duration: 0.1).attributedText)
       .disposed(by: bag)
    

    I can solve this leak with:

    Observable
       .combineLatest(
          foo1.asObservable(),
          foo2.asObservable()
       )
       .map { string in
          NSMutableAttributedString(string: string)
       }
       .bind(to: rx.attributedText)
       .disposed(by: bag)
    

    how do you think?

    opened by StefaniOSApps 0
  • Fix Xcode build error

    Fix Xcode build error

    With the current settings, can build Exmaple/RxAnimated.xcworkspace after pod install, but ./RxAnimated.xcodeproj cannot be built with Xcode because there is no Info.plist.

    This commit removes Info.plist to build the Example, but it's a good idea not to includeInfo.plist in the pod install code.

    opened by Econa77 0
  • Fix swift build

    Fix swift build

    Run swift build locally, will get the following error:

    RxAnimated % swift build
    RxAnimated/Sources/RxAnimated/RxAnimated+animations.swift:3:8: error: no such module 'UIKit'
    import UIKit
           ^
    

    I know the discussion here, but it may have been needed at some point.

    opened by Econa77 0
  • 'AnimationOptions' is not a member type of 'UIView'

    'AnimationOptions' is not a member type of 'UIView'

    Hi I updated facebooksdk in cocoa pods then suddenly started getting this build time errors out of nowhere.

    Xcode 9.4.1 Swift 4.1

    Pattern cannot match values of type 'RxAnimationType' case .transition(let type): 'AnimationOptions' is not a member type of 'UIView' 1 - FlipDirection 2- public func animation(duration: TimeInterval, options: UIView.AnimationOptions 3- RxAnimationType

    Use of unresolved identifier 'UIAccessibility' UIAccessibility.isReduceMotionEnabled

    And I can't take it back.

    Note. I have updated RxSwift and RxCocoa 4.3 to see if anything happens, but same issue still. Thanks.

    This is my pod pod 'Firebase/Core' pod 'Firebase/Firestore' pod 'Firebase/Auth' pod 'Firebase/Storage' pod 'Firebase/Functions' pod 'RxSwift', '~> 4.0' pod 'RxCocoa', '~> 4.0' pod 'RxDataSources', '~> 3.0' pod 'RxAnimated' pod 'SDWebImage', '~> 4.0' pod 'Stripe' pod 'FirebaseUI/Facebook' pod 'FBSDKCoreKit' pod 'FBSDKLoginKit' pod 'Firebase/Messaging'

    opened by selcukyucel 0
Releases(0.9.0)
Owner
RxSwift Community
RxSwift ecosystem projects
RxSwift Community
Cocoa framework and Obj-C dynamism bindings for ReactiveSwift.

Reactive extensions to Cocoa frameworks, built on top of ReactiveSwift. ⚠️ Looking for the Objective-C API? ?? Migrating from RAC 4.x? ?? Release Road

null 20k Jan 8, 2023
RxSwift bindings for Permissions API in iOS.

RxPermission RxSwift bindings for Permission API that helps you with Permissions in iOS. Installation RxPermission is available through CocoaPods. I c

Luke 230 Dec 27, 2022
Lightweight observations and bindings in Swift

What is Hanson? Hanson is a simple, lightweight library to observe and bind values in Swift. It's been developed to support the MVVM architecture in o

Blendle 526 Oct 18, 2022
Simple, lightweight swift bindings

Bindy Just a simple bindings. Installation Add pod 'Bindy' to your podfile, and run pod install SPM is supported too. Usage For now, Bindy has a coupl

Maxim Kotliar 25 Dec 12, 2022
STDevRxExt contains some extension functions for RxSwift and RxCocoa which makes our live easy.

STDevRxExt Example To run the Example.playground, clone the repo, and run pod install from the Example directory first. Requirements iOS 9.0+ tvOS 9.0

STDev 6 Mar 26, 2021
Example Poq App written in Swift with RxSwift and RxCocoa

PoqApp-iOS Example Poq App written in Swift with RxSwift and RxCocoa Overview This is an example app written by Emre AYDIN on 01.16.2022 MVVM Design P

Emre AYDIN 0 Feb 16, 2022
STDevRxExt contains some extension functions for RxSwift and RxCocoa which makes our live easy.

STDevRxExt Example To run the Example.playground, clone the repo, and run pod install from the Example directory first. Requirements iOS 9.0+ tvOS 9.0

STDev 6 Mar 26, 2021
MLIR Bindings for Swift

MLIR Bindings for Swift This project intends to make MLIR APIs accessible from Swift via the MLIR C Bindings. Usage The best reference for how to use

CIRCT 24 Sep 8, 2021
Cocoa framework and Obj-C dynamism bindings for ReactiveSwift.

Reactive extensions to Cocoa frameworks, built on top of ReactiveSwift. ⚠️ Looking for the Objective-C API? ?? Migrating from RAC 4.x? ?? Release Road

null 20k Jan 8, 2023
ZeroMQ Swift Bindings for iOS, macOS, tvOS and watchOS

SwiftyZeroMQ - ZeroMQ Swift Bindings for iOS, macOS, tvOS and watchOS This library provides easy-to-use iOS, macOS, tvOS and watchOS Swift bindings fo

Ahmad M. Zawawi 60 Sep 15, 2022
WebKit aims to provide platform agnostic isolated browser environments without the need for sketchy C bindings or a bloated V8 runtime.

WebKit WebKit aims to provide platform agnostic isolated browser environments without the need for sketchy C bindings or a bloated V8 runtime. Running

Linden 1 Nov 26, 2021
RxSwift bindings for Permissions API in iOS.

RxPermission RxSwift bindings for Permission API that helps you with Permissions in iOS. Installation RxPermission is available through CocoaPods. I c

Luke 230 Dec 27, 2022
Lightweight observations and bindings in Swift

What is Hanson? Hanson is a simple, lightweight library to observe and bind values in Swift. It's been developed to support the MVVM architecture in o

Blendle 526 Oct 18, 2022
Simple, lightweight swift bindings

Bindy Just a simple bindings. Installation Add pod 'Bindy' to your podfile, and run pod install SPM is supported too. Usage For now, Bindy has a coupl

Maxim Kotliar 25 Dec 12, 2022
XVim2 - Vim key-bindings for Xcode 9

XVim2 XVim2 is a Vim plugin for Xcode intending to offer a compelling Vim experience without the need to give up any Xcode features. Xcode 9 or above,

null 2.3k Jan 1, 2023
Coz profiler Swift wrapper/bindings

Swift Coz (Linux Only) Coz profiler Swift wrapper/bindings. This is a Swift wrapper around the Coz profiler here: https://github.com/plasma-umass/coz

Krzysztof Majk 4 Aug 5, 2022
Demo project to try WebRTC native bindings in .net MAUI

MAUI.WebRTC.Demo Demo project to try WebRTC native bindings in .net MAUI. There are two projects with Xamarin bindings https://github.com/melihercan/W

null 4 Dec 5, 2022
SPM-native private framework bindings

Paris SPM-powered SDK for working with private frameworks. Help me! Currently, using Paris is a bit convoluted. Due to a limitation set by SPM, Paris

Eric Rabil 3 Sep 6, 2022
Animated Mask Label is a nice gradient animated label.

Animated Mask Label Demo Screen Screenshot Demo/Example For demo: $ pod try AnimatedMaskLabel To run the example project, clone the repo, and run pod

Jogendra 19 Dec 13, 2022
Presentation helps you to make tutorials, release notes and animated pages.

Presentation helps you to make tutorials, release notes and animated pages.

HyperRedink 3k Dec 28, 2022