1。 AFNetWorking可以完美替换 ASIHttpRequest, 并且使用起来超级简单。
2。 ATPagingView 可以用来做多页的翻页滑动,并且采用了和UITableView类似的回收机制。
3。 通过一个存储在NSUserDefault中的一个变量来判断上次退出程序是因为异常退出还是正常退出,异常退出的标准就是, 退出时没有去把NSUserDefaults中的这个变量置成YES, 而正常的情况下,是会调用
- (void)applicationDidEnterBackground:(UIApplication *)application, 在这里面我们会把这个值置成YES.
而如果进入程序时,检查这个存储在NSUserDefaults中的这个变量, 就可以知道上次退出程序是否是异常退出,如果是, 则可以做一些环境的操作。
4。 在输入TextField值,如输入用户名时,可以增加一个自动选择历史记录,或者自动补齐功能。通过
XXSelectTableView, 这个类来实现, 但是这个类藕合性太强,主要是在执行里面的清除操作, 应该是通过
XXSelectTableView它的代码来执行,而不是直接去执行, 这样便于把它分离出来。
5。 TKAlertCenter可以用来显示几秒钟自动消失的类似AlertView的提示信息, 其实现原理是直接在Windows的最顶层显示了一个UIView, 然后这个UIView在几秒钟的时间后自动消失。
6。 KeyboardToolbar,用来实现多个输入框时的上一项,下一项功能。 (该功能不支持输入框是下拉框的情况,也不支持混用的情况,如果需要的话,可以参考JSFund的代码)
使用时:
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];
上述代码会在屏幕中间画出十字条线出来,而不需要图片的处理, 为了使用CALayer需要添加
#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:self action:@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;
@end
#import "ODLoadMoreControl.h"
#import "UIColor+View.h"
#define kTotalViewHeight 50.0f
#define TEXT_COLOR [UIColor colorWithRed:87.0/255.0 green:108.0/255.0 blue: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;
@end
@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.activityView respondsToSelector:@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.9f alpha: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;
[self sendActionsForControlEvents: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;
}
}
@end
然后就能实现在有数据时, 不断向上滑动过程中, 就会不断地自动进行请求。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:self action:@selector(refreshTableViewData) forControlEvents:UIControlEventValueChanged];
refreshTableViewData方法中, 重新请求数据,并使用当前的界面中的数据刷新即可。