百思不得姐之立即登录注册模块(五)

一 功能图和实现思路

具体功能图:

这里写图片描述

实现思路:
—-> 1 关注控制器模块搭建(xib)
—-> 2 登录和注册界面的总体模块数量(三个模块),可以用三个view来装各自的子控件
—-> 2.2 先做上面的view—>中间的view—>底部的view(顺序自定)
—-> 2.3 创建两个xib,用同一个类来管理两个xib
—-> 2.4 将中间的view的宽度改为屏幕的两倍
—-> 2.5 用拖线的方式修改约束,达到app的整体效果

二 关注控制器模块搭建

1 由整体的app效果图可以看出,直接采用xib的方式来布局
—-> 1.1 具体创建的文件

这里写图片描述

—-> 1.2 xib中在控制器中所有的子控件都处于控制器的中心

这里写图片描述

2 关注控制器的业务逻辑
—-> 2.1 通过拖线的方式,监听立即登录按钮的点击
—-> 2.2 点击完后登录和注册的控制器出现的方式是modal出来的
—-> 2.3 具体代码
- (IBAction)loginRegister
{
    //创建控制器
    XFJLoginRegisterViewController *loginRegisterVC = [[XFJLoginRegisterViewController alloc] init];
    loginRegisterVC.view.backgroundColor = [UIColor redColor];

    [self presentViewController:loginRegisterVC animated:YES completion:nil];
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

三 退出和注册(登录)

1 创建xib来加载登录和注册部分
2 创建一个登录和注册控制器来管理逻辑部分
文件图片:

这里写图片描述

3 顶部两个按钮的设置
—-> 3.1 思路: 通过顶部控制器中添加一个view的方式来装”x”和”注册账号”两个按钮,在xib中设置个子控件的状态

这里写图片描述

—-> 3.2 “x”的业务逻辑,通过连线的方式,实现对modal出来的控制器返回
代码部分:
- (IBAction)backBtnClick
{
    [self dismissViewControllerAnimated:YES completion:nil];
}
 
 
  • 1
  • 2
  • 3
  • 4
—-> 3.3 由于注册账号和已有账号也有业务逻辑,这里我们放到后面讲

四 注册与登录

1 创建文件

这里写图片描述

2 在xib中约束好子控件的位置,然后在该类里面创建一个同样大小的xib,将登录模块中的”忘记密码”去掉,用同一个类来管理两个xib
—-> 2.1 提供两个快速加载xib的类方法
代码:
/**
 *  快速加载xib
 *
 *  @return 返回一个登录的xib
 */
+ (instancetype)loginView;
/**
 *  快速加载xib
 *
 *  @return 返回一个注册的xib
 */
+ (instancetype)registerView;
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
实现:
#pragma mark - 提供快速加载xib的类方法
#pragma mark - login(登录)
+ (instancetype)loginView
{
    return [[[NSBundle mainBundle] loadNibNamed:@"XFJloginRegisterView" owner:nil options:nil] firstObject];
}
#pragma mark - registerView(注册)
+ (instancetype)registerView
{
    return [[[NSBundle mainBundle] loadNibNamed:@"XFJloginRegisterView" owner:nil options:nil] lastObject];
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
—-> 2.2 对登录和注册两个按钮的背景图片的拉伸做处理
#pragma mark - 设置图片为未被拉伸的样式
- (void)awakeFromNib
{
    //不要调用super
//    [super awakeFromNib];

    //获取到当前按钮的背景图片
    UIImage *image = self.loginRegisterView.currentBackgroundImage;
    //设置拉伸的范围
    image = [image stretchableImageWithLeftCapWidth:image.size.width * 0.5 topCapHeight:image.size.height * 0.5];
    //将拉伸的图片赋值回去
    [self.loginRegisterView setBackgroundImage:image forState:UIControlStateNormal];
    //获取当前按钮的背景图片
    UIImage *image1 = self.loginBtnClick.currentBackgroundImage;

    //设置拉伸范围
    image1 = [image1 stretchableImageWithLeftCapWidth:image1.size.width * 0.5 topCapHeight:image1.size.height * 0.5];
    //将拉伸的图片赋值回去
    [self.loginBtnClick setBackgroundImage:image1 forState:UIControlStateNormal];
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

五 快速登录模块

1 需要创建的文件

这里写图片描述

2 布局好的xib显示图

这里写图片描述

3 加载xib(我这里也提供一个快速加载的类方法)
+ (instancetype)fastBtnClick
{
    return [[[NSBundle mainBundle] loadNibNamed:@"XFJFaseView" owner:nil options:nil] firstObject];
}
 
 
  • 1
  • 2
  • 3
  • 4

六 简单业务逻辑

1 将各个模块分别加入到对应的装xib的view中
#pragma mark - 添加中间的view
- (void)setUpMiddleView
{
    //创建登录对象
    XFJloginRegisterView *loginView = [XFJloginRegisterView loginView];
    //加入到view中
    [self.middleView addSubview:loginView];

    //创建注册对象
    XFJloginRegisterView *registerView = [XFJloginRegisterView registerView];
    //加入到view中
    [self.middleView addSubview:registerView];

    //创建快速登录对象
    XFJFaseView *fast = [XFJFaseView fastBtnClick];
    //加入到view中
    [self.fastView addSubview:fast];
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
2 点击注册账号和已有账号能快速切换到对应的模块的原理:通过创建一个两倍于屏幕宽度的view来装登录和注册模块,让后将注册模块的x改为一个屏幕的宽度,通过拿到约束来控制对模块的切换.
各个模块尺寸的代码部分:
#pragma mark - 设置登录和注册的尺寸
- (void)viewDidLayoutSubviews
{
    //从middleView中取出第0个view---->登录
    XFJloginRegisterView *loginView = self.middleView.subviews[0];
    //设置尺寸
    loginView.frame = CGRectMake(0, 0, self.middleView.XFJ_Width * 0.5, self.middleView.XFJ_Height);

    //从midleView中取出第1个view--->注册
    XFJloginRegisterView *registerView = self.middleView.subviews[1];
    //设置尺寸
    registerView.frame = CGRectMake(self.middleView.XFJ_Width * 0.5, 0, self.middleView.XFJ_Width * 0.5, self.middleView.XFJ_Height);

    //从fastView中取出第0个view---->快速登录
    XFJFaseView *fastView = self.fastView.subviews[0];
    //设置尺寸
    fastView.frame = self.fastView.bounds;
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
3 对注册账号和已有账号的监听(通过拖线)
—-> 代码部分一:(“x”按钮)
- (IBAction)backBtnClick
{
    [self dismissViewControllerAnimated:YES completion:nil];
}
 
 
  • 1
  • 2
  • 3
  • 4
—-> 代码部分二:(注册账号和已有账号)—->通过一个三目运算符来对约束的控制
- (IBAction)registerBtnClick:(UIButton *)button
{
    //点击后按钮状态
    button.selected = !button.selected;

    //修改宽度的约束
    self.widConstraint.constant = self.widConstraint.constant == 0 ? -XFJ_screenW : 0;
    //动画效果
    [UIView animateWithDuration:0.25 animations:^{
        [self.view layoutIfNeeded];
    }];
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

七 快速登录模块

1 问题一: 启动app的时候,快速登录模块中的按钮和文字摆放有问题,我们发现这种情况完全不满足需求.
不满足需求的快速登录的图片:

这里写图片描述

2 解决:自定义按钮;重写布局子控件的方法
代码部分:
#pragma mark - 重写按钮中的布局方法
- (void)layoutSubviews
{
    [super layoutSubviews];
    //修改按钮中图片的位置
    self.imageView.XFJ_centerX = self.XFJ_Width * 0.5;
    self.imageView.XFJ_Y = 0;

    //文字自适应
    [self.titleLabel sizeToFit];
    //修改标题的位置
    self.titleLabel.XFJ_centerX = self.XFJ_Width * 0.5;
    self.titleLabel.XFJ_Y = self.XFJ_Height - self.titleLabel.XFJ_Height;
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
3 问题二:文字显示不出来(bug)
—-> 3.1 原因:label尺寸不够–> label跟文字一样
4 解决:自适应;让label的宽度和按钮的宽度一样

八 细节处理

1 问题:
1> 文本框的光标变成白色
2> 让占位文字颜色变成白色
2 处理方式:自定义文本
1> 创建的文件

这里写图片描述

3 监听文本—–> 在加载xib的方法中监听文本的改变
—-> 3.1 监听方式:addTarget
—-> 3.2 不用代理监听的原因:自己监听自己的改变,没有意义
代码部分:(注意代码书写的位置,是写在加载xib的方法中)
//监听文本开始编辑
    [self addTarget:self action:@selector(textChange) forControlEvents:UIControlEventEditingDidBegin];
    //监听文本结束
    [self addTarget:self action:@selector(textEnd) forControlEvents:UIControlEventEditingDidEnd];
 
 
  • 1
  • 2
  • 3
  • 4
​4 处理编辑文本的光标
代码:
self.tintColor = [UIColor whiteColor];
 
 
  • 1
5 处理占位文字的颜色(三种方法)
—-> 5.1 用副文本(第一种:不推荐;代码量较多)
让文本的占位颜色在未开始编辑之前就有对应的颜色:(代码)
//让文本一开始就是这种颜色(第一种方法)
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    dict[NSForegroundColorAttributeName] = [UIColor lightGrayColor];
    self.attributedPlaceholder = [[NSAttributedString alloc] initWithString:self.placeholder attributes:dict];
 
 
  • 1
  • 2
  • 3
  • 4
开始改变的时候代码:
//创建可变字典,用来描述文字颜色(第一种)
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    //用字典包装文字颜色
    dict[NSForegroundColorAttributeName] = [UIColor whiteColor];
    //修改颜色
    self.attributedPlaceholder = [[NSAttributedString alloc] initWithString:self.placeholder attributes:dict];
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
结束编辑时候代码:
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    dict[NSForegroundColorAttributeName] = [UIColor lightGrayColor];
    self.attributedPlaceholder = [[NSAttributedString alloc] initWithString:self.placeholder attributes:dict];
 
 
  • 1
  • 2
  • 3
—-> 5.2 苹果的私有属性placeholderLabel(第二种: 可以使用)
未编辑之间代码:
UILabel *labelText = [self valueForKey:@"placeholderLabel"];
    labelText.textColor = [UIColor lightGrayColor];
 
 
  • 1
  • 2
开始编辑的代码:
UILabel *labelText = [self valueForKey:@"placeholderLabel"];
    labelText.textColor = [UIColor whiteColor];
 
 
  • 1
  • 2
结束编辑的代码:
UILabel *labelText = [self valueForKey:@"placeholderLabel"];
    labelText.textColor = [UIColor lightGrayColor];
 
 
  • 1
  • 2
—-> 5.3 我们是不是想通过直接用”.”然后传入一种颜色,就能直接设置呢.通过一行代码搞定(第三种: 推荐)
—-> ​5.3.1 分类(设置占位文字的颜色)—->提供两个方法
//set方法
- (void)setPlaceholderColor:(UIColor *)placeholderColor
{
    //判断,如果占位为空,那么就直接设置为空
    if (self.placeholder == nil) {
        self.placeholder = @" ";
    }
    //获取占位文字控件
    UILabel *placeholderLabel = [self valueForKey:@"placeholderLabel"];

    //拿到控件去设置颜色(外界传入需要设置的颜色)
    placeholderLabel.textColor = placeholderColor;

}

//get方法
- (UIColor *)placeholderColor
{
    return nil;
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
—-> 5.3.2 调用代码(只用一行代码就可以搞定)
未编辑之前:
self.placeholderColor = [UIColor lightGrayColor];
 
 
  • 1
开始编辑:
self.placeholderColor = [UIColor whiteColor];
 
 
  • 1
结束编辑:
self.placeholderColor = [UIColor lightGrayColor];
 
 
  • 1

九 注意

1 注意: 在开发中,如果碰见很多的view都有同样的功能,自定义view去管理所有的view
2 注意: 以后如果想知道一个类里面有哪些私有的属性,可以采取断点方式查看.

十 补充

1 如果一个控件从xib加载,需不需要固定尺寸?—-> 必须要
2 在viewDidLoad设置子控件位置,行不行?—-> 不行—>在viewDidLayoutSubViews中设置属性,因为需要让约束执行完毕的时候,才设置属性位置.

十一 总结

1 该部分业务逻辑不是多,目的是让我们熟练的掌握自动布局,对约束的理解和运用
2 以后写代码之前一定要明白:代码写到哪个地方?是整个程序只加载一次呢?还是每次都要加载?需要仔细的考虑好.
3 登录与注册的业务逻辑还没有完全的写完,后续我讲及时的更新,如果大家有什么意见问题,请给我留言.如果您阅读了我的博客,感觉写的还行,麻烦您持续关注我的官方博客,一定为你奉上最清晰的代码思路,谢谢!!!!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值