·您现在的位置: 江北区云翼计算机软件开发服务部 >> 文章中心 >> 网站建设 >> app软件开发 >> IOS开发 >> IOS项目-处女作
我最近一直都有在看关于IOS项目的知识,今天也总算是迎来了我的第一个IOS项目。不巧这个项目并不是从头开始开发,而是在基础上维护并添加一些模块。
噗~不管怎么样,还是来分析分析一下源码吧~我这里首先看到的是AppDelegate_ipad.m下的didFinishLaunchingWithOptions方法,这个方法顾名思义应该是应用启动加载完成后所执行的一个方法。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //[NSUserDefaults standardUserDefaults] 获取用户的一些配置信息 if([[[NSUserDefaults standardUserDefaults] stringForKey:@"AddresstheText"] length]==0){ [[NSUserDefaults standardUserDefaults] setObject:@"http://xxxx.com" forKey:@"AddresstheText"]; [[NSUserDefaults standardUserDefaults] synchronize]; } [[NSUserDefaults standardUserDefaults] setObject:@"wangmin" forKey:@"userNameValue"]; [[NSUserDefaults standardUserDefaults] setObject:@"1111" forKey:@"useridValue"]; [[NSUserDefaults standardUserDefaults] synchronize]; FFADSViewController * controller = [[[FFADSViewController alloc] init] autorelease]; //initWithRootViewController的参数API是这样说的,大概就是什么controller都可以,但不能是tabbarcontroller //The root view controller that is pushed on the stack with no animation. It cannot be an instance of tab bar controller. UINavigationController * nav = [[UINavigationController alloc] initWithRootViewController:controller]; //不要显示navigationcontroller的bar [nav setNavigationBarHidden:YES]; //UIDevice可以获取当前设备信息 if ( [[UIDevice currentDevice].systemVersion floatValue] < 6.0){ [self.window addSubview:nav.view]; }else{ self.window.rootViewController = nav; } [self.window makeKeyAndVisible]; return YES; }
接下来稍微的扫一下盲,NSUserDefualts standardUserDefualts是什么呢?
NSUserDefaults standardUserDefaults用来记录一下永久保留的数据非常方便,不需要读写文件,而是保留到一个NSDictionary字典里,由系统保存到文件里,系统会保存到该应用下的/Library/PReferences/gongcheng.plist文件中。需要注意的是如果程序意外退出,NSUserDefaultsstandardUserDefaults数据不会被系统写入到该文件,不过可以使用[[NSUserDefaultsstandardUserDefaults] synchronize]命令直接同步到文件里,来避免数据的丢失。接下来我们来看FFADSViewController~!往下走!GO!
#import "FFADSViewController.h" #import "FFLrcController.h" @implementation FFADSViewController -(void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:YES]; [self.navigationController setNavigationBarHidden:YES animated:NO]; } //这个页就相当于app进入login页面之前,需要缓冲一些数据会在这个页面停留1-2秒种 - (void)loadView { [super loadView]; CGRect frame = CGRectMake(0, 0, 768, 1024); UIImage * image = [UIImage imageNamed:@"ipadguodu"]; UIImageView * imageView = [[UIImageView alloc] initWithImage:image]; CGRect imageFrame = frame; imageView.frame = imageFrame; imageView.tag = 100; //addSubview 添加子视图 [self.view addSubview:imageView]; [imageView release]; //延迟2秒钟后执行toController [self performSelector:@selector(toController) withObject:nil afterDelay:2]; } -(void)toController{ FFLrcController *publish = [[FFLrcController alloc]init]; UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:publish]; //presentModalViewController:弹出视图 [self presentModalViewController:nav animated:NO]; [publish release]; } - (void)dealloc { [super dealloc]; } @end
这个controller很简单,继续往下走FFLrcController估计就是登录页面了,真是不容易啊!走了好多路才到了登录界面。登录页面首先执行的是loadView事件
注:remember、login、personnumber、passWord、state等属性都已经在FFLrcController.h中定义
- (void)loadView { [super loadView];//隐藏导航bar [self.navigationController setNavigationBarHidden:YES animated:NO]; //设置背景颜色 self.view.backgroundColor=[UIColor colorWithRed:235/255.0 green:232/255.0 blue:222/255.0 alpha:1]; //label,设置相应的字体颜色背景等等信息 UILabel *remember=[[UILabel alloc]initWithFrame:CGRectMake(100, 733, 150, 30)]; remember.textColor=[UIColor colorWithRed:189/255.0 green:183/255.0 blue:167/255.0 alpha:1]; remember.text=@"记住登录状态"; [self.view addSubview:remember]; [remember release]; //登陆 login = [[UITextField alloc] initWithFrame:CGRectMake(345, 452, 300, 40)]; login.backgroundColor = [UIColor clearColor]; login.borderStyle = UITextBorderStyleRoundedRect; login.borderStyle=UITextBorderStyleNone; //“委托的意思不就是自己的任务交给其他人去做么” //对象.delegate=self的意思就是对象的任务交给self去做 对象!=self login.delegate = self; login.keyboardType = UIKeyboardTypeDefault; // use the default type input method (entire keyboard) login.placeholder=@"姓名"; login.returnKeyType = UIReturnKeyDone; [self.view addSubview:login]; personnumber = [[UITextField alloc] initWithFrame:CGRectMake(345, 545, 300, 40)]; personnumber.backgroundColor = [UIColor clearColor]; personnumber.borderStyle = UITextBorderStyleRoundedRect; personnumber.borderStyle=UITextBorderStyleNone; personnumber.delegate = self; personnumber.keyboardType = UIKeyboardTypeDefault; // use the default type input method (entire keyboard) personnumber.placeholder=@"身份证号码"; personnumber.returnKeyType = UIReturnKeyDone; [self.view addSubview:personnumber]; //密码 password = [[UITextField alloc] initWithFrame:CGRectMake(345, 636, 300, 40)]; password.secureTextEntry=YES; password.backgroundColor = [UIColor clearColor]; password.borderStyle = UITextBorderStyleRoundedRect; password.delegate = self; password.borderStyle=UITextBorderStyleNone; password.keyboardType = UIKeyboardTypeDefault; // use the default type input method (entire keyboard) password.placeholder=@"密码"; password.returnKeyType = UIReturnKeyDone; [self.view addSubview:password];//记住状态 state = [UIButton buttonWithType:UIButtonTypeCustom]; state.frame =CGRectMake(50, 720, 52, 52); //UIControlEventTouchDown事件后会转跳到remember方法中做处理 [state addTarget:self action:@selector(remember) forControlEvents:UIControlEventTouchDown]; [state setBackgroundImage:[UIImage imageNamed:@"ipadcheckLogin"] forState:UIControlStateNormal]; [self.view addSubview:state]; //登陆按钮 UIButton *check = [UIButton buttonWithType:UIButtonTypeCustom]; check.frame =CGRectMake(350, 725, 319, 72); [check.titleLabel setFont:[UIFont boldSystemFontOfSize:18]]; //UIControlEventTouchDown事件后会执行goHome [check addTarget:self action:@selector(goHome) forControlEvents:UIControlEventTouchDown]; [check setBackgroundImage:[UIImage imageNamed:@"ipadlogin_btn"] forState:UIControlStateNormal]; [self.view addSubview:check]; //他这里condition方法编写的是假如有记住密码则将配置文件里的信息读取到UITextField当中 [self condition]; }
FFLrcController.m ---> goHome事件
- (void)goHome { //交出第一响应的身份,可能是回收键盘操作 [login resignFirstResponder]; [personnumber resignFirstResponder]; [password resignFirstResponder]; //SVProgressHUD 是一个第三方的控件,是一个弹出提示层,用来提示网络加载或提示对错 [SVProgressHUD showWithStatus:@"数据加载中..." maskType:SVProgressHUDMaskTypeClear]; //不重复,只调用一次。timer运行一次就会自动停止运行 timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(loginTO) userInfo:nil repeats:NO]; }
FFLrcController.m ---> loginTO事件
-(void)loginTO{ //设置URL 这里相当于 http://xxxx.com/CheckLogin/index/type/name/001/IDcardNO/331004xxxxxxxx/password/001/uuid/e1e2ed3sgfw2/macaddress/192.168.1.1/checkword/?p=ui
//总之这个根据服务器具体所需要的url来配置 NSString *urlString=[NSString stringWithFormat:@"%@/CheckLogin/index/type//name/%@/IDcardNO/%@/password/%@/uuid/%@/macaddress/%@/checkword/?p=ui"
,@"http://xxxx.com",login.text,personnumber.text,password.text,[self getUUID],[self getMacAddress]]; //NSLog(@"urlString %@",urlString); NSURL *url=[NSURL URLWithString:urlString]; //ASIHTTPRequest类库中的ASIFormDataRequest是实现HTTP协议中的处理POST表单的很好的类库。 ASIFormDataRequest *request = [[ASIFormDataRequest alloc] initWithURL:url]; [request setDelegate:self]; //成功后调用dataFetchComplete [request setDidFinishSelector:@selector(dataFetchComplete:)]; //失败后调用dataFail [request setDidFailSelector:@selector(dataFail:)]; [request setTimeOutSeconds:60]; [[SEAOperationQueue mainQueue] addOperation:request]; [request release]; }
FFLrcController.m ---> dataFetchComplete事件
- (void)dataFetchComplete:(ASIHTTPRequest *)request { //隐藏进度条框 [SVProgressHUD dismiss]; //从服务器中得到的数据是二进制的 NSData * data = [request responseData]; if (data) {
//从服务器得到返回的数据转UTF-8,这里为什么不是json,竟然带有html的 NSString *myString = [[NSString alloc] initWithBytes:[data bytes] length:[data length] encoding:NSUTF8StringEncoding]; //这里过滤掉一些标签如:<script></script>等 //使用NSString的stringByReplacingOccurrencesOfString:@"要过滤的" withString:@"替换成的"方法 //以下省略9行过滤代码
if ([myString isEqualToString:@"您的身份证号码有误!"]) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"身份证号码输入错误" delegate:nil cancelButtonTitle:@"确认" otherButtonTitles:nil, nil]; [alert show]; [alert release]; return; }else if ([myString isEqualToString:@"用户名或密码输入错误!"]) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"登陆信息输入错误" delegate:nil cancelButtonTitle:@"确认" otherButtonTitles:nil, nil]; [alert show]; [alert release]; return; }else if ([myString hasprefix:@"/userid"]) { myString=[myString stringByReplacingOccurrencesOfString:@"/userid/" withString:@""]; if (flag) { [[NSUserDefaults standardUserDefaults] setObject:@"true" forKey:@"flag"]; [self writeUser]; }else{ [[NSUserDefaults standardUserDefaults] setObject:@"false" forKey:@"flag"]; } //记录登陆时间写入配置文件 NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"YYYY-MM-dd"]; NSString *timestamp = [formatter stringFromDate:[NSDate date]]; NSString *countTime=@"上次登陆:"; countTime=[countTime stringByAppendingString:timestamp]; [[NSUserDefaults standardUserDefaults] setObject:countTime forKey:@"loginTime"]; [formatter release]; //这里登陆成功后,写入一些信息到配置文件。这里省去一些代码 FFFFSwitchViewController *controller = [[FFFFSwitchViewController alloc]init]; controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal; [self.navigationController pushViewController:controller animated:YES]; [controller release]; } } }
可以看到接下来就是FFFFSwitchViewController
FFFFSwitchViewController.h文件
#import <UIKit/UIKit.h> //这个TransparendValueDelegate干嘛用暂时不清楚 @protocol TransparendValueDelegate; //首先这个类继承了UITabBarController,且实现了UITabBarControllerDelegate和UINavigationControllerDelegate两个接口 @interface FFFFSwitchViewController : UITabBarController<UITabBarControllerDelegate,UINavigationControllerDelegate> { } - (void)makeTabBarHidden:(BOOL)hide; -(void)hiddenTabButton; -(void)displayTabButton; @end
FFFFSwitchViewController.m ---> init构造函数方法
-(id)init { if(self= [super init]){ [self makeTabBarHidden:YES]; //定义一个能够存放很多controller的数组 NSMutableArray *controllers = [[NSMutableArray alloc] initWithCapacity:5]; //首页controller FFHomePageViewController *payout=[[FFHomePageViewController alloc]init]; payout.title=@"首页"; UINavigationController *nav1 = [[UINavigationController alloc]initWithRootViewController:payout]; nav1.navigationBar.tintColor =[UIColor colorWithRed:0.161 green:0.584 blue:0.839 alpha:1]; [nav1 setNavigationBarHidden:YES animated:NO]; //设置controller FFshezhi *shouce=[[FFshezhi alloc]init]; shouce.title=@"设置"; UINavigationController *nav2 = [[UINavigationController alloc]initWithRootViewController:shouce]; nav2.navigationBar.tintColor =[UIColor colorWithRed:0.161 green:0.584 blue:0.839 alpha:1]; [nav2 setNavigationBarHidden:YES animated:NO]; //视频controller FFVideo *conver=[[FFVideo alloc]init]; conver.title=@"视频"; UINavigationController *nav3 = [[UINavigationController alloc]initWithRootViewController:conver]; nav3.navigationBar.tintColor =[UIColor colorWithRed:0.161 green:0.584 blue:0.839 alpha:1]; [nav3 setNavigationBarHidden:YES animated:NO]; //拍照controller FFCamera *shoucang=[[FFCamera alloc]init]; shoucang.title=@"拍照"; UINavigationController *nav4 = [[UINavigationController alloc]initWithRootViewController:shoucang]; nav4.navigationBar.tintColor =[UIColor colorWithRed:0.161 green:0.584 blue:0.839 alpha:1]; [nav4 setNavigationBarHidden:YES animated:NO]; nav1.navigationBar.barStyle = UIBarStyleDefault; nav2.navigationBar.barStyle = UIBarStyleDefault; nav3.navigationBar.barStyle = UIBarStyleDefault; nav4.navigationBar.barStyle = UIBarStyleDefault; payout.tabBarItem.image = [UIImage imageNamed:@"sysytem"]; nav2.tabBarItem.image = [UIImage imageNamed:@"setting"]; nav3.tabBarItem.image = [UIImage imageNamed:@"camera"]; nav4.tabBarItem.image = [UIImage imageNamed:@"vido"]; [controllers addObject:nav1]; [controllers addObject:nav3]; [controllers addObject:nav4]; [controllers addObject:nav2]; //因为本身就是tabcontroller的子类 self.viewControllers = controllers; self.delegate = self; [payout release]; [nav1 release]; [shouce release]; [nav2 release]; [conver release]; [nav3 release]; [shoucang release]; [nav4 release]; float width=self.view.bounds.size.width/4; //初始化界面 for (int i = 0; i<4; i++) { //初始化底部的按钮 UIButton * choiceButton= [UIButton buttonWithType:UIButtonTypeCustom]; choiceButton.frame = CGRectMake(width * i, 1024-90, width, 90); //tag设置成10111 choiceButton.tag = i+10111; //给按钮添加点击事件 //点击事件无非就是点击后改变按钮的背景图片 [choiceButton addTarget:self action:@selector(clickButton:) forControlEvents:UIControlEventTouchDown]; NSString *imagename=[NSString stringWithFormat:@"IpadTabbar%d",i+1]; [choiceButton setImage:[UIImage imageNamed:imagename] forState:UIControlStateNormal]; [choiceButton setBackgroundColor:[UIColor clearColor]]; [self.view addSubview:choiceButton]; } //得到当前第一个button的引用 UIButton *button=(UIButton *)[self.view viewWithTag:10111]; //第一个为选中状态,所以给他设置别的背景图片 [button setImage:[UIImage imageNamed:@"IpadTabbarBack1"] forState:UIControlStateNormal]; self.selectedIndex = 0; } return self; }
从FFFFSwitchViewController.m中可以看出他是一个类似iPad主菜单界面。它是一个tab页分别容纳了四个controller,分别是FFHomePageViewControlle、FFshezhi、FFCamera、FFVideo。
顾名思义FFHomePageViewControlle应该所有controller当中最中心的一个controller。
进入FFHomePageViewControlle.h
#import <UIKit/UIKit.h> #import "FFHomeView.h" #import "FFFFWebViewController.h" //FFHomePageViewController继承UIViewController,并实现了FFHomeViewControllerDelegate,UITableViewDelegate, //和UITableViewDataSource三个接口。其中FFHomeViewControllerDelegate为自定义接口 @interface FFHomePageViewController : UIViewController <FFHomeViewControllerDelegate,UITableViewDelegate,UITableViewDataSource>{ NSMutableArray *bookData; } @end
在看FFHomePageViewControlle.m之前先去探究下FFHomeViewControllerDelegate接口
FFHomeView.h文件
#import <UIKit/UIKit.h> @class FFHomeView; //接口申明 @protocol FFHomeViewControllerDelegate<NSObject> @required -(void)getPerSonProduct:(FFHomeView *)controller; @end @interface FFHomeView : UIView { NSArray *bookArray; NSMutableDictionary *perDict; //这个类包含这个接口 id<FFHomeViewControllerDelegate>delegate; } @property(nonatomic,retain)NSMutableDictionary *perDict; @property(nonatomic,retain)NSArray *bookArray; //接口变量delegate作为类FFHomeView的属性 @property(nonatomic,assign)id<FFHomeViewControllerDelegate>delegate;
@end
FFHomeView.m文件
#import "FFHomeView.h" @implementation FFHomeView @synthesize delegate; @synthesize bookArray; @synthesize perDict; - (id)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { self.backgroundColor=[UIColor clearColor]; } return self; } // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. - (void)drawRect:(CGRect)rect { NSInteger i= 0; NSUInteger count = 4; CGFloat width = self.frame.size.width / count; for (NSDictionary *dict in bookArray) { NSString *keypic=[dict objectForKey:@"image"]; UIImage *image=[UIImage imageNamed:keypic]; if (!image) { image = [UIImage imageNamed:@"defaultimage.png"]; } if (image) { CGRect frameImage=CGRectMake(172 *i+70,10, 112, 112); [[UIColor whiteColor]set]; [[UIColor colorWithRed:221/255.0 green:221/255.0 blue:221/255.0 alpha:1]set]; [[UIColor clearColor] set]; [image drawInRect:CGRectInset(frameImage,0,0)]; } [[UIColor colorWithRed:116/255.0 green:109/255.0 blue:88/255.0 alpha:1]set]; NSString *china=[NSString stringWithFormat:@"%@",[dict objectForKey:@"name"]]; [china drawInRect:CGRectMake(172 *i+30,125, width, 30) withFont:[UIFont boldSystemFontOfSize:15]
lineBreakMode:UILineBreakModeTailTruncation alignment:UITextAlignmentCenter]; i++; } } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { CGPoint pt = [[touches anyObject] locationInView:self]; NSUInteger width = self.bounds.size.width / 4; NSUInteger count = 0; for (NSMutableDictionary * dict in bookArray) { CGRect rect = CGRectMake(width * count++, 0,width, self.bounds.size.height); if (CGRectContainsPoint(rect, pt)) { //NSLog(@"dict %@",dict); perDict=dict; if(delegate && [delegate respondsToSelector:@selector(getPerSonProduct:)]){ [delegate getPerSonProduct:self]; return; } } } } - (void)dealloc { [super dealloc]; } @end
看到这里我已经完全晕掉了,完全不知这个是用来干什么的?算了还是回到原来的路去吧,之前我们是看到了FFHomePageViewController.h。FFHomePageViewController.h是实现了FFHomeViewControllerDelegate接口,所以我们才会看到上述两个文件的。那现在我们来看下FFHomePageViewController.m的构造函数吧~
FFHomePageViewController.m ---> init构造函数(从这个构造函数可以发现bookData是用来存储bookMenu.plist加载到内存中的键值对的)
-(id)init { if(self= [super init]){ NSString *contentPath = [NSString stringByAppendDocumentDirectory:@"bookMenu.plist"]; bookData=[[NSMutableArray alloc] initWithContentsOfFile:contentPath]; } return self; }
FFHomePageViewController.m ---> loadView方法
//每次访问UIViewController的view(比如controller.view、self.view)而且view为nil,loadView方法就会被调用。 - (void)loadView { [super loadView]; //指定view的背景颜色 self.view.backgroundColor=[UIColor colorWithRed:235/255.0 green:232/255.0 blue:222/255.0 alpha:1]; //Logo图片 UIImageView *upImage=[[UIImageView alloc] initWithFrame:CGRectMake(0,0, 768, 88)]; upImage.tag=51; [upImage setImage:[UIImage imageNamed:@"Ipadup"]]; [self.view addSubview:upImage]; [upImage release]; //TableView放一些菜单图标 UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 88, 768, 830-5) style:UITableViewStylePlain]; [tableView setDelegate:self]; [tableView setDataSource:self]; [tableView setTag:111110]; tableView.separatorStyle=UITableViewCellSeparatorStyleNone; tableView.separatorColor=[UIColor clearColor]; [tableView setBackgroundColor:[UIColor clearColor]]; [self.view addSubview:tableView]; [tableView release]; }
话说FFHomePageViewController.h是实现UITableViewDataSource接口和UITableViewDelegate接口的,又通过[tableView setDelegate:self],[tableView setDataSource:self]语句,表示只要在FFHomePageViewController.m当前类重写那些方法就可以了。
UITableViewDataSource,主要为UITableView提 供显示用的数据(UITableViewCell),指定UITableViewCell支持的编辑操作类型(insert,delete和 reordering),并根据用户的操作进行相应的数据更新操作,如果数据没有更具操作进行正确的更新,可能会导致显示异常,甚至crush。
UITableViewDelegate,主要提供一些可选的方法,用来控制tableView的选择、指定section的头和尾的显示以及协助完成cell的删除和排序等功能。
接下来看下渲染每一个cell的方法
FFHomePageViewController.m ---> - (UITableViewCell *)tableView:(UITableView *)tableView1 cellForRowAtIndexPath:(NSIndexPath *)indexPath
//初始化每一行会调用该方法 - (UITableViewCell *)tableView:(UITableView *)tableView1 cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = nil; static NSString *kCellTextField1 = @"Cell"; cell = [tableView1 dequeueReusableCellWithIdentifier:kCellTextField1]; if (cell==nil) { if (indexPath.section==0) { //初始化Image UIImage * bgImage = nil; bgImage = [[UIImage imageNamed:@"shuguiback.png"] stretchableImageWithLeftCapWidth:0 topCapHeight:34]; cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellTextField1] autorelease]; cell.selectionStyle = UITableViewCellSelectionStyleNone; cell.accessoryType=UITableViewCellAccessoryNone; //自定义的FFHomeView类构造函数返回自己本身 FFHomeView *drawFriends=[[FFHomeView alloc]initWithFrame:CGRectMake(0, 0,320, 160)]; [drawFriends setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight]; [drawFriends setTag:1]; //FFHomeView的delegate就是FFHomeViewControllerDelegate //而当前类就是实现FFHomeViewControllerDelegate接口的。就是把FFHomeView中要做的事,交给当前类 [drawFriends setDelegate:self]; [drawFriends setUserInteractionEnabled:YES]; [cell.contentView addSubview:drawFriends]; [drawFriends release]; cell.backgroundView=[[UIImageView alloc]initWithImage:bgImage]; } } //这里还没怎么看的明白 if (indexPath.section==0) { if (bookData) { NSUInteger count = [bookData count]; NSUInteger length = indexPath.row * ROWCALUE_NUMBER + ROWCALUE_NUMBER > count?count - indexPath.row * ROWCALUE_NUMBER:ROWCALUE_NUMBER; NSArray * array = [bookData subarrayWithRange:NSMakeRange(indexPath.row * ROWCALUE_NUMBER , length)]; if (array) { FFHomeView * view1 = (FFHomeView * )[cell.contentView viewWithTag:1]; view1.bookArray=array; //setNeedsDisplay会调用自动调用drawRect方法 [view1 setNeedsDisplay]; } } } return cell; }
看了这个方法后差不多也明白了之前的FFHomeView.m文件做的是什么事情了,按照java的理解方式是这样的。就相当于在FFHomeView类中写了一个事件接口FFHomeViewControllerDelegate,在该类的touchesEnded事件函数中回调FFHomeViewControllerDelegate接口里的getPerSonProduct方法。而getPerSonProduct方法真正的实现而在FFHomePageViewController类当中。
然后调用顺序就是:
当我们触发菜单栏的图标--->调用FFHomeView里的touchesEnded事件--->再调用到FFHomePageViewController里的getPerSonProduct事件
FFHomePageViewController.m ---> getPerSonProduct方法
-(void)getPerSonProduct:(FFHomeView *)controllerRenqi{ //在FFHomeView内部调用该函数的时候把自己本身传入,而自己本身包含perDict键值对 //<dict><key>url</key><string>/index.php/cms/item-hjindex</string></dict> NSString *stringURL=[controllerRenqi.perDict objectForKey:@"url"]; if ([stringURL isEqualToString:@"exit"]) { //若退出,显示登陆界面 FFLrcController *publish = [[FFLrcController alloc]init]; UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:publish]; [self presentModalViewController:nav animated:NO]; //每次使用完controller都释放掉 [publish release]; return; } NSString *createurl=[controllerRenqi.perDict objectForKey:@"createurl"]; //WebViewController FFFFWebViewController * web=[[FFFFWebViewController alloc] init:stringURL createURL:createurl]; NSString *name=[controllerRenqi.perDict objectForKey:@"name"]; web.TT=name; web.hidesBottomBarWhenPushed=YES; [self.navigationController pushViewController:web animated:YES]; [web release]; }
看完上面这些代码后,发现接下来的视图传入的是WebViewController,参数是url。我想这个一定是传说中的app中加个webview。大部分操作可能会由webview来实现。
另外我想你会跟我一样有这样的一些问题,createurl是什么?干什么用?不急不急,接下来来看看FFFFWebViewController 是怎么实现的。
#import <UIKit/UIKit.h> #import "FFFFSwitchViewController.h" //发现这个类是继承UIViewController,并实现了UIWebViewDelegate接口 @interface FFFFWebViewController : UIViewController <UIWebViewDelegate>{ //浏览器 UIWebView * webView; //UIActivityIndicatorView实例提供轻型视图,这些视图显示一个标准的旋转进度轮。 UIActivityIndicatorView *activityIndicator; NSString *stringUrl; NSString *createUrl; NSString *TT; } @property(nonatomic,retain)NSString *TT; @property(nonatomic,retain)NSString *stringUrl; @property(nonatomic,retain)NSString *createUrl; -(id)init:(NSString *)string createURL:(NSString*)curl; //-(void)loadWebView:(NSString*)string; @end
FFFFWebViewControlle.h主要就是实现了 UIWebViewDelegate委托接口,UIWebViewDelegate主要有下面几个方法。
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType; //加载前
//第一个参数为:要显示的地址 -(id)init:(NSString *)string createURL:(NSString*)curl{ if(self=[super init]){ self.stringUrl=[[NSString stringWithFormat:@"%@%@", @"http://xxxxx/hjjd", string]
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; self.createUrl = curl; } return self; }
FFFFWebViewController.m ---> loadView方法
- (void)loadView { [super loadView]; self.view.backgroundColor=[UIColor colorWithRed:235/255.0 green:232/255.0 blue:222/255.0 alpha:1]; //存放logo UIImageView *uv=[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 768, 60)]; uv.tag=1; [uv setImage:[UIImage imageNamed:@"Ipadnavigation"]]; [self.view addSubview:uv]; [uv release]; //返回按钮 UIButton *check = [UIButton buttonWithType:UIButtonTypeCustom]; check.tag=2; check.frame =CGRectMake(10, 22, 48, 30); [check.titleLabel setFont:[UIFont boldSystemFontOfSize:14]]; [check setTitle:@"返回" forState:UIControlStateNormal]; //点击后出发goBack事件 [check addTarget:self action:@selector(goBack) forControlEvents:UIControlEventTouchDown]; [check setBackgroundImage:[UIImage imageNamed:@"IpadnClose"] forState:UIControlStateNormal]; [self.view addSubview:check]; //新建按钮 if(![self.createUrl isEqualToString:@"null"]){ UIButton *upButton = [UIButton buttonWithType:UIButtonTypeCustom]; upButton.tag=3; upButton.frame =CGRectMake(768-58, 22, 48, 30); [upButton setTitle:@"新建" forState:UIControlStateNormal]; [upButton.titleLabel setFont:[UIFont boldSystemFontOfSize:14]]; //点击后触发resum事件 [upButton addTarget:self action:@selector(resum) forControlEvents:UIControlEventTouchDown]; [upButton setBackgroundImage:[UIImage imageNamed:@"IpadnClose"] forState:UIControlStateNormal]; [self.view addSubview:upButton]; } //标题 UILabel *titleLabel=[[UILabel alloc]initWithFrame:CGRectMake(0,23,768,30)]; titleLabel.tag=4; [titleLabel setFont:[UIFont boldSystemFontOfSize:20]]; [titleLabel setTextAlignment:UITextAlignmentCenter]; titleLabel.lineBreakMode=UILineBreakModeWordWrap; titleLabel.numberOfLines=0; titleLabel.text =TT; [titleLabel setTextColor:[UIColor whiteColor]]; [titleLabel setBackgroundColor:[UIColor clearColor]]; [self.view addSubview:titleLabel]; [titleLabel release]; webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 60, 768, 1024-20-88-88+60)]; webView.scalesPageToFit = YES; //设置delegate为本身,因为该类实现UIWebViewDelegate接口 webView.delegate = self; webView.backgroundColor = [UIColor clearColor]; [self.view addSubview:webView];
activityIndicator = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(0, 15, 50, 50)]; [activityIndicator setCenter:CGPointMake(768/2,1024/2)]; [activityIndicator setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleGray]; [self.view addSubview:activityIndicator]; //加载链接地址 [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.stringUrl]]]; }
FFFFWebViewController.m ---> resum事件
-(void)resum{ FFcreateViewContonroller *matchset=[[FFcreateViewContonroller alloc]init:self.createUrl]; matchset.TT=[NSString stringWithFormat:@"新建%@",TT]; [self presentModalViewController:matchset animated:YES]; [matchset release]; }
FFFFWebViewController.m ---> goBack事件
- (void)goBack { //假如浏览器可以goBack就先goBack if([webView canGoBack]){ [webView goBack]; }else{ //否则弹出controller [self.navigationController popViewControllerAnimated:YES]; } }
从上面的代码就可以看出createurl是用来做什么的了,假如我们点击右上角的新建按钮,createurl可以让webview转跳到自己定义的页面当中。另外假如自己需要controller之间的转跳,则只要在新建点击后判断createurl的内容,就可以任意转跳到自己的地方了。到这里差不多可以看懂原作者的app设计思路是怎么样的了。这里点击新建后会进入 FFcreateViewContonroller。FFcreateViewContonroller其实与FFFFWebViewController非常的相似,也就是嵌入一个webview。