iOS登录界面和注册界面

本文介绍了如何在iOS中创建登录和注册界面,包括输入框的实现原理、使用Quartz2D绘制分隔线,以及自定义UITextField和背景视图。通过创建BasicTextField、LoginBackgroundView和LoginView类,实现了具有占位符、左侧图片和输入验证的登录界面。代码示例详细展示了各个组件的定制过程。
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"

@implementation BasicTextField

//  重写leftViewX
- (
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 <UIKit/UIKit.h>

@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 <UIKit/UIKit.h>

@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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值