Skip to content

Instantly share code, notes, and snippets.

@ahmattox
Created March 24, 2013 19:07
Show Gist options
  • Save ahmattox/5233088 to your computer and use it in GitHub Desktop.
Save ahmattox/5233088 to your computer and use it in GitHub Desktop.
UITableView Sorting with Animations
//
// main.m
// TableViewTest
//
// Created by Anthony Mattox on 2/27/13.
// Copyright (c) 2013 Friends of The Web. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "TTAppDelegate.h"
int main(int argc, char *argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([TTAppDelegate class]));
}
}
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="2.0" toolsVersion="3084" systemVersion="12C60" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" initialViewController="2">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="2083"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="5">
<objects>
<viewController id="2" customClass="TTViewController" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="3">
<rect key="frame" x="0.0" y="20" width="320" height="548"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" rowHeight="70" sectionHeaderHeight="22" sectionFooterHeight="22" id="HZt-Lb-kgm">
<rect key="frame" x="0.0" y="54" width="320" height="494"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<prototypes>
<tableViewCell contentMode="scaleToFill" selectionStyle="blue" indentationWidth="10" reuseIdentifier="cell" rowHeight="70" id="cOc-IN-VM0" customClass="TTCell">
<rect key="frame" x="0.0" y="22" width="320" height="70"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="320" height="69"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<view contentMode="scaleToFill" id="RhA-Y3-H8r">
<rect key="frame" x="0.0" y="0.0" width="320" height="69"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="SOb-ba-WB2">
<rect key="frame" x="20" y="24" width="193" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<color key="highlightedColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Label" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="wwT-Cb-S3W">
<rect key="frame" x="211" y="24" width="82" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<color key="highlightedColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</label>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<connections>
<outlet property="backgroundView" destination="RhA-Y3-H8r" id="sbN-lF-0bw"/>
<outlet property="orderLabel" destination="wwT-Cb-S3W" id="M5O-4v-6Zt"/>
<outlet property="titleLabel" destination="SOb-ba-WB2" id="ldP-eF-tvn"/>
</connections>
</tableViewCell>
</prototypes>
<connections>
<outlet property="dataSource" destination="2" id="zeI-Yb-l5L"/>
<outlet property="delegate" destination="2" id="svZ-3t-QHC"/>
</connections>
</tableView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="WWK-b2-ayi">
<rect key="frame" x="6" y="5" width="108" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" title="Randomize">
<color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<state key="highlighted">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="randomizePresseed:" destination="2" eventType="touchUpInside" id="vUx-Qo-O2v"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="8WJ-lg-wrH">
<rect key="frame" x="118" y="5" width="95" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" title="Sort">
<color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<state key="highlighted">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="sortPressed:" destination="2" eventType="touchUpInside" id="Srz-zx-BOm"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="CB0-Sz-Fer">
<rect key="frame" x="217" y="5" width="95" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" title="Rainbow!">
<color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<state key="highlighted">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="rainbowPressed:" destination="2" eventType="touchUpInside" id="Z5w-2M-ky9"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
<connections>
<outlet property="tableView" destination="HZt-Lb-kgm" id="rrU-nr-Htw"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="4" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="415" y="263"/>
</scene>
</scenes>
<classes>
<class className="TTCell" superclassName="UITableViewCell">
<source key="sourceIdentifier" type="project" relativePath="./Classes/TTCell.h"/>
<relationships>
<relationship kind="outlet" name="backgroundView" candidateClass="UIView"/>
<relationship kind="outlet" name="orderLabel" candidateClass="UILabel"/>
<relationship kind="outlet" name="titleLabel" candidateClass="UILabel"/>
</relationships>
</class>
<class className="TTViewController" superclassName="UIViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/TTViewController.h"/>
<relationships>
<relationship kind="outlet" name="tableView" candidateClass="UITableView"/>
</relationships>
</class>
</classes>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4"/>
</simulatedMetricsContainer>
</document>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>com.friendsoftheweb.${PRODUCT_NAME:rfc1034identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIMainStoryboardFile</key>
<string>MainStoryboard</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
//
// Prefix header for all source files of the 'TableViewTest' target in the 'TableViewTest' project
//
#import <Availability.h>
#ifndef __IPHONE_5_0
#warning "This project uses features only available in iOS SDK 5.0 and later."
#endif
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#endif
//
// TTAppDelegate.h
// TableViewTest
//
// Created by Anthony Mattox on 2/27/13.
// Copyright (c) 2013 Friends of The Web. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface TTAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
//
// TTAppDelegate.m
// TableViewTest
//
// Created by Anthony Mattox on 2/27/13.
// Copyright (c) 2013 Friends of The Web. All rights reserved.
//
#import "TTAppDelegate.h"
@implementation TTAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
return YES;
}
@end
//
// TTCell.h
// TableViewTest
//
// Created by Anthony Mattox on 2/27/13.
// Copyright (c) 2013 Friends of The Web. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface TTCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
@property (weak, nonatomic) IBOutlet UIView *backgroundView;
@property (weak, nonatomic) IBOutlet UILabel *orderLabel;
@end
//
// TTCell.m
// TableViewTest
//
// Created by Anthony Mattox on 2/27/13.
// Copyright (c) 2013 Friends of The Web. All rights reserved.
//
#import "TTCell.h"
@implementation TTCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
@end
//
// TTCellData.h
// TableViewTest
//
// Created by Anthony Mattox on 2/28/13.
// Copyright (c) 2013 Friends of The Web. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface TTCellData : NSObject
@property (nonatomic, strong) UIColor *color;
@property (nonatomic) int identifier;
@property (nonatomic) int order;
- (id)initWithIdentifier:(int) identifier;
@end
//
// TTCellData.m
// TableViewTest
//
// Created by Anthony Mattox on 2/28/13.
// Copyright (c) 2013 Friends of The Web. All rights reserved.
//
#import "TTCellData.h"
@implementation TTCellData
- (id)initWithIdentifier:(int) identifier {
if (self = [super init]) {
self.color = [UIColor colorWithHue:((float)(arc4random()%255)) / 255 saturation:.4 brightness:.8 alpha:1];
self.order = arc4random() % 100;
_identifier = identifier;
}
return self;
}
@end
//
// TTViewController.h
// TableViewTest
//
// Created by Anthony Mattox on 2/27/13.
// Copyright (c) 2013 Friends of The Web. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface TTViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@end
//
// TTViewController.m
// TableViewTest
//
// Created by Anthony Mattox on 2/27/13.
// Copyright (c) 2013 Friends of The Web. All rights reserved.
//
#import "TTViewController.h"
#import "TTCellData.h"
#import "TTCell.h"
#define kNumberOfItems 12
@interface TTViewController ()
@property (nonatomic, strong) NSArray *tableData;
@property (nonatomic) BOOL switchRainbow;
@end
@implementation TTViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:kNumberOfItems];
for (int i=0; i< kNumberOfItems ; i++) {
[array addObject:[[TTCellData alloc] initWithIdentifier:i]];
}
self.tableData = [NSArray arrayWithArray:array];
}
- (void) randomizeOrder {
for (TTCellData *data in _tableData) {
data.order = arc4random() % 100;
}
}
#pragma mark - Actions
- (IBAction)randomizePresseed:(id)sender {
[self randomizeOrder];
[_tableView reloadData];
}
- (IBAction)sortPressed:(id)sender {
NSArray *oldData = [_tableData copy];
_tableData = [_tableData sortedArrayUsingComparator:^NSComparisonResult(TTCellData *data1, TTCellData *data2) {
return data1.order > data2.order;
}];
[self.tableView beginUpdates];
for (int i=0; i<oldData.count; i++) {
int newRow = [_tableData indexOfObject:[oldData objectAtIndex:i]];
[_tableView moveRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0] toIndexPath:[NSIndexPath indexPathForRow:newRow inSection:0]];
}
[self.tableView endUpdates];
}
- (IBAction)rainbowPressed:(id)sender {
NSArray *oldData = [_tableData copy];
_tableData = [_tableData sortedArrayUsingComparator:^NSComparisonResult(TTCellData *data1, TTCellData *data2) {
CGFloat hue1;
CGFloat hue2;
[data1.color getHue:&hue1 saturation:nil brightness:nil alpha:nil];
[data2.color getHue:&hue2 saturation:nil brightness:nil alpha:nil];
return (hue1 < hue2) != _switchRainbow;
}];
[self.tableView beginUpdates];
for (int i=0; i<oldData.count; i++) {
int newRow = [_tableData indexOfObject:[oldData objectAtIndex:i]];
[_tableView moveRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0] toIndexPath:[NSIndexPath indexPathForRow:newRow inSection:0]];
}
[self.tableView endUpdates];
_switchRainbow = !_switchRainbow;
}
#pragma mark - Table view
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _tableData.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TTCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
TTCellData *data = _tableData[indexPath.row];
cell.backgroundView.backgroundColor = data.color;
cell.titleLabel.text = [NSString stringWithFormat:@"Cell %i", data.identifier];
cell.orderLabel.text = [NSString stringWithFormat:@"%i", data.order];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
TTCellData *data = [_tableData objectAtIndex:indexPath.row];
data.order = arc4random() % 100;
[tableView deselectRowAtIndexPath:indexPath animated:NO];
[tableView reloadData];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment