iOS登录界面和注册界面

来源:互联网 发布:联想笔记本网络驱动 编辑:程序博客网 时间:2024/05/03 17:53
iOS登录界面和注册界面
一、登录和注册界面实现效果图:
二、实现原理
1、输入框的实现原理:把两个无边框的UITextField添加到一个作为背景的UIView上,然后重写UIView的 :
-(void)drawRect:(CGRect)rect 方法,用Quartz2D画出中间的那条分隔线。然后再设置背景UIView为带边框的圆角就可以实现上面的效果了。
注意:为了方便要把textField添加到背景view上,然后设置textField的frame值时根据View的frame值计算简单些。
三、直接上代码
注:由于代码是直接从自己的小项目中粘贴过来的,有些功能可能你用不到,可以自行删减。
1、我前面有一篇博客讲了如何设置textField的占位符和左边的图片,这里就不再赘述。
下面直接上代码:
新建一个BasicTextField类继承自UITextField
BasicTextField.h文件:
#import<UIKit/UIKit.h>

@interface BasicTextField : UITextField

@end

BasicTextField.m文件:
#import"BasicTextField.h"

@implementationBasicTextField

//  重写leftViewX
- (
CGRect)leftViewRectForBounds:(CGRect)bounds{
   
CGRect iconRect = [superleftViewRectForBounds:bounds];
    iconRect.
origin.x+= 10;
   
return iconRect;
}

//  重写占位符的x
- (
CGRect)placeholderRectForBounds:(CGRect)bounds{
   
CGRect placeholderRect = [superplaceholderRectForBounds:bounds];
    placeholderRect.
origin.x+= 1;
   
return placeholderRect;
}

//  重写文字输入时的x
- (
CGRect)editingRectForBounds:(CGRect)bounds{
   
CGRect editingRect = [supereditingRectForBounds:bounds];
    editingRect.
origin.x+= 20;
   
return editingRect;
}

//  重写文字显示时的x
- (
CGRect)textRectForBounds:(CGRect)bounds{
   
CGRect textRect = [supereditingRectForBounds:bounds];
    textRect.origin.x+= 20;
   return textRect;
}
@end

2、新建LoginBackgroundView类继承自UIView,作为textField的输入框的背景。
LoginBackgroundView.h文件:
#import<UIKit/UIKit.h>

@interface LoginBackgroundView : UIView

@end

LoginBackgroundView.m文件:

#define mianBodyColor(r, g, b) [UIColor colorWithRed:r/255.0fgreen:g/255.0fblue:b/255.0falpha:1]
#import"LoginBackgroundView.h"

@implementationLoginBackgroundView

//重写此方法,用Quartz2D画出中间分割线
-(void)drawRect:(CGRect)rect{
   
CGContextRefcontext = UIGraphicsGetCurrentContext();
   
CGContextSetLineWidth(context,0.7);
   
CGContextBeginPath(context);
   
CGContextMoveToPoint(context,0,40);
   
CGContextAddLineToPoint(context,self.frame.size.width,40);
   
CGContextClosePath(context);
    [
mianBodyColor(207,207,207)setStroke];
   
CGContextStrokePath(context);
}

3、新建LoginView类继承自UIView,把这个LoginView设置为控制器的rootView即可。
LoginView.h文件:

#import<UIKit/UIKit.h>

@protocol LoginViewDelegate <NSObject>

@interfaceLoginView : UIView
@end

LoginView.m文件:

#define textFieldColor(r, g, b) [UIColor colorWithRed:r/255.0fgreen:g/255.0fblue:b/255.0falpha:1]
#define mianBodyColor(r, g, b) [UIColor colorWithRed:r/
255.0fgreen:g/255.0fblue:b/255.0falpha:1]
#import
"LoginView.h"

#import "BasicTextField.h"
#import
"LoginBackgroundView.h"

@interface LoginView ()<UITextFieldDelegate>

@property (nonatomic,strong)LoginBackgroundView*backgroundView;
@property (nonatomic,strong)BasicTextField *userTextField;
@property (nonatomic,strong)BasicTextField *passwordTextField;
@property (nonatomic,strong)UIButton *loginButton;
@property (nonatomic,strong)UIActivityIndicatorView*logioningActivityIndicatorView;
@property (nonatomic,assign)BOOL isUserEmpty;
@property(nonatomic,assign)BOOL isPasswordEmpty;
@end

