Permalink
Browse files

Add PullRefresh, rounded reply count label

but there is still a problem, where to removeObersever?
  • Loading branch information...
1 parent 1172eb9 commit eec1854ba14aa9f90d1ad0a3e395ba74f4bd39e2 @winfield committed Mar 8, 2012
@@ -0,0 +1,59 @@
+//
+// PullRefreshTableViewController.h
+// Plancast
+//
+// Created by Leah Culver on 7/2/10.
+// Copyright (c) 2010 Leah Culver
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#import <UIKit/UIKit.h>
+
+
+@interface PullRefreshTableViewController : UITableViewController {
+ UIView *refreshHeaderView;
+ UILabel *refreshLabel;
+ UIImageView *refreshArrow;
+ UIActivityIndicatorView *refreshSpinner;
+ BOOL isDragging;
+ BOOL isLoading;
+ NSString *textPull;
+ NSString *textRelease;
+ NSString *textLoading;
+}
+
+@property (nonatomic) UIView *refreshHeaderView;
+@property (nonatomic) UILabel *refreshLabel;
+@property (nonatomic) UIImageView *refreshArrow;
+@property (nonatomic) UIActivityIndicatorView *refreshSpinner;
+@property (nonatomic, copy) NSString *textPull;
+@property (nonatomic, copy) NSString *textRelease;
+@property (nonatomic, copy) NSString *textLoading;
+
+- (void)setupStrings;
+- (void)addPullToRefreshHeader;
+- (void)startLoading;
+- (void)stopLoading;
+- (void)refresh;
+
+@end
@@ -0,0 +1,181 @@
+//
+// PullRefreshTableViewController.m
+// Plancast
+//
+// Created by Leah Culver on 7/2/10.
+// Copyright (c) 2010 Leah Culver
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#import <QuartzCore/QuartzCore.h>
+#import "PullRefreshTableViewController.h"
+
+#define REFRESH_HEADER_HEIGHT 52.0f
+
+
+@implementation PullRefreshTableViewController
+
+@synthesize textPull, textRelease, textLoading, refreshHeaderView, refreshLabel, refreshArrow, refreshSpinner;
+
+- (id)initWithStyle:(UITableViewStyle)style {
+ self = [super initWithStyle:style];
+ if (self != nil) {
+ [self setupStrings];
+ }
+ return self;
+}
+
+- (id)initWithCoder:(NSCoder *)aDecoder {
+ self = [super initWithCoder:aDecoder];
+ if (self != nil) {
+ [self setupStrings];
+ }
+ return self;
+}
+
+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
+ self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
+ if (self != nil) {
+ [self setupStrings];
+ }
+ return self;
+}
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+ [self addPullToRefreshHeader];
+}
+
+- (void)setupStrings{
+ textPull = [[NSString alloc] initWithString:@"Pull down to refresh..."];
+ textRelease = [[NSString alloc] initWithString:@"Release to refresh..."];
+ textLoading = [[NSString alloc] initWithString:@"Loading..."];
+}
+
+- (void)addPullToRefreshHeader {
+ refreshHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0 - REFRESH_HEADER_HEIGHT, 320, REFRESH_HEADER_HEIGHT)];
+ refreshHeaderView.backgroundColor = [UIColor clearColor];
+
+ refreshLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, REFRESH_HEADER_HEIGHT)];
+ refreshLabel.backgroundColor = [UIColor clearColor];
+ refreshLabel.font = [UIFont boldSystemFontOfSize:12.0];
+ refreshLabel.textAlignment = UITextAlignmentCenter;
+
+ refreshArrow = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"arrow.png"]];
+ refreshArrow.frame = CGRectMake(floorf((REFRESH_HEADER_HEIGHT - 27) / 2),
+ (floorf(REFRESH_HEADER_HEIGHT - 44) / 2),
+ 27, 44);
+
+ refreshSpinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
+ refreshSpinner.frame = CGRectMake(floorf(floorf(REFRESH_HEADER_HEIGHT - 20) / 2), floorf((REFRESH_HEADER_HEIGHT - 20) / 2), 20, 20);
+ refreshSpinner.hidesWhenStopped = YES;
+
+ [refreshHeaderView addSubview:refreshLabel];
+ [refreshHeaderView addSubview:refreshArrow];
+ [refreshHeaderView addSubview:refreshSpinner];
+ [self.tableView addSubview:refreshHeaderView];
+}
+
+- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
+ if (isLoading) return;
+ isDragging = YES;
+}
+
+- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
+ if (isLoading) {
+ // Update the content inset, good for section headers
+ if (scrollView.contentOffset.y > 0)
+ self.tableView.contentInset = UIEdgeInsetsZero;
+ else if (scrollView.contentOffset.y >= -REFRESH_HEADER_HEIGHT)
+ self.tableView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
+ } else if (isDragging && scrollView.contentOffset.y < 0) {
+ // Update the arrow direction and label
+ [UIView beginAnimations:nil context:NULL];
+ if (scrollView.contentOffset.y < -REFRESH_HEADER_HEIGHT) {
+ // User is scrolling above the header
+ refreshLabel.text = self.textRelease;
+ [refreshArrow layer].transform = CATransform3DMakeRotation(M_PI, 0, 0, 1);
+ } else { // User is scrolling somewhere within the header
+ refreshLabel.text = self.textPull;
+ [refreshArrow layer].transform = CATransform3DMakeRotation(M_PI * 2, 0, 0, 1);
+ }
+ [UIView commitAnimations];
+ }
+}
+
+- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
+ if (isLoading) return;
+ isDragging = NO;
+ if (scrollView.contentOffset.y <= -REFRESH_HEADER_HEIGHT) {
+ // Released above the header
+ [self startLoading];
+ }
+}
+
+- (void)startLoading {
+ isLoading = YES;
+
+ // Show the header
+ [UIView beginAnimations:nil context:NULL];
+ [UIView setAnimationDuration:0.3];
+ self.tableView.contentInset = UIEdgeInsetsMake(REFRESH_HEADER_HEIGHT, 0, 0, 0);
+ refreshLabel.text = self.textLoading;
+ refreshArrow.hidden = YES;
+ [refreshSpinner startAnimating];
+ [UIView commitAnimations];
+
+ // Refresh action!
+ [self refresh];
+}
+
+- (void)stopLoading {
+ isLoading = NO;
+
+ // Hide the header
+ [UIView beginAnimations:nil context:NULL];
+ [UIView setAnimationDelegate:self];
+ [UIView setAnimationDuration:0.3];
+ [UIView setAnimationDidStopSelector:@selector(stopLoadingComplete:finished:context:)];
+ self.tableView.contentInset = UIEdgeInsetsZero;
+ UIEdgeInsets tableContentInset = self.tableView.contentInset;
+ tableContentInset.top = 0.0;
+ self.tableView.contentInset = tableContentInset;
+ [refreshArrow layer].transform = CATransform3DMakeRotation(M_PI * 2, 0, 0, 1);
+ [UIView commitAnimations];
+}
+
+- (void)stopLoadingComplete:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
+ // Reset the header
+ refreshLabel.text = self.textPull;
+ refreshArrow.hidden = NO;
+ [refreshSpinner stopAnimating];
+}
+
+- (void)refresh {
+ // This is just a demo. Override this method with your custom reload action.
+ // Don't forget to call stopLoading at the end.
+ [self performSelector:@selector(stopLoading) withObject:nil afterDelay:2.0];
+}
+
+
+@end
Submodule PullToRefresh added at 9da9a6
@@ -16,6 +16,8 @@
F3269DA2150390E100C7D2DA /* MainStoryboard_iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F3269DA0150390E100C7D2DA /* MainStoryboard_iPhone.storyboard */; };
F3269DA5150390E100C7D2DA /* MainStoryboard_iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F3269DA3150390E100C7D2DA /* MainStoryboard_iPad.storyboard */; };
F3269DA8150390E100C7D2DA /* RCITopicViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F3269DA7150390E100C7D2DA /* RCITopicViewController.m */; };
+ F36A861B1508B3E400A8DE8B /* arrow.png in Resources */ = {isa = PBXBuildFile; fileRef = F36A861A1508B3E400A8DE8B /* arrow.png */; };
+ F36A861F1508B6CE00A8DE8B /* PullRefreshTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F36A861E1508B6CE00A8DE8B /* PullRefreshTableViewController.m */; };
F3D546021503A59700F5A9E3 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3D546001503A59700F5A9E3 /* CFNetwork.framework */; };
F3D546031503A59700F5A9E3 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3D546011503A59700F5A9E3 /* CoreData.framework */; };
F3D546051503A5A600F5A9E3 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3D546041503A5A600F5A9E3 /* MobileCoreServices.framework */; };
@@ -81,6 +83,9 @@
F3269DA4150390E100C7D2DA /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/MainStoryboard_iPad.storyboard; sourceTree = "<group>"; };
F3269DA6150390E100C7D2DA /* RCITopicViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCITopicViewController.h; sourceTree = "<group>"; };
F3269DA7150390E100C7D2DA /* RCITopicViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCITopicViewController.m; sourceTree = "<group>"; };
+ F36A861A1508B3E400A8DE8B /* arrow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = arrow.png; sourceTree = "<group>"; };
+ F36A861D1508B6CE00A8DE8B /* PullRefreshTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PullRefreshTableViewController.h; path = ../PullRefreshTableViewController.h; sourceTree = "<group>"; };
+ F36A861E1508B6CE00A8DE8B /* PullRefreshTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PullRefreshTableViewController.m; path = ../PullRefreshTableViewController.m; sourceTree = "<group>"; };
F3D545EA1503A44D00F5A9E3 /* RestKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RestKit.xcodeproj; path = ../RestKit/RestKit.xcodeproj; sourceTree = "<group>"; };
F3D546001503A59700F5A9E3 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
F3D546011503A59700F5A9E3 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
@@ -100,9 +105,9 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ F3D5460B1503A5BC00F5A9E3 /* QuartzCore.framework in Frameworks */,
F3D5462B1503A76700F5A9E3 /* libRestKit.a in Frameworks */,
F3D5460D1503A5CE00F5A9E3 /* libxml2.dylib in Frameworks */,
- F3D5460B1503A5BC00F5A9E3 /* QuartzCore.framework in Frameworks */,
F3D546081503A5B000F5A9E3 /* Security.framework in Frameworks */,
F3D546091503A5B000F5A9E3 /* SystemConfiguration.framework in Frameworks */,
F3D546051503A5A600F5A9E3 /* MobileCoreServices.framework in Frameworks */,
@@ -165,6 +170,9 @@
F3D546401503B7BA00F5A9E3 /* RCITopic.m */,
F3D5464F1503B89E00F5A9E3 /* RCIUser.h */,
F3D546501503B89E00F5A9E3 /* RCIUser.m */,
+ F36A861D1508B6CE00A8DE8B /* PullRefreshTableViewController.h */,
+ F36A861E1508B6CE00A8DE8B /* PullRefreshTableViewController.m */,
+ F36A861A1508B3E400A8DE8B /* arrow.png */,
F3269D95150390E000C7D2DA /* Supporting Files */,
);
path = "Ruby China";
@@ -285,6 +293,7 @@
F3269D99150390E000C7D2DA /* InfoPlist.strings in Resources */,
F3269DA2150390E100C7D2DA /* MainStoryboard_iPhone.storyboard in Resources */,
F3269DA5150390E100C7D2DA /* MainStoryboard_iPad.storyboard in Resources */,
+ F36A861B1508B3E400A8DE8B /* arrow.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -300,6 +309,7 @@
F3269DA8150390E100C7D2DA /* RCITopicViewController.m in Sources */,
F3D546411503B7BA00F5A9E3 /* RCITopic.m in Sources */,
F3D546511503B89F00F5A9E3 /* RCIUser.m in Sources */,
+ F36A861F1508B6CE00A8DE8B /* PullRefreshTableViewController.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -8,7 +8,8 @@
#import <UIKit/UIKit.h>
#import <RestKit/RestKit.h>
+#import "PullRefreshTableViewController.h"
-@interface RCITopicViewController : UITableViewController <RKObjectLoaderDelegate>
+@interface RCITopicViewController : PullRefreshTableViewController <RKObjectLoaderDelegate>
@end
@@ -6,6 +6,7 @@
// Copyright (c) 2012 lainuo.info. All rights reserved.
//
+#import <QuartzCore/QuartzCore.h>
#import "RCITopicViewController.h"
#import "RCITopic.h"
@@ -35,8 +36,8 @@ - (void)viewDidLoad
{
[super viewDidLoad];
- RKObjectMapping *topicMappping = [[RKObjectManager sharedManager].mappingProvider objectMappingForClass:[RCITopic class]];
- [[RKObjectManager sharedManager] loadObjectsAtResourcePath:@"/api/topics.json" objectMapping:topicMappping delegate:self];
+ RKObjectMapping *topicMapping = [[RKObjectManager sharedManager].mappingProvider objectMappingForClass:[RCITopic class]];
+ [[RKObjectManager sharedManager] loadObjectsAtResourcePath:@"/api/topics.json" objectMapping:topicMapping delegate:self];
}
@@ -57,12 +58,14 @@ - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interface
#pragma mark - RKObjectLoaderDelegate
-- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {
+- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray *)objects {
self.topics = [objects copy];
+ NSLog(@"KKKKKK");
[self.topicTableView reloadData];
+ [self stopLoading];
}
-- (void)objectLoader:(RKObjectLoader*)objectLoader didFailWithError:(NSError*)error {
+- (void)objectLoader:(RKObjectLoader*)objectLoader didFailWithError:(NSError *)error {
}
#pragma mark - UITableViewDataSource
@@ -87,6 +90,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
nodeLabel.text = topic.nodeName;
UILabel *countLabel = (UILabel *)[cell viewWithTag:104];
countLabel.text = topic.repliesCount.stringValue;
+ countLabel.layer.cornerRadius = 4;
// cell.textLabel.text = topic.title;
if (![self.observedVisibleItems containsObject:topic.user]) {
@@ -119,6 +123,12 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
*/
}
+- (void)refresh
+{
+ RKObjectMapping *topicMapping = [[RKObjectManager sharedManager].mappingProvider objectMappingForClass:[RCITopic class]];
+ [[RKObjectManager sharedManager] loadObjectsAtResourcePath:@"/api/topics.json" objectMapping:topicMapping delegate:self];
+}
+
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:RCITopicPropertyNamedGravatar]) {
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.

0 comments on commit eec1854

Please sign in to comment.