1。 AFNetWorking能夠完美替換 ASIHttpRequest, 而且使用起來超級簡單。 算法
2。 ATPagingView 能夠用來作多頁的翻頁滑動,而且採用了和UITableView相似的回收機制。 json
3。 經過一個存儲在NSUserDefault中的一個變量來判斷上次退出程序是由於異常退出仍是正常退出,異常退出的標準就是, 退出時沒有去把NSUserDefaults中的這個變量置成YES, 而正常的狀況下,是會調用 服務器
- (void)applicationDidEnterBackground:(UIApplication *)application, 在這裏面咱們會把這個值置成YES. 網絡
而若是進入程序時,檢查這個存儲在NSUserDefaults中的這個變量, 就能夠知道上次退出程序是不是異常退出,若是是, 則能夠作一些環境的操做。 app
4。 在輸入TextField值,如輸入用戶名時,能夠增長一個自動選擇歷史記錄,或者自動補齊功能。經過 異步
XXSelectTableView, 這個類來實現, 可是這個類藕合性太強,主要是在執行裏面的清除操做, 應該是經過 ui
XXSelectTableView它的代碼來執行,而不是直接去執行, 這樣便於把它分離出來。 atom
5。 TKAlertCenter能夠用來顯示幾秒鐘自動消失的相似AlertView的提示信息, 其實現原理是直接在Windows的最頂層顯示了一個UIView, 而後這個UIView在幾秒鐘的時間後自動消失。 spa
6。 KeyboardToolbar,用來實現多個輸入框時的上一項,下一項功能。 (該功能不支持輸入框是下拉框的狀況,也不支持混用的狀況,若是須要的話,能夠參考JSFund的代碼) .net
使用時:
a:// keyboard
self.keyboardbar = [[[KeyboardToolbar alloc] init] autorelease];
self.keyboardbar.showDelegate = self;
[self.keyboardbar addTextView:self.usernameTextField];
[self.keyboardbar addTextView:self.passwordTextField];
b:在viewWillAppear中執行,
[self.keyboardbar addKeyboardObserver];
c:在
viewDidDisappear中執行
[self.keyboardbar removeKeyboardObserver];
d:釋放時:
[self.keyboardbar clean];
e:在文本輸入回調中,
- (void)textFieldDidBeginEditing:(NMTextField *)textField, 執行
[self.keyboardbar setActiveTextView:textField];
7。經過ASIHttpRequest或者AFNetworking來作網絡請求後,服務端會返回數據給客戶端,爲了更好地減小網絡傳輸的壓力,能夠和服務器進行商定,把傳輸過來的數據先進行壓縮,客戶端取到數據後,再執行解壓便可, 下面的這個算法能夠減小約50%的數據傳輸量。(簡單地說,就是回來的NSData, 再調用response2Dictionary, 轉化爲Dictionary,在轉化前,將會調用解壓縮算法)
@implementation NSData(GZip)
- (NSData *)gzipUnpack {
if ([self length] < 3)// 若是字節數過小, 則不知足是gzip的狀況,直接返回便可
return self;
Byte *header = (Byte*)[self bytes];
if (header[0] == 0x1f && header[1]==0x8b) { // if gzip, 這裏能夠判斷出是gzip類型
unsigned full_length = [self length];
unsigned half_length = [self length] / 2;
NSMutableData *decompressed = [NSMutableData dataWithLength: full_length + half_length];
BOOL done = NO;
int status;
z_stream strm;
strm.next_in = (Bytef *)[self bytes];
strm.avail_in = [self length];
strm.total_out = 0;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
if (inflateInit2(&strm, (15+32)) != Z_OK)
return nil;
while (!done) {
// Make sure we have enough room and reset the lengths.
if (strm.total_out >= [decompressed length])
[decompressed increaseLengthBy: half_length];
strm.next_out = [decompressed mutableBytes] + strm.total_out;
strm.avail_out = [decompressed length] - strm.total_out;
// Inflate another chunk.
status = inflate (&strm, Z_SYNC_FLUSH);
if (status == Z_STREAM_END)
done = YES;
else if (status != Z_OK)
break;
}
if (inflateEnd (&strm) != Z_OK) return nil;
// Set real length.
if (done) {
[decompressed setLength: strm.total_out];
return [NSData dataWithData: decompressed];
}
}
return self;
}
- (NSDictionary *)response2Dictionary {
NSData *jsonData = [self gzipUnpack];
// parse response data to dictionary
NSError *error = nil;
NSDictionary *items = nil;
if ([[UIDevice currentDevice].systemVersion floatValue] >= 5.0)
items = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
else
items = [jsonData objectFromJSONDataWithParseOptions:JKParseOptionLooseUnicode error:&error];
if (!error && items)
return items;
else
return nil;
}
CALayer *horizontalLine = [CALayer layer];
horizontalLine.frame = CGRectMake(0, self.view.frame.size.height / 2, self.view.frame.size.width, 1);
horizontalLine.backgroundColor = [UIColor blueColor].CGColor;
[self.view.layer addSublayer:horizontalLine];
CALayer *verticalLine = [CALayer layer];
verticalLine.frame = CGRectMake(self.view.frame.size.width / 2,
0, 1, self.view.frame.size.height);
verticalLine.backgroundColor = [UIColor redColor].CGColor;
[self.view.layer addSublayer:verticalLine];
#import <QuartzCore/QuartzCore.h>並導入這個QuartzCore.framework
9。 UITableView的向上滑時,底部須要請求時,如每次只從新請求20條數據, 用以下代碼, 而後在loadMoreTableViewData中進行新20條數據的請求,請求到數據後,再直接更新整個tableView。就能夠作到不斷上滑的過程當中,若是有數據,則會不斷的請求,直到沒有數據爲止,注意,請求時,以異步請求比較好。
self.moreFooterView = [[[ODLoadMoreControl alloc]initInScrollView:self.uitableView] autorelease];
self.moreFooterView.backgroundColor = [UIColor clearColor];
[self.moreFooterView addTarget:selfaction:@selector(loadMoreTableViewData)forControlEvents:UIControlEventValueChanged];
self.uitableView.tableFooterView = self.moreFooterView;
注:ODLoadMoreControl頭文件以下:
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
@interface ODLoadMoreControl : UIControl
@property (nonatomic, retain) UILabel *statusLabel;
@property (nonatomic, retain) UIActivityIndicatorView *activityView;
- (id)initInScrollView:(UIScrollView *)scrollView;
- (void)beginRefreshing;
- (void)endRefreshing;
#import "ODLoadMoreControl.h"
#import "UIColor+View.h"
#define kTotalViewHeight 50.0f
#define TEXT_COLOR [UIColor colorWithRed:87.0/255.0 green:108.0/255.0blue:137.0/255.0 alpha:1.0]
#define FLIP_ANIMATION_DURATION 0.18f
@interface ODLoadMoreControl ()
@property (nonatomic, assign) BOOL refreshing;
@property (nonatomic, assign) UIScrollView *scrollView;
@property (nonatomic, assign) UIEdgeInsets originalContentInset;
@implementation ODLoadMoreControl
@synthesize refreshing = _refreshing;
@synthesize scrollView = _scrollView;
@synthesize originalContentInset = _originalContentInset;
@synthesize statusLabel = _statusLabel;
@synthesize activityView = _activityView;
- (void)dealloc
{
[self.scrollView removeObserver:self forKeyPath:@"contentOffset"];
[self.scrollView removeObserver:self forKeyPath:@"contentInset"];
self.scrollView = nil;
[_statusLabel release];
[super dealloc];
}
- (id)initInScrollView:(UIScrollView *)scrollView {
return [self initInScrollView:scrollView activityIndicatorView:nil];
}
- (id)initInScrollView:(UIScrollView *)scrollView activityIndicatorView:(UIView *)activity
{
self = [super initWithFrame:CGRectMake(0, 0, scrollView.frame.size.width, kTotalViewHeight)];
if (self) {
self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
self.backgroundColor = [UIColor viewBkGrayColor];
self.scrollView = scrollView;
self.originalContentInset = scrollView.contentInset;
self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[scrollView addSubview:self];
[scrollView addObserver:self forKeyPath:@"contentOffset"options:NSKeyValueObservingOptionNew context:nil];
[scrollView addObserver:self forKeyPath:@"contentInset"options:NSKeyValueObservingOptionNew context:nil];
self.activityView = [[[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]autorelease];
self.activityView.frame = CGRectMake(self.frame.size.width/2-100.0f, 13.0f, 20.0f, 20.0f);
self.activityView.autoresizingMask =UIViewAutoresizingFlexibleLeftMargin |UIViewAutoresizingFlexibleRightMargin;
if ([self.activityViewrespondsToSelector:@selector(startAnimating)]) {
[self.activityView startAnimating];
}
[self addSubview:self.activityView];
//說明文字下拉
self.statusLabel = [[[UILabel alloc]initWithFrame:CGRectMake(0.0f,13.0f,self.frame.size.width,20.0f) ]autorelease];
self.statusLabel.autoresizingMask=UIViewAutoresizingFlexibleWidth;
self.statusLabel.font = [UIFont systemFontOfSize:12.0f];
self.statusLabel.textColor = [UIColor blackColor];
self.statusLabel.shadowColor = [UIColor colorWithWhite:0.9falpha:1.0f];
self.statusLabel.shadowOffset =CGSizeMake(0.0f,1.0f);
self.statusLabel.backgroundColor = [UIColor clearColor];
self.statusLabel.textAlignment = UITextAlignmentCenter;
self.statusLabel.text = @"加載中...";
[self addSubview:self.statusLabel];
self.refreshing = NO;
}
return self;
}
- (void)willMoveToSuperview:(UIView *)newSuperview
{
[super willMoveToSuperview:newSuperview];
if (!newSuperview) {
[self.scrollView removeObserver:self forKeyPath:@"contentOffset"];
[self.scrollView removeObserver:self forKeyPath:@"contentInset"];
self.scrollView = nil;
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (self.scrollView && [keyPath isEqualToString:@"contentOffset"]) {
CGFloat offset = [[change objectForKey:@"new"] CGPointValue].y;
if (offset > 10 && offset +kTotalViewHeight+self.scrollView.frame.size.height >=self.scrollView.contentSize.height-self.scrollView.frame.size.height) {
if (!self.refreshing) {
self.refreshing = YES;
[selfsendActionsForControlEvents:UIControlEventValueChanged];
}
}
}
}
- (void)beginRefreshing
{
if (!_refreshing) {
CGPoint offset = self.scrollView.contentOffset;
[self.scrollView setContentOffset:offset animated:NO];
self.refreshing = YES;
}
}
- (void)endRefreshing
{
if (_refreshing) {
self.refreshing = NO;
}
}
而後就能實如今有數據時, 不斷向上滑動過程當中, 就會不斷地自動進行請求。EGOMoreTableFooterView來作向上滑動時,提示,「上拉加載更多」, 「鬆開便可加載」, 而後會請求新數據。
使用以下:
EGOMoreTableFooterView *moreView = [[EGOMoreTableFooterView alloc]initWithFrame:CGRectMake(0.0f,self.uitableView.tableFooterView.frame.size.height,self.uitableView.frame.size.width, self.uitableView.bounds.size.height)];
moreView.delegate = self;
[self.uitableView.tableFooterView addSubview:moreView];
// self.uitableView.tableFooterView = moreView;這是另外一種方式
self.moreFooterView = moreView;
[moreView release];
- (void)egoMoreTableFooterDidTriggerMore:(EGOMoreTableFooterView *)view {
[self performSelector:@selector(reloadTableViewFooterDataSource)withObject:nil afterDelay:0.0f];
// 作刷新後的動做,通常爲網絡的從新請求
}
- (BOOL)egoMoreTableFooterDataSourceIsLoading:(EGOMoreTableFooterView*)view {
return _loadingmore;// 這個變量表示是否正在作請求
}
- (NSDate *)egoMoreTableFooterDataSourceLastUpdated:(EGOMoreTableFooterView *)view {
return [NSDate date];// 當前刷新的日期,用以顯示上次刷新時間
}
ODRefreshControl
使用代碼以下:self.refreshControl = [[[ODRefreshControl alloc]initInScrollView:self.uitableView] autorelease];
self.refreshControl.backgroundColor = [UIColor viewBkGrayColor];
self.refreshControl.tintColor = [UIColor lightGrayColor];
[self.refreshControl addTarget:selfaction:@selector(refreshTableViewData)forControlEvents:UIControlEventValueChanged];
refreshTableViewData方法中, 從新請求數據,並使用當前的界面中的數據刷新便可。