@implementationLoginView

- (
id)initWithFrame:(CGRect)frame{
   
self = [super initWithFrame:frame];
   
if (self) {
        [
selfaddLoginBackgroundView:frame];
        [
selfcustomAllButtons:frame];
        [
selfcustomUserTextField:self.backgroundView.frame];
        [
selfcustomPasswordTextField:self.backgroundView.frame];
    }
   
return self;
}
//添加textField的背景View
- (void)addLoginBackgroundView:(CGRect)frame{
   
CGFloat backgroundX = 30;
   
CGFloat backgroundY = 160;
   
CGFloat backgroundW = frame.size.width- 60;
   
CGFloat backgroundH = 80;
   
self.backgroundView= [[LoginBackgroundViewalloc]initWithFrame:CGRectMake(backgroundX, backgroundY, backgroundW, backgroundH)];
    [
self.backgroundViewsetBackgroundColor:[UIColorwhiteColor]];
    [
self.backgroundView.layersetCornerRadius:5.0];
    [
self.backgroundView.layersetBorderWidth:1.0];
    [
self.backgroundView.layersetBorderColor:textFieldColor(207,207,207).CGColor];
    [
self addSubview:self.backgroundView];
}

- (
void)customAllButtons:(CGRect)frame{
   
//返回button
   
UIButton*backButton = [[UIButtonalloc]initWithFrame:CGRectMake(19,35,22,22)];
    [backButton
setBackgroundImage:[UIImageimageNamed:@"back"]forState:UIControlStateNormal];
    [backButton
addTarget:selfaction:@selector(clickTheBackButton:)forControlEvents:UIControlEventTouchDown];
    [
self addSubview:backButton];
   
//登录button
   
CGFloat loginButtonX = 30;
   
CGFloat loginButtonY = 250;
   
CGFloat loginButtonW = frame.size.width- 60;
   
self.loginButton= [[UIButtonalloc]initWithFrame:CGRectMake(loginButtonX, loginButtonY, loginButtonW,40)];
    [
self.loginButtonsetEnabled:NO];
   
self.loginButton.titleLabel.alpha= 0.5;
    [
self.loginButton.layersetCornerRadius:3.0];
    [
self.loginButtonsetTitle:@"登录"forState:UIControlStateNormal];
    [
self.loginButtonsetTitleColor:[UIColorwhiteColor]forState:UIControlStateReserved];
    [
self.loginButtonsetBackgroundColor:mianBodyColor(133,122,250)];
    [
self.loginButtonaddTarget:selfaction:@selector(clickLoginButton:)forControlEvents:UIControlEventTouchDown];
    [
self addSubview:self.loginButton];
   
//忘记密码
   
CGFloat forgetButtonW = 73;
   
CGFloat forgetButtonX = loginButtonX + loginButtonW - forgetButtonW;
   
CGFloat forgetButtonY = 0.916* (loginButtonY + 100);
   
CGFloat forgetButtonH = 20;
   
UIButton*forgetButton = [[UIButtonalloc]initWithFrame:CGRectMake(forgetButtonX, forgetButtonY, forgetButtonW, forgetButtonH)];
    [forgetButton
addTarget:selfaction:@selector(clickForgetpasswordTextFieldButton:)forControlEvents:UIControlEventTouchDown];
    [forgetButton
setTitle:@"忘记密码?"forState:UIControlStateNormal];
    [forgetButton.
titleLabelsetFont:[UIFontsystemFontOfSize:14]];
    [forgetButton
setTitleColor:textFieldColor(74,74,74)forState:UIControlStateNormal];
    [
self addSubview:forgetButton];
}

