1 自定义UITableViewCell
1.(1)要注意给此Cell设置大小.
[self setFrame:CGRectMake(0, 0, 320, 120)];
1.(2)初始化每个Cell中的控件,并且将其添加到Cell中
[self addSubview:picUIImageView];
2 协议的使用
在一个类的.h文件中定义一个协议,抛出数据
@protocol XmlRequestDelegate <NSObject>
- (void)validateRequestphotosInfos:(NSMutableArray *)photosInfos;
- (void)invalidateRequestphotosInfos:(NSString *)errorMessage;
@end
并且有一个属性
@property (retain, nonatomic) id<XmlRequestDelegate> xmlRequestDelegate;
在.m文件中,根据逻辑抛出数据
if ([self.xmlRequestDelegate respondsToSelector:@selector(validateRequestphotosInfos:)]) {
[self.xmlRequestDelegate validateRequestphotosInfos:photosInfo];
}
photosInfo即为抛出的数据
在另外的一个类中实现此协议,所以可以接收到抛出的数据;如
在.h文件中
@interface MainVC : MainBaseVC
<XmlRequestDelegate,UITableViewDelegate,UITableViewDataSource>
{
……………………………………………………………;
}
@property(nonatomic,retain) ……………………………………;
@end
在.文件中覆写协议中的方法
-(void) validateRequestphotosInfos:(NSMutableArray *)photosInfos{
[self setPhotosInfo:photosInfos];
//一定要有[self.uiTableView reloadData]方法,否则TableView中没有数据显示
[self.uiTableView reloadData];
}
在此将接到的数据photosInfos赋值给了自己的属性photosInfo
3 关于TableView的一些细节问题
去掉每个Cell之间的分割线,在委托方法cellForRowAtIndexPath中
[tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
当点击Cell的时候,取消蓝色的背景,否则此颜色会一直存在.在委托方法didSelectRowAtIndexPath中
[tableView deselectRowAtIndexPath:indexPath animated:YES];
在自定义的Cell中常需要设置Cell高度.在委托方法didSelectRowAtIndexPath中heightForRowAtIndexPath
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 80;
}
4 XML解析
导入第三方框架KissXml以后总是提示libxml/tree.h file not found
解决方式如下:
第一步 首先要确保在Frameworks下引入了libxml2.dylib
第二步 点击project下的图标 然后选Build Settings 然后点击All在Search Paths 找到Header Search Paths
可参见http://rss.9ria.com/?p=3670
第三步 给Header Search Paths下的Debug和Release添加如下代码:/usr/include/libxml2
可参见http://hi.baidu.com/����/blog/item/d06aff8bfc76d509c8fc7a99.html
KissXML解析XML的一般流程
(1) 请求xml数据,返回的是NSString
(2) 利用返回的NSString生成DDXMLDocument
(3) 从DDXMLDocument中获取所有的需要的节点,返回的是数组
DDXMLDocument *dDXMLDocument = [[DDXMLDocument alloc]
initWithXMLString:responseXMLString
options:DDXMLDocumentKind
error:&error];
NSArray *allPlacesNodes = [dDXMLDocument nodesForXPath:@"//result" error:&error];
(4) 利用DDXMLElement遍历此数组,得到每个有用的信息并解析封装
for (DDXMLElement *ddXMLElement in allPlacesNodes) {
Place *place1= [XMLParse parsePlaceInfoXML:ddXMLElement];
[placesInfo addObject:place1];
}
常用的XML解析方式可以参见项目SearchMe2中的XMLParse.m
5 状态栏和导航栏
//设置此页面的导航栏为隐藏
[self.navigationController setNavigationBarHidden:YES];
//设置整个应用的状态栏为透明
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent];
//设置整个应用的状态栏消失
[[UIApplication sharedApplication] setStatusBarHidden:YES];
//设置my自己的导航栏navigationBar为透明
mynavgation.navigationBar.barStyle=UIBarStyleBlackTranslucent;
6 内存管理
(1)在dealloc方法里面要首先调用[super dealloc],否则容易引起潜在的内存泄露
-(void)dealloc{
[super dealloc];
}
(2)在应用程序的…AppDelegate中避免内存泄露,应该这么写
_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
并且在-dealloc方法里面[_window release];
(3)利用自动释放池避免内存泄露
for(while)( ){
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *string=调用某个方法返回的值;
UIImage *image=调用某个方法返回的值;
MyClass *myclass=NSString *string=调用某个方法返回的值;
[pool release];
}
此for或者while循环次数很大,应该采用自动释放池,否则很可能造成内存泄露
(4)autorelease的例子
ThumbnailObject *obj = [_dataSource objectAtIndex:index];
thumbNailView.image = [[[UIImage alloc] initWithContentsOfFile:obj.imageURL] autorelease];
注意这里有alloc但是不能直接用release,所以采用autorelease避免内存泄露
(5)关于@property的声明
在@property的时候,若此对象是一个delegate对象那么使用使用assign,而不是retain!
在@property的时候,若此对象是一个NSString对象那么使用copy,而不是retain!
7 利用NSUserDefaults存取数据
存数据
[[NSUserDefaults standardUserDefaults] setValue:@"key" forKey:@"value"];
取数据
NSString *value=[[NSUserDefaults standardUserDefaults] valueForKey:@"value"];
注意NSUserDefaults只能存取已经实现了序列化的对象
若想自定义对象实现序列话可以将此类实现<NSCopying, NSCoding>协议,然后覆写其中的方法.具体代码可以参见RemindMe中的TipModelLoc.m
(1)//将一些自定义对象保存在NSMutableArray locsNSMutableArray中.然后将此数组保存到NSUserDefaults中
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:locsNSMutableArray] forKey:@"locsNSMutableArray"];
(2)//从NSUserDefaults中取出此数组
NSUserDefaults *curDefaults = [NSUserDefaults standardUserDefaults];
NSData *locData = [curDefaults objectForKey:@"locsNSMutableArray"];
NSMutableArray *locseArray = [NSKeyedUnarchiver unarchiveObjectWithData:locData];
8 将字符串转换为数字
核心点;保证转换后的精度
(1)将字符串转换为NSDecimalNumber类型
(2)将NSDecimalNumber转换为double
NSString *stringNumber=@"123.45678";
NSDecimalNumber *decimalNumber = [NSDecimalNumber decimalNumberWithString:stringNumber];
double doubleNumber=[decimalNumber floatValue];
9 本地通知和通知中心
关于本地通知
发送本地通知:
//建立一个本地通知
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
//设置时区
localNotif.timeZone = [NSTimeZone defaultTimeZone];
//设置发送通知的时间
localNotif.fireDate = selectedNSDate;
//设置通知的内容
localNotif.alertBody = tit;
//设置通知提醒用户的方式.此处为View的方式
localNotif.alertAction = @"View";
//设置通知的声音
localNotif.soundName = UILocalNotificationDefaultSoundName;
//设置通知的userInfo,可作为通知的身份标示
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:tit forKey:tit];
localNotif.userInfo = infoDict;
//将此本地通知加入系统
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
收到本地通知时进行处理:
覆写xxxAppDelegate.m中的方法
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)notif {
NSString *info=[notif alertBody];
//手机震动 引入AudioToolbox.framework
AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
}
其中[notif alertBody]就是消息体
关于通知中心
发送通知:
[[NSNotificationCenter defaultCenter] postNotificationName:@"ok" object:nil];
发送了一个叫ok的通知
接收通知:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(update) name:@"ok" object:nil];
指定接收名字叫ok的通知,并且在收到通知以后调用update方法,进行业务操作
取消通知:
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center removeObserver: self];
//接收通知并且对传递过来的数据进行处理
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getZoomScale:) name:@"ok" object:nil];
- (void)getZoomScale:(NSNotification *)notification {
//取得由NSNotificationCenter送来的讯息
NSNumber *number = [notification object];
float numberFloat=[number floatValue];
}
10 时间及其格式化
NSDate *nowDate=[NSDate date];
NSDateFormatter *dateFormatter=[[NSDateFormatter alloc]init];
//yyyy-MM-dd HH:mm:ss显示完整的时间
//yyyy-MM-dd 只显示年月日
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSString *nowTime=[dateFormatter stringFromDate:nowDate];
11 关于NSString的操作
关于字符串的截取和拆分
比如locStr是网络请求返回的xml,它是NSString,里面有许多东西但是要得到<coordinates>1,2,3</coordinates>中的数字
NSString * locStr =@"xxxxxxxxxooooooooooo<coordinates>1,2,3</coordinates>ooooooooooxxxx";
NSString *rawString = locStr;
//找到<coordinates>出现的range
NSString *startString = @"<coordinates>";
NSRange range1 = [rawString rangeOfString:startString];
//找到</coordinates>出现的range
NSString *endString = @"</coordinates>";
NSRange range2 = [rawString rangeOfString:endString];
//去掉尾巴,即</coordinates>以后的部分
NSString *start=[locStr substringToIndex:range2.location];
//去掉头部.即<coordinates>(包括<coordinates>自身,所以+13)以前的部分
NSString *result=[start substringFromIndex:range1.location+13];
//依据,拆分
NSArray *resultArray=[result componentsSeparatedByString:@","];
获取文件名
比如testNSString
NSString *testNSString=@"d:/123/haha/xixi.pdf";
NSString *result=[testNSString lastPathComponent];
NSLog(@"result=%@",result);
获取除了文件名以外的路径
NSString *testNSString=@"d:/123/haha/xixi.pdf";
testNSString=[testNSString stringByDeletingLastPathComponent];
NSLog(@"testNSString=%@",testNSString);
//testNSString=d:/123/haha
拼凑字符串
NSString *name=@"every";
name = [NSString stringWithFormat:@"hello %@",name];
依据URL或者文件路径获取字符串
+(NSArray *)getLocationByKeyword:(NSString *) addressString
{ //注意URL请求涉及到编码的问题
//所以在利用参数拼接URL请求的时候要注意使用UTF-8编码
NSString *locationRUL = [NSString stringWithFormat:@"http://maps.google.com/maps/geo?q=%@&output=xml",
[addressString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSError *error;
//依据编译后的URL路径,得到服务器返回的NSString数据!!!
NSString *result1 = [NSString stringWithContentsOfURL:[NSURL URLWithString:locationRUL] encoding:NSUTF8StringEncoding error:&error];
//还有类似的方法——从指定的文件路径获取文件中的内容,并且以NSString数据返回
NSString *result2=[NSString stringWithContentsOfFile:(NSString *) usedEncoding:(NSStringEncoding *) error:(NSError **)];
}
12 UIButton的图片切换
UIButton *closeButton = [UIButton buttonWithType:UIButtonTypeCustom];
closeButton.frame = CGRectMake(10, 8, 68, 28);
[closeButton addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
//未被点击时的图片
[closeButton setImage:[UIImage imageNamed:@"bgButton.png"] forState:UIControlStateNormal];
//点击时的图片
[closeButton setImage:[UIImage imageNamed:@"bgButton_On.png"] forState:UIControlStateHighlighted];
13 调用xxxxAppDelegate.m文件中的方法
//应该写成如下的代码,不应该采用alloc的方法建立一个对象然后调用
MizuhoCatalogAppDelegate *m= (MizuhoCatalogAppDelegate *)[[UIApplication sharedApplication] delegate];
[m createThumbnails];
14 关于Documents的操作
//重要参考资料:http://www.tongwenguan.com/tag/pathextension
//得到设备的Documents路径方法一
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [paths objectAtIndex:0];
//得到设备的Documents路径方法二
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
遍历的方法
//建立文件管理对象
NSFileManager *fileMgr = [[NSFileManager alloc] init];
//利用文件管理对象和Documents的路径取得迭代器,
NSDirectoryEnumerator *enumer = [fileMgr enumeratorAtPath:path];
NSString *file;
//利用迭代器迭代Documents中的所有文件
//file就是Documents下每个文件的名字
while (file=[enumer nextObject]) {
//判断文件是否是以pdf的格式
//利用了pathExtension来获取文件的扩展名
if ([[file pathExtension] isEqualToString:@"pdf"]) {
//模拟一些业务操作
//得到此文件的完整路径.记在Documents路径后追加
//采用的方法是stringByAppendingPathComponent 将file添加到已有的路径名称path的末尾
NSString *newNSString= [path stringByAppendingPathComponent:file];
}
}
在Documents下创建目录
+ (void)createDirector: (NSString*)path
{
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL fileExists = [fileManager fileExistsAtPath: path];
if (!fileExists) {
[fileManager createDirectoryAtPath: path withIntermediateDirectories: YES attributes: nil error: nil];
}
}
//在Documents下保存文件
//得到Documents的路径
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//利用文件名组拼目的地路径
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"myimage.png"];
UIImage *myimage=[UIImage imagenamed:@"myimage.png"];
NSData *imageData = UIImagePNGRepresentation(myimage);
[imageData writeToFile:filePath atomically:NO];
15 判断pdf是否被旋转以及创建pdf的缩略图
-(void)checkPDF{
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
NSFileManager *fileMgr = [NSFileManager defaultManager];
NSDirectoryEnumerator *enumer = [fileMgr enumeratorAtPath:path];
NSString *file;
while (file = [enumer nextObject]) {
if ([[file pathExtension] isEqualToString:@"pdf"]) {
printf("%s\n",[file UTF8String]);
NSString *pdfFilePath = [path stringByAppendingPathComponent:file];
//利用pdf文件的路径生成的对应的URL
NSURL *pdfUrl = [NSURL fileURLWithPath:pdfFilePath];
CFURLRef pdfUrlRef = (CFURLRef)pdfUrl;
CGPDFDocumentRef pdfDoc = CGPDFDocumentCreateWithURL(pdfUrlRef);
//得到pdf文件第一页的索引
CGPDFPageRef pageRef = CGPDFDocumentGetPage(pdfDoc, 1);
//得到其旋转角度
int angle = CGPDFPageGetRotationAngle(pageRef);
if(angle != 0){
NSLog(@"已经被旋转了");
}
CFRelease(pdfDoc);
}
}
}
//得到pdf文件的缩略图
//1 pageRef是CGPDFPageRef类的对象
//2 UIGraphicsBeginImageContextWithOptions方法的第二个参数十分重要
// 表示生成的图像是否是透明的.如果选择了YES,不好意思,悲剧发生了生成的图片一片漆黑!!!
- (UIImage *)imageFromPDFWithDocumentRef
{
CGRect pageRect = CGPDFPageGetBoxRect(pageRef, kCGPDFCropBox);
UIGraphicsBeginImageContextWithOptions(pageRect.size, NO, 0.3);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, CGRectGetMinX(pageRect),CGRectGetMaxY(pageRect));
CGContextScaleCTM(context, 1, -1);
CGContextTranslateCTM(context, -(pageRect.origin.x), -(pageRect.origin.y));
CGContextDrawPDFPage(context, pageRef);
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
return finalImage;
}
16 创建风火轮的一种方式
在一个方法中建立和启动风火轮
UIActivityIndicatorView *spinner =
[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
spinner.frame = CGRectMake(470, 350, 100, 100);
//注意在此为此风火轮设定了一个tag作为唯一标示符,这样就不用把spinner声明为全局变量,在后面也可以再次操作它
spinner.tag = 1111111;
[spinner startAnimating];
[self.view addSubview:spinner];
[spinner release];
在另外的一个方法中停止这个风火轮
UIActivityIndicatorView * spinner = (UIActivityIndicatorView *)[self.view viewWithTag:1111111];
[spinner stopAnimating];
[spinner removeFromSuperview];
17 自定义圆角UIView显示带提示信息的风火轮
//注意
//1 UIActivityIndicatorView和UILabel的frame是相对于theView而言的,而不是相对于屏幕而言的.
// 因为最后是把这两个控件加到了theView上而不是加到了self上.所以在设置坐标的时候要额外注意
//2 需要引入QuartzCore.framework
//3 需要#import <QuartzCore/QuartzCore.h>
- (void)viewDidLoad
{
[super viewDidLoad];
//关于风火轮的部分
CGRect frame = CGRectMake(0, 5, 40, 40);
UIActivityIndicatorView* progressInd = [[UIActivityIndicatorView alloc] initWithFrame:frame];
[progressInd startAnimating];
progressInd.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
//关于提示信息的部分
frame = CGRectMake(40, 4, 120, 40);
UILabel *waitingLable = [[UILabel alloc] initWithFrame:frame];
waitingLable.text = @"Processing...";
waitingLable.textColor = [UIColor whiteColor];
waitingLable.font = [UIFont systemFontOfSize:20];;
waitingLable.backgroundColor = [UIColor clearColor];
//利用一个视图添加了风火轮和提示信息
UIView *theView = [[UIView alloc] initWithFrame:CGRectMake(90, 170, 170, 42)];
[theView setBackgroundColor: [UIColor grayColor]];
theView.alpha = 0.5;
//设置那个圆角的有多圆
theView.layer.cornerRadius = 10;
[theView addSubview:progressInd];
[theView addSubview:waitingLable];
[self.view addSubview:theView];
}
18 获得window的长和宽以及在其上添加子视图
CGRect frame = [[UIScreen mainScreen] applicationFrame];
NSLog(@"frame.size.height=%f",frame.size.height);
NSLog(@"frame.size.width=%f",frame.size.width);
[[[UIApplication sharedApplication] keyWindow] addSubview:childView];
19 屏幕的旋转
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation == UIInterfaceOrientationPortrait||interfaceOrientation==UIDeviceOrientationPortraitUpsideDown) {
//NSLog(@"现在是竖屏");
}else
{
//NSLog(@"现在是横屏");
}
return YES;
}
20 数组的相关操作
迭代,拷贝,排序
NSMutableArray *newArray=[[NSMutableArray alloc]init];
NSArray *oldArray=[[NSArray alloc]initWithObjects:@"z",@"c",@"d",@"a",@"e",nil];
//得到数组的迭代器
//objectEnumerator正向遍历
//reverseObjectEnumerator反向遍历
NSEnumerator *enumerator=[oldArray objectEnumerator];
id obj;
while (obj=[enumerator nextObject]) {
[newArray addObject:obj];
}
[newArray sortUsingSelector:@selector(compare:)];
NSLog(@"newArray=%@",newArray);
字符串与数组的相互转换
//将字符串拆分后装到数组里
NSString *testString1=@"one,two,three,four";
NSArray *testArray=[testString1 componentsSeparatedByString:@","];
NSLog(@"testArray=%@",testArray);
//将数组里的元素取出来存放到字符串中
NSString *testString2=[testArray componentsJoinedByString:@","];
NSLog(@"testString2=%@",testString2);
其余的零碎知识点
当按钮被按下的时候得到按钮上的文字
NSString *title=[sender titleForState:UIControlStateNormal];
NSString的操作要加强!!!!!!!