mirror of
https://github.com/wu736139669/Doctor.git
synced 2026-08-07 06:14:35 +00:00
new
This commit is contained in:
Generated
+19
@@ -0,0 +1,19 @@
|
||||
Copyright (C) 2011 by BJ Basañes, http://shikii.net
|
||||
|
||||
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.
|
||||
Generated
+28
@@ -0,0 +1,28 @@
|
||||
|
||||
STableViewController
|
||||
====================================================================================================
|
||||
|
||||
STableViewController is a custom table view controller that supports **pull-to-refresh** and
|
||||
**load-more**. It was designed to have views and behaviors that can be easily customized.
|
||||
|
||||
See the demo project in `Demo/Demo.xcodeproj`.
|
||||
|
||||
|
||||
Usage
|
||||
----------------------------------------------------------------------------------------------------
|
||||
To start, simply copy `STableViewController.h` and `STableViewController.m` into your project file.
|
||||
|
||||
STableViewController is not very useful on its own. It has to be subclassed to apply your custom
|
||||
views and adjust any behavior. To get started quickly, you may include these files for reference:
|
||||
|
||||
* `DemoTableViewController` - subclass of `STableViewController`. This declares what views
|
||||
to use for pull-to-refresh and load-more. Also includes samples on what methods to override
|
||||
for data loading and a sample customization to interact with the header and footer views
|
||||
depending on the situation.
|
||||
* `DemoTableHeaderView` - the view used for pull-to-refresh
|
||||
* `DemoTableFooterView` - the view used for load-more
|
||||
|
||||
You may also opt to implement your own subclass for `STableViewController` and use your own
|
||||
views for pull-to-refresh and load-more.
|
||||
|
||||
See `STableViewController.h` for more information on the methods available.
|
||||
@@ -0,0 +1,103 @@
|
||||
//
|
||||
// STableViewController.h
|
||||
//
|
||||
// @author Shiki
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
||||
@interface STableViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
|
||||
|
||||
@protected
|
||||
|
||||
BOOL isDragging;
|
||||
BOOL isRefreshing;
|
||||
BOOL isLoadingMore;
|
||||
|
||||
// had to store this because the headerView's frame seems to be changed somewhere during scrolling
|
||||
// and I couldn't figure out why >.<
|
||||
CGRect headerViewFrame;
|
||||
}
|
||||
|
||||
// The view used for "pull to refresh"
|
||||
@property (nonatomic, retain) UIView *headerView;
|
||||
|
||||
// The view used for "load more"
|
||||
@property (nonatomic, retain) UIView *footerView;
|
||||
|
||||
@property (nonatomic, retain) UITableView *tableView;
|
||||
@property (readonly) BOOL isDragging;
|
||||
@property (readonly) BOOL isRefreshing;
|
||||
@property (readonly) BOOL isLoadingMore;
|
||||
@property (nonatomic) BOOL canLoadMore;
|
||||
|
||||
@property (nonatomic) BOOL pullToRefreshEnabled;
|
||||
|
||||
// Defaults to YES
|
||||
@property (nonatomic) BOOL clearsSelectionOnViewWillAppear;
|
||||
|
||||
// Just a common initialize method
|
||||
- (void) initialize;
|
||||
|
||||
#pragma mark - Pull to Refresh
|
||||
|
||||
// The minimum height that the user should drag down in order to trigger a "refresh" when
|
||||
// dragging ends.
|
||||
- (CGFloat) headerRefreshHeight;
|
||||
|
||||
// Will be called if the user drags down which will show the header view. Override this to
|
||||
// update the header view (e.g. change the label to "Pull down to refresh").
|
||||
- (void) willShowHeaderView:(UIScrollView *)scrollView;
|
||||
|
||||
// If the user is dragging, will be called on every scroll event that the headerView is shown.
|
||||
// The value of willRefreshOnRelease will be YES if the user scrolled down enough to trigger a
|
||||
// "refresh" when the user releases the drag.
|
||||
- (void) headerViewDidScroll:(BOOL)willRefreshOnRelease scrollView:(UIScrollView *)scrollView;
|
||||
|
||||
// By default, will permanently show the headerView by setting the tableView's contentInset.
|
||||
- (void) pinHeaderView;
|
||||
|
||||
// Reverse of pinHeaderView.
|
||||
- (void) unpinHeaderView;
|
||||
|
||||
// Called when the user stops dragging and, if the conditions are met, will trigger a refresh.
|
||||
- (void) willBeginRefresh;
|
||||
|
||||
// Override to perform fetching of data. The parent method [super refresh] should be called first.
|
||||
// If the value is NO, -refresh should be aborted.
|
||||
- (BOOL) refresh;
|
||||
|
||||
// Call to signal that refresh has completed. This will then hide the headerView.
|
||||
- (void) refreshCompleted;
|
||||
|
||||
#pragma mark - Load More
|
||||
|
||||
// The value of the height starting from the bottom that the user needs to scroll down to in order
|
||||
// to trigger -loadMore. By default, this will be the height of -footerView.
|
||||
- (CGFloat) footerLoadMoreHeight;
|
||||
|
||||
// Override to perform fetching of next page of data. It's important to call and get the value of
|
||||
// of [super loadMore] first. If it's NO, -loadMore should be aborted.
|
||||
- (BOOL) loadMore;
|
||||
|
||||
// Called when all the conditions are met and -loadMore will begin.
|
||||
- (void) willBeginLoadingMore;
|
||||
|
||||
// Call to signal that "load more" was completed. This should be called so -isLoadingMore is
|
||||
// properly set to NO.
|
||||
- (void) loadMoreCompleted;
|
||||
|
||||
// Helper to show/hide -footerView
|
||||
- (void) setFooterViewVisibility:(BOOL)visible;
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// A helper method that calls refreshCompleted and/or loadMoreCompleted if any are active.
|
||||
- (void) allLoadingCompleted;
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void) releaseViewComponents;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,326 @@
|
||||
//
|
||||
// STableViewController.m
|
||||
//
|
||||
// @author Shiki
|
||||
//
|
||||
|
||||
#import "STableViewController.h"
|
||||
|
||||
#define DEFAULT_HEIGHT_OFFSET 52.0f
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@implementation STableViewController
|
||||
|
||||
@synthesize tableView;
|
||||
@synthesize headerView;
|
||||
@synthesize footerView;
|
||||
|
||||
@synthesize isDragging;
|
||||
@synthesize isRefreshing;
|
||||
@synthesize isLoadingMore;
|
||||
|
||||
@synthesize canLoadMore;
|
||||
|
||||
@synthesize pullToRefreshEnabled;
|
||||
|
||||
@synthesize clearsSelectionOnViewWillAppear;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (void) initialize
|
||||
{
|
||||
pullToRefreshEnabled = YES;
|
||||
|
||||
canLoadMore = YES;
|
||||
|
||||
clearsSelectionOnViewWillAppear = YES;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (id) init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
[self initialize];
|
||||
return self;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (id) initWithCoder:(NSCoder *)aDecoder
|
||||
{
|
||||
if ((self = [super initWithCoder:aDecoder]))
|
||||
[self initialize];
|
||||
return self;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (void) viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
self.tableView = [[[UITableView alloc] init] autorelease];
|
||||
tableView.frame = self.view.bounds;
|
||||
tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
tableView.dataSource = self;
|
||||
tableView.delegate = self;
|
||||
|
||||
[self.view addSubview:tableView];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (void) viewWillAppear:(BOOL)animated
|
||||
{
|
||||
[super viewWillAppear:animated];
|
||||
|
||||
if (clearsSelectionOnViewWillAppear) {
|
||||
NSIndexPath *selected = [self.tableView indexPathForSelectedRow];
|
||||
if (selected)
|
||||
[self.tableView deselectRowAtIndexPath:selected animated:animated];
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark - Pull to Refresh
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (void) setHeaderView:(UIView *)aView
|
||||
{
|
||||
if (!tableView)
|
||||
return;
|
||||
|
||||
if (headerView && [headerView isDescendantOfView:tableView])
|
||||
[headerView removeFromSuperview];
|
||||
[headerView release]; headerView = nil;
|
||||
|
||||
if (aView) {
|
||||
headerView = [aView retain];
|
||||
|
||||
CGRect f = headerView.frame;
|
||||
headerView.frame = CGRectMake(f.origin.x, 0 - f.size.height, f.size.width, f.size.height);
|
||||
headerViewFrame = headerView.frame;
|
||||
|
||||
[tableView addSubview:headerView];
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (CGFloat) headerRefreshHeight
|
||||
{
|
||||
if (!CGRectIsEmpty(headerViewFrame))
|
||||
return headerViewFrame.size.height;
|
||||
else
|
||||
return DEFAULT_HEIGHT_OFFSET;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (void) pinHeaderView
|
||||
{
|
||||
[UIView animateWithDuration:0.3 animations:^(void) {
|
||||
self.tableView.contentInset = UIEdgeInsetsMake([self headerRefreshHeight], 0, 0, 0);
|
||||
}];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (void) unpinHeaderView
|
||||
{
|
||||
[UIView animateWithDuration:0.3 animations:^(void) {
|
||||
self.tableView.contentInset = UIEdgeInsetsZero;
|
||||
}];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (void) willBeginRefresh
|
||||
{
|
||||
if (pullToRefreshEnabled)
|
||||
[self pinHeaderView];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (void) willShowHeaderView:(UIScrollView *)scrollView
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (void) headerViewDidScroll:(BOOL)willRefreshOnRelease scrollView:(UIScrollView *)scrollView
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (BOOL) refresh
|
||||
{
|
||||
if (isRefreshing)
|
||||
return NO;
|
||||
|
||||
[self willBeginRefresh];
|
||||
isRefreshing = YES;
|
||||
return YES;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (void) refreshCompleted
|
||||
{
|
||||
isRefreshing = NO;
|
||||
|
||||
if (pullToRefreshEnabled)
|
||||
[self unpinHeaderView];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark - Load More
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (void) setFooterView:(UIView *)aView
|
||||
{
|
||||
if (!tableView)
|
||||
return;
|
||||
|
||||
tableView.tableFooterView = nil;
|
||||
[footerView release]; footerView = nil;
|
||||
|
||||
if (aView) {
|
||||
footerView = [aView retain];
|
||||
|
||||
tableView.tableFooterView = footerView;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (void) willBeginLoadingMore
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (void) loadMoreCompleted
|
||||
{
|
||||
isLoadingMore = NO;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (BOOL) loadMore
|
||||
{
|
||||
if (isLoadingMore)
|
||||
return NO;
|
||||
|
||||
[self willBeginLoadingMore];
|
||||
isLoadingMore = YES;
|
||||
return YES;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (CGFloat) footerLoadMoreHeight
|
||||
{
|
||||
if (footerView)
|
||||
return footerView.frame.size.height;
|
||||
else
|
||||
return DEFAULT_HEIGHT_OFFSET;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (void) setFooterViewVisibility:(BOOL)visible
|
||||
{
|
||||
if (visible && self.tableView.tableFooterView != footerView)
|
||||
self.tableView.tableFooterView = footerView;
|
||||
else if (!visible)
|
||||
self.tableView.tableFooterView = nil;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (void) allLoadingCompleted
|
||||
{
|
||||
if (isRefreshing)
|
||||
[self refreshCompleted];
|
||||
if (isLoadingMore)
|
||||
[self loadMoreCompleted];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark - UIScrollViewDelegate
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (void) scrollViewWillBeginDragging:(UIScrollView *)scrollView
|
||||
{
|
||||
if (isRefreshing)
|
||||
return;
|
||||
isDragging = YES;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (void) scrollViewDidScroll:(UIScrollView *)scrollView
|
||||
{
|
||||
if (!isRefreshing && isDragging && scrollView.contentOffset.y < 0) {
|
||||
[self headerViewDidScroll:scrollView.contentOffset.y < 0 - [self headerRefreshHeight]
|
||||
scrollView:scrollView];
|
||||
} else if (!isLoadingMore && canLoadMore) {
|
||||
CGFloat scrollPosition = scrollView.contentSize.height - scrollView.frame.size.height - scrollView.contentOffset.y;
|
||||
if (scrollPosition < [self footerLoadMoreHeight]) {
|
||||
[self loadMore];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
|
||||
{
|
||||
if (isRefreshing)
|
||||
return;
|
||||
|
||||
isDragging = NO;
|
||||
if (scrollView.contentOffset.y <= 0 - [self headerRefreshHeight]) {
|
||||
if (pullToRefreshEnabled)
|
||||
[self refresh];
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark - UITableViewDelegate
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (void) releaseViewComponents
|
||||
{
|
||||
[headerView release]; headerView = nil;
|
||||
[footerView release]; footerView = nil;
|
||||
[tableView release]; tableView = nil;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (void) dealloc
|
||||
{
|
||||
[self releaseViewComponents];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
- (void) viewDidUnload
|
||||
{
|
||||
[self releaseViewComponents];
|
||||
[super viewDidUnload];
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user