Enhanced transitioning between UICollectionView layouts in iOS.

Overview

TLLayoutTransitioning

Enhanced transitioning between UICollectionView layouts in iOS.

##Overview

TLLayoutTransitioning provides a TLLayoutTransition transition layout subclass and a UICollectionView+TLTransitioning category that combine to solve a few problems with collection view layout transitioning:

  1. UICollectionViewLayoutTransition does not handle content offset well, often leaving cells where you don't want them. TLTransitionLayout provides elegant control of content offset with Minimal, Visible, Center, Top, Left, Bottom or Right placement options relative to one or more index paths.

  2. UICollectionViewLayoutTransition does not support supplementary views. TLTransitionLayout provides support for any supplementary view kinds specified in the initializer.

  3. -[UICollectionView setCollectionViewLayout:animated:completion] has serious known bugs in iOS7 and does not provide any animation options. TLLayoutTransitioning provides a robust alternative to this API with support for animation duration, 30+ easing curves and content offset control. This is done by using CADisplayLink to drive an interactive TLTransitionLayout as a non-interactive animation. Note that this approach may not perform as well as Core Animation with more complex cells.

Check out the demos in the Examples workspace!

###TLTransitionLayout Class

TLTransitionLayout is a subclass of UICollectionViewTransitionLayout that interpolates linearly between layouts and optionally between the current content offset and a specified final offset.

The final offset is specified by setting the toContentOffset property. The UICollectionView+TLTransitioning category provides an API for calculating Minimal, Visible, Center, Top, Left, Bottom or Right offset placements relative to one or more index paths.

The basic usage is as follows:

- (void)someViewControllerEventHandler
{
    UICollectionViewLayout *nextLayout = ...;
    self.transitionLayout = (TLTransitionLayout *)[self.collectionView startInteractiveTransitionToCollectionViewLayout:nextLayout 
                                        completion:^(BOOL completed, BOOL finish) {
	    if (finish) {
            self.collectionView.contentOffset = self.transitionLayout.toContentOffset;
            self.transitionLayout = nil;
	    }
    }];
    NSArray *indexPaths = ...;// some selection of index paths to place
    self.transitionLayout.toContentOffset = [self.collectionView toContentOffsetForLayout:self.transitionLayout indexPaths:indexPaths placement:TLTransitionLayoutIndexPathPlacementCenter];
}

- (UICollectionViewTransitionLayout *)collectionView:(UICollectionView *)collectionView transitionLayoutForOldLayout:(UICollectionViewLayout *)fromLayout newLayout:(UICollectionViewLayout *)toLayout
{
    NSArray *supplementaryKinds = ...; // optional supplementary view kinds
    return [[TLTransitionLayout alloc] initWithCurrentLayout:fromLayout nextLayout:toLayout supplementaryKinds:supplementaryKinds];
}

Note that the collection view will reset contentOffset after the transition is finalized, but as illustrated above, this can be negated by setting it back to toContentOffset in the completion block.

####Canceling a Transition

If you want to stop the current transition to start a new one from the current position, you need a way to stop the current transition in-place. Apple provides finishInteractiveTransition and cancelInteractiveTransition to end a transition, but neither of these stops the transition in-place. So, TLLayoutTransitioning provides such a method:

[self.collectionView cancelInteractiveTransitionInPlaceWithCompletion:^(){
    // initiate new transition in the completion block
}];

You can find out if a transition is currently in progress by checking the isInteractiveTransitionInProgress on UICollectionView.

###UICollectionView+TLTransitioning Category

The UICollectionView+TLTransitioning category provides some of useful methods for calculating for interactive transitions. In particular, the toContentOffsetForLayout:indexPaths:placement API calculates final content offset values to achieve Minimal, Visible, Center, Top, Left, Bottom or Right placements for one or more index paths. The expanded version of this API provides for even further fine-tuning and supports transitioning to a different collection view size and content inset:

- (CGPoint)toContentOffsetForLayout:(UICollectionViewTransitionLayout *)layout
                         indexPaths:(NSArray *)indexPaths
                          placement:(TLTransitionLayoutIndexPathPlacement)placement
                    placementAnchor:(CGPoint)placementAnchor
                     placementInset:(UIEdgeInsets)placementInset
                             toSize:(CGSize)toSize
                     toContentInset:(UIEdgeInsets)toContentInset

