代码改变世界

使用UIView实现自动登录

2011-08-17 17:29  乱世文章  阅读(269)  评论(0编辑  收藏  举报


在iPhone开发中,自动登录一直是一个问题。因为传统UINavigationController的方式,需要在没有用户触发的情况下自动push出视图控制器。然而经过长时间的尝试,我们发现如果使用ViewController和UINavigationController.pushViewController的方式进行自动登录,会导致UINavigateController的栈内的视图控制器顺序混乱,导致无法正确导航。因此,最终还是只能采用切换UIView的方式实现自动登录。大体思路如下:

首先我们需要分别实现两个UIView:

一个用于呈现登录界面,包含密码、帐号输入框和登录按钮等UI组件以及登录验证的逻辑;

一个用于显示登录成功后的内容界面,比如显示用户操作菜单等;

然后,我们实现一个UIViewController,在其中加入这两个UIView组件,并实现视图切换的逻辑和转换动画。

一、LoginView

首先是实现 UIView 的 initWithFrame 方法,在其中绘制界面,比如:

-(id)initWithFrame:(CGRect)frame{

if(self=[super initWithFrame:frame]){

// 绘制控件代码略

… …

[self performSelector:@selector(login)];

 

}

return self;

}

界面绘制后,进行自动登录,这是通过调用autoLogin方法实现的:

//自动登录在此实现

- (void)login // 从文件加载用户名密码进行自动登录等

{

// 加载用户名、密码的代码略

… …

//  输入验证的代码略

… …

// 进行登录

[self performSelector:@selector(loginClicked)];

}

loginClicked的方法实现真正的登录验证逻辑,这个方法同时可被用于响应登录按钮的触摸事件:

//登录按钮触摸时触发

-(void)loginClicked{

//验证登录的代码略

… …

 

if (owner!=nil) {

[owner loginSuccess:success params:params];

}

}

在这里owner被定义为实现了协议LoginOwnerDelegate的对象(id):

id<LoginOwnerDelegate> owner;

@property (assign,nonatomic)id<LoginOwnerDelegate>owner;

而LoginOwnerDelegate协议的定义如下:

 

@protocol LoginOwnerDelegate<NSObject>

 

@required

-(void)loginSuccess:(BOOL)success params:(NSDictionary*)params;

@end

在后面,owner属性将被设置为UIViewController实例。因此,要求UIViewController实现LoginOwnerDelegate协议。这样,当LoginView中处理完登录后,将回调UIViewController的loginSuccess:params: 方法。

二、MenuView

这个UIView用于显示登录成功后的功能菜单页面。当点击某个菜单项时,需要回调delegate的menuItemClick  方法:

if (delegate!=nil) {

[delegate menutItemClicked:indexPath.row account:account password:pass userid:userid];

}

delegate协议被定义为实现了协议MenuDelegate的id对象:

id<MenuDelegate> delegate;

}

@property(assign,nonatomic)id<MenuDelegate>delegate;

而MenuDelegate协议定义如下:

@protocol MenuDelegate<NSObject>

@required

-(void)menutItemClicked:(int)index account:(NSString*)acc password:(NSString*)pass userid:(NSString*)uid;

@end

在后面会把delegate属性赋值为UIViewController实例。因此,UIViewController需要实现协议MenuDelegate。

三、UIViewController

从上可知,UIViewController需要实现两个协议:LoginOwnerDelegate和MenuDelegate:

@interface MyViewController:UIViewController

<LoginOwnerDelegate,QXTMenuDelegate>{

… …

}

@end

在加载视图的时候,加入前面的两个UIView:

//初始化UIView

self.view=[[UIView alloc]initWithFrame:CGRectMake(0,0, 320, 400)];

 

loginCtr=[[LoginvView alloc]initWithFrame:self.view.frame];

loginCtr.owner=self;

[self.view addSubview:loginCtr];

 

menu=[[MenuView alloc]initWithFrame:self.view.frame];

menu.delegate=self;

[self.view addSubview:menu];

[menu setHidden:YES];

 

实现时别忘了实现两个协议方法:

#pragma markLoginOwnerDelegate 协议方法

-(void)loginSuccess:(BOOL)success params:(NSDictionary*)params{

if (success) {

// 登录成功,显示MenuView,将LoginView设为隐藏

 

CATransition *transition=getOglFlipAnimation();

[menu setModel:params];

// 让LoginView和MenuView上下交换位置

[self.view exchangeSubviewAtIndex:0 withSubviewAtIndex:1];

[menu setHidden:NO];

[loginCtr setHidden:YES];

// 设置转换动画

[[self.view layer] addAnimation:transition forKey:@"suckAnimation"];

 

}else {

//登录失败代码略

… …

}

}

#pragma mark MenuDelegate 协议方法

-(void)menutItemClicked:(int)index account:(NSString*)acc password:(NSString*)pass userid:(NSString*)uid{

  // 当点击MenuView中的某个菜单时,进行处理,代码略

… …

}