- (
void)customUserTextField:(CGRect)frame{
   
self.userTextField= [[BasicTextFieldalloc]initWithFrame:CGRectMake(0,0, frame.size.width,40)];
   
self.userTextField.keyboardType= UIKeyboardTypeNumberPad;
   
self.userTextField.delegate= self;
   
self.userTextField.tag= 7;
   
self.userTextField.placeholder= @"请输入账号";
    [
self.userTextFieldsetFont:[UIFontsystemFontOfSize:14]];
   
UIImageView*userTextFieldImage = [[UIImageViewalloc]initWithImage:[UIImageimageNamed:@"userIcon"]];
   
self.userTextField.leftView= userTextFieldImage;
   
self.userTextField.leftViewMode= UITextFieldViewModeAlways;
   
self.userTextField.clearButtonMode= UITextFieldViewModeAlways;
    [[
NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(userTextFieldDidChange)name:UITextFieldTextDidChangeNotificationobject:self.userTextField];
   
self.isPasswordEmpty= YES;
    [
self.backgroundViewaddSubview:self.userTextField];
}

- (
void)customPasswordTextField:(CGRect)frame{
   
self.passwordTextField= [[BasicTextFieldalloc]initWithFrame:CGRectMake(0,40, frame.size.width,40)];
   
self.passwordTextField.delegate= self;
   
self.passwordTextField.tag= 11;
   
self.passwordTextField.placeholder= @"请输入密码";
    [
self.passwordTextFieldsetFont:[UIFontsystemFontOfSize:14]];
   
UIImageView*passwordTextFieldImage = [[UIImageViewalloc]initWithImage:[UIImageimageNamed:@"passwordIcon"]];
   
self.passwordTextField.leftView= passwordTextFieldImage;
   
self.passwordTextField.leftViewMode= UITextFieldViewModeAlways;
   
self.passwordTextField.clearButtonMode= UITextFieldViewModeAlways;
   self.passwordTextField.secureTextEntry= YES;
//设置监听
    [[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(passwordTextFieldDidChange)name:UITextFieldTextDidChangeNotificationobject:self.passwordTextField];
   
self.isUserEmpty= YES;
    [
self.backgroundViewaddSubview:self.passwordTextField];
}

- (
void)addLogioningActivityIndicatorView{
   
CGFloat logioningActivityIndicatorViewX = self.loginButton.frame.origin.x+ 80;
   
CGFloat logioningActivityIndicatorViewY = self.loginButton.frame.origin.y;
   
CGFloat logioningActivityIndicatorViewWH = self.loginButton.frame.size.height;
   
self.logioningActivityIndicatorView= [[UIActivityIndicatorViewalloc]initWithFrame:CGRectMake(logioningActivityIndicatorViewX, logioningActivityIndicatorViewY, logioningActivityIndicatorViewWH, logioningActivityIndicatorViewWH)];
    [
self addSubview:self.logioningActivityIndicatorView];
}

- (void)clickLoginButton:(id)sender{
    [self.loginButtonsetTitle:@"登录中..."forState:UIControlStateNormal];
    [
self addLogioningActivityIndicatorView];
    [self.logioningActivityIndicatorViewstartAnimating];
//当点击登录按钮时,账号和密码输入框放弃第一响应者,此时键盘退出
    [self.userTextFieldresignFirstResponder];
    [
self.passwordTextFieldresignFirstResponder];
}

- (void)clickForgetpasswordTextFieldButton:(id)sender{
   //点击忘记密码button后需要执行的代码
}

- (void)clickTheBackButton:(id)sender{
  //点击左上角圈叉按钮返回上一界面
}

#pragma makr --UITextFieldDelegate
//UITextField的代理方法,点击键盘return按钮退出键盘
- (BOOL)textFieldShouldReturn:(UITextField*)textField{
    [self.passwordTextFieldresignFirstResponder];
   
return YES;
}
//此处为userTextField的监听方法,后面会细讲,主要是实时监听textField值的变化
- (void)userTextFieldDidChange{
   
if (self.userTextField.text.length> 0) {
       
UIImageView*loginTextFieldImage = [[UIImageViewalloc]initWithImage:[UIImageimageNamed:@"userIconEdited"]];
       
self.userTextField.leftView= loginTextFieldImage;
       
self.isUserEmpty= NO;
       
if (self.isPasswordEmpty== NO) {
           
self.loginButton.titleLabel.alpha= 1;
            [
self.loginButtonsetEnabled:YES];
        }
    }
else{
       
UIImageView*loginTextFieldImage = [[UIImageViewalloc]initWithImage:[UIImageimageNamed:@"userIcon"]];
       
self.userTextField.leftView= loginTextFieldImage;
        [
self.loginButtonsetTitle:@"登录"forState:UIControlStateNormal];
       
self.loginButton.titleLabel.alpha= 0.5;
        [
self.loginButtonsetEnabled:NO];
       
self.isUserEmpty= YES;
        [
self.logioningActivityIndicatorViewstopAnimating];
    }
}
//passwordTextField的监听方法
- (void)passwordTextFieldDidChange{
    
if (self.passwordTextField.text.length> 0) {
        
self.isPasswordEmpty= NO;
         
UIImageView*loginTextFieldImage = [[UIImageViewalloc]initWithImage:[UIImageimageNamed:@"passwordIconEdited"]];
        
self.passwordTextField.leftView= loginTextFieldImage;
        
if (self.isUserEmpty== NO){
            
self.loginButton.titleLabel.alpha= 1;
             [
self.loginButtonsetEnabled:YES];
         }
      }
else{
         
self.isPasswordEmpty= YES;
         
UIImageView*loginTextFieldImage = [[UIImageViewalloc]initWithImage:[UIImageimageNamed:@"passwordIcon"]];
       
self.passwordTextField.leftView= loginTextFieldImage;
        [
self.loginButtonsetTitle:@"登录"forState:UIControlStateNormal];
       
self.loginButton.titleLabel.alpha= 0.5;
        [
self.loginButtonsetEnabled:NO];
        [
self.logioningActivityIndicatorViewstopAnimating];
    }
}
//点击界面空白处退出键盘
- (void)touchesBegan:(NSSet<UITouch*> *)touches withEvent:(UIEvent*)event{
    [
self.userTextFieldresignFirstResponder];
    [
self.passwordTextFieldresignFirstResponder];
}
@end

四、登录界面一些与用户交互的细节问题处理:
1、可以看到当选中账号输入框时,左边的图片没有变化;而输入字符时图片就会变为紫色。我开始是用UITextField的代理方法,但是都达不到预想的效果,最后用注册通知监听器的方式实现了实时监测textField的改变。即用下面的方法:
[[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(userTextFieldDidChange)name:UITextFieldTextDidChangeNotificationobject:self.userTextField];

observer:监听器,即谁要接收这个通知。

Selector:收到通知后,回调监听器的这个方法,并且把通知对象当做参数传入。

name:通知的名称,如果为nil,无论通知的名称是什么,监听器都能收到这个通知。

object:通知发布者,如果object和name都为nil,监听器收到所有的通知。

2、- (void)userTextFieldDidChange:所以可以在这个方法能内写入当userTextField内的值被改变后,需要执行的代码。例如上面当userTextField的输入数字时右侧图片变为紫色的图片。

3、关于UItextField的代理方法,可以根据需求自行选择。
可以看到当账号和密码输入框都被输入后,登录按钮此时变成可以点击了。
这个就是在- (void)userTextFieldDidChange:方法中设置的。
self.loginButton.titleLabel.alpha= 1;//设置登录的titleLabel的透明度为1(初始值为0.5)
[self.loginButtonsetEnabled:YES];//设置登录按钮可以被点击(初始值为NO)
登录界面看起来简单,但是很多不起眼的功能就可能影响到用户体验,所以做好登录和注册界面的重要性不言而喻。
4、退出键盘
//当点击空白处退出键盘
- (void)touchesBegan:(NSSet<UITouch*> *)touches withEvent:(UIEvent*)event{
    [self.userTextFieldresignFirstResponder];
    [
self.passwordTextFieldresignFirstResponder];
}
resign这个单词有辞职的意思,这里就是某某放弃第一响应者的意思;如果个是点击userTextField调出的键盘,userTextField就是键盘的第一响应者,当userTextField放弃第一响应后,键盘退出。同理是谁叫出了键盘,就谁调用resignFirstResponderl来退出键盘。而在哪何时退出键盘就看交互需要了。

四、注册界面的实现方式和登录界面一样,注册界面能的更多功能都可以根据这些来实现。这里就不再帖代码了。 
1 1