UICollectionView+TLTransitioning also provides an alternative to -[UICollectionView setCollectionViewLayout:animated:completion] for non-interactive animation between layouts with support for animation duration, 30 built-in easing curves (courtesy of Warren Moore's AHEasing library), user defined easing curves (by defining custom AHEasingFunctions) and content offset control. The basic transition call is as follows:

TLTransitionLayout *layout = (TLTransitionLayout *)[collectionView transitionToCollectionViewLayout:toLayout duration:2 easing:QuarticEaseInOut completion:nil];
CGPoint toOffset = [collectionView toContentOffsetForLayout:layout indexPaths:@[indexPath] placement:TLTransitionLayoutIndexPathPlacementCenter];
layout.toContentOffset = toOffset;

where the view controller is configured to provide an instance of TLTransitionLayout as described above. Check out the Resize sample project in the Examples workspace to see this in action.

##Installation

###CocoaPods

Add the following to your Podfile

pod 'TLLayoutTransitioning'

###Carthage

Add the following to your Cartfile

github "wtmoose/TLLayoutTransitioning"

Note that TLLayoutTransitioning has a dependency on AHEasing, which does not support Carthage. As a workaround, TLLayoutTransitioning's Cartfile uses the wtmoose/AHEasing fork which adds Carthage support.

To request Carthage support for the canonical AHEasing library, consider leaving a comment in favor of reopening the Add dynamic frameworks support pull request.

###Manual

If you're not using a dependency manager, check out the noframeworks branch and copy the following files into your project:

TLTransitionLayout.h
TLTransitionLayout.m
UICollectionView+TLTransitionAnimator.h    
UICollectionView+TLTransitionAnimator.m

And copy the following files from AHEasing:

easing.h
easing.c

##Examples

Open the Examples workspace (not the project) to run the sample app. The following examples are included:

###Resize

The Resize example combines TLTransitionLayout and -[UICollectionView+TLTransitioning transitionToCollectionViewLayout:duration:easing:completion:] as a better alternative to -[UICollectionView setCollectionViewLayout:animated:completion]. Experiment with different durations, easing curves and content offset options on the settings panel. Toggle "show section headers" to see transitioning supplementary views.

###Pinch

The Pinch example demonstrates a simple pinch-driven interactive transition using TLTransitionLayout. The destination contentOffset is selected such that the initial visible cells remain centered. Or if a cell is tapped, the contentOffset the cell is centered.

About SwiftKick Mobile

We build high quality apps! Get in touch if you need help with a project.

Comments
  • UICollectionView not centering transition in iOS 9, worked fine in iOS 8.

    UICollectionView not centering transition in iOS 9, worked fine in iOS 8.

    The app essentially transitions between two different UICollectionViewFlowLayouts in a UICollectionView. I've not had a single problem with the TLLayoutTransitioning class prior to iOS 9. Thanks so much for taking the time to make and share this, by the way! It's a life saver. :)

    For some reason since updating to iOS 9 (app still compiled for 8+) the transition doesn't center the offset, and instead seems to throw the whole transition off now while transitioning from large to small layouts, as seen here:

    ripewellwornkagu-size_restricted

    Any thoughts what might've changed?

    opened by wanderingme 20
  • Update Examples project to build with frameworks

    Update Examples project to build with frameworks

    • Update Podfile deployment target to iOS 8.0 (required for dynamic frameworks)
    • Add use_frameworks! to Podfile
    • Bump deployment target in Examples.xcodeproj to iOS 8.0
    • Run pod update to update Pods and reintegrate them as frameworks

    See discussion on #19 for more details.

    opened by smileyborg 15
  • Memory leak

    Memory leak

    Hello, I am using your collectionview transition in my app and I appear to have a memory leak and xcodes profiler indicates it is here:

    UICollectionViewTransitionLayout *transitionLayout = [self startInteractiveTransitionToCollectionViewLayout:layout completion:^(BOOL completed, BOOL finish) { UICollectionViewTransitionLayout *transitionLayout = [self tl_transitionLayout]; if ([transitionLayout conformsToProtocol:@protocol(TLTransitionAnimatorLayout)]) { idlayout = (id)transitionLayout; [layout collectionViewDidCompleteTransitioning:self completed:completed finish:finish]; } [self tl_setAnimationDuration:nil]; [self tl_setAnimationStartTime:nil]; [self tl_setTransitionLayout:nil]; [self tl_setEasingFunction:NULL]; if (completion) { completion(completed, finish); } [[UIApplication sharedApplication] endIgnoringInteractionEvents]; }];

    I am unsure of how to fix this, can you help?

    opened by holidaycottages 12
  • Fix dynamic framework/modules build error

    Fix dynamic framework/modules build error

    When using TLLayoutTransitioning as a CocoaPod where use_frameworks! is specified and Modules are enabled, the framework fails to build because of how the easing.h header from AHEasing is being imported:

    Include of non-modular header inside framework module ‘TLLayoutTransitioning.UICollectionView_TLTransitioning’
    

    screen shot 2015-06-17 at 10 30 09 am

    This is easily resolved by changing the AHEasing import to a framework style import.

    See http://blog.cocoapods.org/Pod-Authors-Guide-to-CocoaPods-Frameworks/ for further discussion.

    opened by smileyborg 11
  • Cancel transition

    Cancel transition

    Hello again,

    I have a situation where if i rotate my device while performing a layout transition the app errors with the following error:

    the collection is already in the middle of an interactive transition

    So I was wondering if there was a way I could cancel the transition if one was in progress?

    opened by holidaycottages 8
  • Hi Tim - I get this error on demo

    Hi Tim - I get this error on demo

    the demo can't find TLCollectionViewController.

    TLCollectionViewController', superclass of 'CollectionViewController'; did you mean 'UICollectionViewController'?

    did this file get misplaced from repo?

    Cheers JP

    opened by johndpope 6
  • layout transition for supplementary views

    layout transition for supplementary views

    Hi Tim,

    I'm currently making use of your TLLayoutTransitioning class and it is really easy to use! Thanks a lot for developing this! Actually, I encountered a problem with transition with supplementary views. In my project, instead of only one section, I have two sections in the collection view, and for each section, there is a header view and a footer view. However, after applying your resizing example, the header view and footer view are gone after doing a layout transition (animate cells to be bigger.) I don't think this is an issue with your implementation, but I just have no idea how to accommodate supplementary views in your example (Maybe there is a way to fix it easily which I'm not aware of.). So, if at all possible, could you also add some header view/footer view in your resizing example so that I can study from it? I'm in desperate need of a way to make my project work...

    Thanks a lot in advance!

    Sincerely,

    Frank

    opened by franklixuefei 5
  • Examples not building

    Examples not building

    Many errors like Pods-TLIndexPathTools-prefix.pch:2:9: Could not build module 'UIKit' or CoreFoundation.h:11:10: Could not build module 'Darwin' occur when trying to run the Examples project for iOS 7.1 simulator in Xcode 5.1 (5B130a) straight from the repo, no modifications.

    opened by jombipva 5
  • Added support for a custom layout attributes class

    Added support for a custom layout attributes class

    It is useful to be able to pass the progress, for example, to the cells during complex transitions. Previously the transition layout was using UICollectionViewLayoutAttributes by default instead of honouring the class defined by layoutAttributesClass

    opened by jrturton 5
  • Transition crashes when the number of sections in the datasource increases

    Transition crashes when the number of sections in the datasource increases

    Hey Tim, thanks for creating this. It was working well for me when I had only one section in my collection view, but now with multiple sections I'm experiencing a crash during transitionToCollectionViewLayout:duration:easing:completion: that I wasn't experiencing with the stock setCollectionViewLayout:animated:completion: method.

    The setup: I have a collection view that supports a transition between a 1-wide grid layout and a 4-wide grid layout. The cells in the collection view are sectioned by month (Sept 2014, August 2014, ...) and the content is paginated such that when the user scrolls to the bottom new content is requested from my API and appended to my dataSource (currently just calling reloadData instead of performing any insertion updates).

    Steps:

    1. Start with a 1-wide grid. Transition to a 4-wide grid. Technically there's still only 1 section at this point, because we're still in the first month of data.
    2. Scroll down a few pages in the 4-wide grid until we've reached the next section.
    3. Attempt to transition back to the 1-wide grid results in a crash at this line:
    UICollectionViewLayoutAttributes *toPose = reverse
                        ? [self.currentLayout layoutAttributesForItemAtIndexPath:indexPath]
                        : [self.nextLayout layoutAttributesForItemAtIndexPath:indexPath];
    

    Because self.nextLayout's layoutAttributesForItemAtIndexPath:indexPath returns nil when the section index > 0. The error is:

    Uncaught exception: *** -[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]

    It appears that when I transition from the 1-wide layout, there's only one section in existence. Then, after scrolling the 4-wide layout, there's multiple sections. Attempting to go back to the 1-wide layout, the crash occurs.

    If I scroll through many sections while in the 1-wide layout, and then scroll back up, I'm free to transition between layouts since the number of sections in the 1-wide layout is in sync with the number of sections in the 4-wide layout.

    Any idea how to fix this? I'd very much like to continue using your library.

    Thanks!

    opened by scalessec 4
  • -[UICollectionViewTransitionLayout setToContentOffset:]: unrecognized selector

    -[UICollectionViewTransitionLayout setToContentOffset:]: unrecognized selector

    This library is super helpful! Thank you so much! But I'm getting this bug suddenly:

    "[UICollectionViewTransitionLayout setToContentOffset:]: unrecognized selector sent to instance 0x146f8360"

    Specifically my stack trace breaks at the following line in your example:

    "layout.toContentOffset = toOffset;"

    If I comment it out, everything works fine, except, obviously, I no longer get that awesome offset during transitions. The problem, as best as I can tell, is that the following line of code is returning a [UICollectionViewTransitionLayout] and therefore isn't being properly typed to your [TLTransitionLayout] subclass for some reason:

    "TLTransitionLayout *layout = (TLTransitionLayout *)[collectionView transitionToCollectionViewLayout:toLayout duration:2 easing:QuarticEaseInOut completion:nil];"

    When I NSLog the 'layout' object, it's definitely a [UICollectionViewTransitionLayout] type, not [TLTransitionLayout]. And, obviously, the [UICollectionViewTransitionLayout] class doesn't have the property "toOffset" I need, hence the error I'm experiencing. I've searched all over since this problem popped up over 9 hours ago, and zero solutions have helped. I've ensured all headers are included with #import and the implementation files are all being compiled within the correct target. I've cleared all my Derived Data, etc. Even uninstalled and reinstalled Xcode. I'm certainly lost. It just stopped working suddenly. I know it must be PEBKAC, but I can't for the life of me figure out how that can be. :( Anyhow, thanks a bunch for any insight. It was spectacular when it was working for me. :)

    opened by wanderingme 3
  • No source files in framework target.

    No source files in framework target.

    The framework target needs to include the .m files.

    Also, AHEasing needs to be added to Linked Frameworks and Libraries.

    These changes are needed for the framework to be used with Carthage.

    opened by bwhiteley 1
  • Not usable with Swift due to problem with AHEasing.

    Not usable with Swift due to problem with AHEasing.

    The AHEasing module referenced in the Cartfile does not work with Swift. The AHEasing umbrella header AHEasing.h does not include the other public headers in the AHEasing project.

    opened by bwhiteley 0
  • Disable bounce effect in interactive transitions

    Disable bounce effect in interactive transitions

    Hi!

    There seems to be a bounce effect when you complete an interactive transition, I'd like to replace that by just decelerating to final position without bouncing.

    You can check this effect in the Example project, if you pinch and release it'll complete the interactive transition with a bounce effect going a bit further than final progress in some cases.

    The workaround I found is to subclass TLTransitionLayout and override the setProgress:time: method limiting values to 0..1

    - (void)setTransitionProgress:(CGFloat)transitionProgress time:(CGFloat)time
    {
        [super setTransitionProgress:MAX(0, MIN(transitionProgress, 1.f)) time:MAX(0, MIN(time, 1.f))];
    }
    

    This does get rid for the bounce effect (it's no longer visible to the user) but the transition still takes some time to complete because it thinks it's bouncing.

    Any idea how can I solve this issue?

    Thanks in advance,

    Nicolás.

    opened by jakunico 4
  • Jarring snap at end of interactive transition.

    Jarring snap at end of interactive transition.

    I've noticed a jarring snap to an unintended position when the user lifts their fingers, ending the pinch gesture. After the layout snaps to the unintended position it will animate back to the expected layout.

    interactive_transition_snap

    opened by dillan 3
  • Resize example crashes when double clicking a cell

    Resize example crashes when double clicking a cell

    Tim, thank you very much for building this. I'm playing around the resize example. When double clicking a cell, the program crashes. The error message is: Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'the collection is already in the middle of an interactive transition'. I guess the beginIgnoringInteractionEvents and endIgnoringInteractionEvents calls should be added in collectionView:didSelectItemAtIndexPath:?

    opened by ghost 1
Releases(1.0.5)
  • 1.0.5(Jun 29, 2015)

    • Support Cocoapoda with or without !use_frameworks directive
    • Change project target to dynamic framework to support Carthage
    • Fix crash in Pinch example when pinching while transition in progress
    Source code(tar.gz)
    Source code(zip)
Owner
SwiftKick Mobile
Mobile app design and development agency
SwiftKick Mobile
A bunch of layouts providing light and seamless experiences in your Collection View

Swinflate Description Swinflate aims to encorporate a set of collection view layouts which provide a better and even more fluid experience in collecti

Vlad Iacob 224 Dec 19, 2022
The waterfall (i.e., Pinterest-like) layout for UICollectionView.

CHTCollectionViewWaterfallLayout CHTCollectionViewWaterfallLayout is a subclass of UICollectionViewLayout, and it trys to imitate UICollectionViewFlow

Nelson 4.4k Dec 24, 2022
Blueprints is a collection of flow layouts that is meant to make your life easier when working with collection view flow layouts.

Blueprints is a collection of flow layouts that is meant to make your life easier when working with collection view flow layouts. It comes

Christoffer Winterkvist 982 Dec 7, 2022
📏 A set of advanced compositional layouts for UICollectionView with examples

compositional-layouts-kit If you like the project, please give it a star ⭐ It will show the creator your appreciation and help others to discover the

Astemir Eleev 378 Dec 27, 2022
Our Guillotine Menu Transitioning Animation implemented in Swift reminds a bit of a notorious killing machine.

GuillotineMenu.swift Inspired by this project on Dribbble Also, read how it was done in our blog Requirements iOS 8.0+ Xcode 10 Swift 5.0 (v 4.1+) Swi

Yalantis 2.9k Dec 13, 2022
UIViewController subclass inspired by "Inbox by google" animated transitioning.

SAInboxViewController SAInboxViewController realizes Inbox like view transitioning. You can launch sample project on web browser from here. Features I

Taiki Suzuki 298 Jun 29, 2022
Painless custom transitioning. Easy extend, easy setup, just focus on animations.

TransitionManager Painless custom transitioning. Easy extend, easy setup, just focus on animations. Installation CocoaPods You can use CocoaPods to in

Cem Olcay 205 Aug 23, 2022
Custom transition between two collection view layouts

Display Switcher We designed a UI that allows users to switch between list and grid views on the fly and choose the most convenient display type. List

Yalantis 2.3k Dec 14, 2022
In-App iOS Debugging Tool With Enhanced Logging, Networking Info, Crash reporting And More.

The debugger tool for iOS developer. Display logs, network request, device informations, crash logs while using the app. Easy accessible with its bubble head button ?? . Easy to integrate in any apps, to handle development or testing apps easier. First version, there is plenty of room for improvement.

Remi ROBERT 1.8k Dec 29, 2022
Dotzu In-App iOS Debugging Tool With Enhanced Logging, Networking Info, Crash reporting And More.

Dotzu In-App iOS Debugging Tool With Enhanced Logging, Networking Info, Crash reporting And More. The debugger tool for iOS developer. Display logs, n

Remi ROBERT 1.8k Jan 3, 2023
blued enhanced tweak for iOS

BLUEDHOOK 本项目支持 Blued、Blued 极速版。 非越狱机型请通过 Monkeydev 环境打包 ipa 或 dylib/deb 进行重签名,越狱机型直接安装 release deb 即可。 已知问题 重签后不支持 apns 推送 同时安装 Blued、Blued 极速版 并登录同一

null 22 Oct 22, 2022
A enhanced JSON decoder.

JSONDecoderEx A enhanced JSON decoder. Usage struct User: Codable { struct Role: OptionSet, Codable, CustomStringConvertible { let rawValu

SAGESSE-CN 105 Dec 19, 2022
A enhanced JSON decoder.

JSONDecoderEx A enhanced JSON decoder. Usage struct User: Codable { struct Role: OptionSet, Codable, CustomStringConvertible { let rawValu

SAGESSE-CN 105 Dec 19, 2022
A marriage between the Shazam Discover UI and Tinder, built with UICollectionView in Swift.

VerticalCardSwiper A marriage between the Shazam Discover UI and Tinder, built with UICollectionView in Swift. Project goal and information The goal o

Joni Van Roost 1.2k Dec 28, 2022
Cool wave like transition between two or more UICollectionView

CKWaveCollectionViewTransition This is a cool custom transition between two or more UICollectionViewControllers with wave-like cell animation. Could b

Cezary Kopacz 1.9k Oct 4, 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
Tool to debug layouts directly on iOS devices: inspect layers in 3D and debug each visible view attributes

Introduction Features Inspect layouts directly on iOS devices Inspection could be triggered only if app is running under DEBUG build configuration, so

Ihor Savynskyi 510 Dec 24, 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
iOS app built with UIKit and programatic auto-layouts to learn and apply knowledge. Offline storage using CoreData and Caching

PurpleImage Search Pixabay for images and save them offline to share and view To use: Clone the GitHub project, build and run in Xcode. The API is com

Frederico Kückelhaus 0 May 10, 2022
A collection of native SwiftUI layouts (iOS 16+)

SwiftUILayouts A library of commonly requested layouts. Implemented using SwiftUI's native layout system. NOTE: SwiftUILayouts requires iOS 16 or abov

Apptek Studios 25 Dec 26, 2022