iOS登录界面和注册界面

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

@interface BasicTextField : UITextField

@end

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

@implementation BasicTextField

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

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

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

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

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

@interface LoginBackgroundView : UIView

@end

LoginBackgroundView.m文件:

#define mianBodyColor(r, g, b) [UIColor colorWithRed:r/ 255.0f green:g/ 255.0f blue:b/ 255.0f alpha: 1 ]
#import "LoginBackgroundView.h"

@implementation LoginBackgroundView

// 重写此方法,用 Quartz2D 画出中间分割线
-( void )drawRect:( CGRect )rect{
   
CGContextRef context = 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

@protocol LoginViewDelegate < NSObject >

@interface LoginView : UIView
@end

LoginView.m文件:

#define textFieldColor(r, g, b) [UIColor colorWithRed:r/ 255.0f green:g/ 255.0f blue:b/ 255.0f alpha: 1 ]
#define mianBodyColor(r, g, b) [UIColor colorWithRed:r/
255.0f green:g/ 255.0f blue:b/ 255.0f alpha: 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

@implementation LoginView

- (
id )initWithFrame:( CGRect )frame{
   
self = [ super initWithFrame :frame];
   
if ( self ) {
        [
self addLoginBackgroundView :frame];
        [
self customAllButtons :frame];
        [
self customUserTextField : self . backgroundView . frame ];
        [
self customPasswordTextField : 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 = [[ LoginBackgroundView alloc ] initWithFrame : CGRectMake (backgroundX, backgroundY, backgroundW, backgroundH)];
    [
self . backgroundView setBackgroundColor :[ UIColor whiteColor ]];
    [
self . backgroundView . layer setCornerRadius : 5.0 ];
    [
self . backgroundView . layer setBorderWidth : 1.0 ];
    [
self . backgroundView . layer setBorderColor : textFieldColor ( 207 , 207 , 207 ). CGColor ];
    [
self addSubview : self . backgroundView ];
}

- (
void )customAllButtons:( CGRect )frame{
   
// 返回 button
   
UIButton *backButton = [[ UIButton alloc ] initWithFrame : CGRectMake ( 19 , 35 , 22 , 22 )];
    [backButton
setBackgroundImage :[ UIImage imageNamed : @"back" ] forState : UIControlStateNormal ];
    [backButton
addTarget : self action : @selector (clickTheBackButton:) forControlEvents : UIControlEventTouchDown ];
    [
self addSubview :backButton];
   
// 登录 button
   
CGFloat loginButtonX = 30 ;
   
CGFloat loginButtonY = 250 ;
   
CGFloat loginButtonW = frame. size . width - 60 ;
   
self . loginButton = [[ UIButton alloc ] initWithFrame : CGRectMake (loginButtonX, loginButtonY, loginButtonW, 40 )];
    [
self . loginButton setEnabled : NO ];
   
self . loginButton . titleLabel . alpha = 0.5 ;
    [
self . loginButton . layer setCornerRadius : 3.0 ];
    [
self . loginButton setTitle : @" 登录 " forState : UIControlStateNormal ];
    [
self . loginButton setTitleColor :[ UIColor whiteColor ] forState : UIControlStateReserved ];
    [
self . loginButton setBackgroundColor : mianBodyColor ( 133 , 122 , 250 )];
    [
self . loginButton addTarget : self action : @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 = [[ UIButton alloc ] initWithFrame : CGRectMake (forgetButtonX, forgetButtonY, forgetButtonW, forgetButtonH)];
    [forgetButton
addTarget : self action : @selector (clickForgetpasswordTextFieldButton:) forControlEvents : UIControlEventTouchDown ];
    [forgetButton
setTitle : @" 忘记密码 ?" forState : UIControlStateNormal ];
    [forgetButton.
titleLabel setFont :[ UIFont systemFontOfSize : 14 ]];
    [forgetButton
setTitleColor : textFieldColor ( 74 , 74 , 74 ) forState : UIControlStateNormal ];
    [
self addSubview :forgetButton];
}

- (
void )customUserTextField:( CGRect )frame{
   
self . userTextField = [[ BasicTextField alloc ] initWithFrame : CGRectMake ( 0 , 0 , frame. size . width , 40 )];
   
self . userTextField . keyboardType = UIKeyboardTypeNumberPad ;
   
self . userTextField . delegate = self ;
   
self . userTextField . tag = 7 ;
   
self . userTextField . placeholder = @" 请输入账号 " ;
    [
self . userTextField setFont :[ UIFont systemFontOfSize : 14 ]];
   
UIImageView *userTextFieldImage = [[ UIImageView alloc ] initWithImage :[ UIImage imageNamed : @"userIcon" ]];
   
self . userTextField . leftView = userTextFieldImage;
   
self . userTextField . leftViewMode = UITextFieldViewModeAlways ;
   
self . userTextField . clearButtonMode = UITextFieldViewModeAlways ;
    [[
NSNotificationCenter defaultCenter ] addObserver : self selector : @selector (userTextFieldDidChange) name : UITextFieldTextDidChangeNotification object : self . userTextField ];
   
self . isPasswordEmpty = YES ;
    [
self . backgroundView addSubview : self . userTextField ];
}

- (
void )customPasswordTextField:( CGRect )frame{
   
self . passwordTextField = [[ BasicTextField alloc ] initWithFrame : CGRectMake ( 0 , 40 , frame. size . width , 40 )];
   
self . passwordTextField . delegate = self ;
   
self . passwordTextField . tag = 11 ;
   
self . passwordTextField . placeholder = @" 请输入密码 " ;
    [
self . passwordTextField setFont :[ UIFont systemFontOfSize : 14 ]];
   
UIImageView *passwordTextFieldImage = [[ UIImageView alloc ] initWithImage :[ UIImage imageNamed : @"passwordIcon" ]];
   
self . passwordTextField . leftView = passwordTextFieldImage;
   
self . passwordTextField . leftViewMode = UITextFieldViewModeAlways ;
   
self . passwordTextField . clearButtonMode = UITextFieldViewModeAlways ;
    self.passwordTextField.secureTextEntry = YES;
//设置监听
    [[ NSNotificationCenter defaultCenter ] addObserver : self selector : @selector (passwordTextFieldDidChange) name : UITextFieldTextDidChangeNotification object : self . passwordTextField ];
   
self . isUserEmpty = YES ;
    [
self . backgroundView addSubview : 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 = [[ UIActivityIndicatorView alloc ] initWithFrame : CGRectMake (logioningActivityIndicatorViewX, logioningActivityIndicatorViewY, logioningActivityIndicatorViewWH, logioningActivityIndicatorViewWH)];
    [
self addSubview : self . logioningActivityIndicatorView ];
}

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

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

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

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

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

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

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

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

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

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

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

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

你可能感兴趣的:(iOS学习之登录界面)