一个登录注册界面的设计过程。有许多的小细节和技术点补充
- 在PCH文件中设置了一个全局颜色
#define CYARGBColor(a, r, g, b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:(a)/255.0]
#define CYColor(r, g, b) CYARGBColor(255, (r), (g), (b))
#define CYGrayColor(v) CYColor((v), (v), (v))
#define CYCommonBgColor CYGrayColor(215)
- 修改状态栏样式
// iOS7之前修改状态栏样式
[UIApplication sharedApplication].statusBarStyle;
// iOS7开始由控制器来修改状态栏样式
/**
* 让状态栏样式为白色
*/
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
/**
* 让状态栏样式为黑色
*/
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleDefault;
}
####一
- 一个这样的登录注册界面该如何做呢?它又会涉及到哪些技术点呢?
- 下面我给大家总结一下
-
从图中可以看出上面的“登录”部分和下面的“快速登录”部分是固定死的
-
当你发现界面的布局是固定不变的时候就得想到要用Xib进行布局
-
固定界面用Xib布局
- 用一个UIView把它们绑在一起
- UIView作为绑在一起的子控件的父控件(苹果不推荐使用像UIImageView之类的控件作为父控件,而推荐使用UIView)
- 也就是说容器一般就是UIView
-
先是整个一个大的“快速登录整体”UIView(给定固定宽高,定好约束)里面嵌套两个UIView(给定固定宽高)
- 一个是快速登录上部分,一个是其他快捷登录部分
- 将他们细分过来一步步做
- 主要是设置好约束
-
上部分的UIView
- “快速登录”的Lable加上两个ImageView的左右线。
- 设置约束,lable是先水平竖直居中,设置好大概的字体大小
- lable设定死的宽高
- 左线:距离左边0,上边0,下边0,右边5。
- 里面的图片设置属性Mode为Right就OK了
- 右线:距离左边5,上边0,下边0,右边0。
- 里面的图片设置属性Mode为Left就OK了
- 其他快捷登陆部分“QQ登录”“新浪微博”“腾讯微博”
- 就是三个Button
- 先设置好“QQ登录”这个按钮,再复制两个
- 设置三个宽度一致
- 再设置“QQ登录”距离左边0,上边0,下边0,右边0
- 再设置“新浪微博”距离不需要设置左边,上边0,下边0,右边0
- 再设置“腾讯微博”距离不需要设置左边,上边0,下边0,右边0
- “快速登录”的Lable加上两个ImageView的左右线。
-
由于有设定的背景,所以这些UIView的背景都设置为ClearColor
-
但是我们实际还需要去调整按钮中图片和文字的位置
- 要调整Button里面的子控件,所以我们自定义这个Button
- 自定义为CYQuickLoginButton,让三个按钮都继承于它
- 里面有ImageView和UILable
- 我们调整他们的位置就是调整x,y,width,heiht等值
- 为了方便我们这里封装一个UIView的类别(类扩展)
- 因为许多控件都是继承自UIView的,所以对其进行封装扩展可以更加方便的去改它的x,y,width,heiht等值
- 自定义为CYQuickLoginButton,让三个按钮都继承于它
####二 ####UIView的类别(类扩展)
- UIView+CYExtension.h文件中
#import <UIKit/UIKit.h>
@interface UIView (CYExtension)
@property (nonatomic, assign) CGFloat x;
@property (nonatomic, assign) CGFloat y;
@property (nonatomic, assign) CGFloat width;
@property (nonatomic, assign) CGFloat height;
@property (nonatomic, assign) CGFloat centerX;
@property (nonatomic, assign) CGFloat centerY;
@end
- UIView+CYExtension.m文件中 +重写它们的GET和SET方法
#import "UIView+CYExtension.h"
@implementation UIView (XMGExtension)
- (void)setX:(CGFloat)x
{
CGRect frame = self.frame;
frame.origin.x = x;
self.frame = frame;
}
- (CGFloat)x
{
return self.frame.origin.x;
}
- (void)setY:(CGFloat)y
{
CGRect frame = self.frame;
frame.origin.y = y;
self.frame = frame;
}
- (CGFloat)y
{
return self.frame.origin.y;
}
- (void)setWidth:(CGFloat)width
{
CGRect frame = self.frame;
frame.size.width = width;
self.frame = frame;
}
- (CGFloat)width
{
return self.frame.size.width;
}
- (void)setHeight:(CGFloat)height
{
CGRect frame = self.frame;
frame.size.height = height;
self.frame = frame;
}
- (CGFloat)height
{
return self.frame.size.height;
}
- (void)setCenterX:(CGFloat)centerX
{
CGPoint center = self.center;
center.x = centerX;
self.center = center;
}
- (CGFloat)centerX
{
return self.center.x;
}
- (void)setCenterY:(CGFloat)centerY
{
CGPoint center = self.center;
center.y = centerY;
self.center = center;
}
- (CGFloat)centerY
{
return self.center.y;
}
@end
- 那么在CYQuickLoginButton.m文件中
#import "CYQuickLoginButton.h"
@implementation CYQuickLoginButton
- (void)awakeFromNib
{
self.titleLabel.textAlignment = NSTextAlignmentCenter;
}
- (void)layoutSubviews
{
[super layoutSubviews];
// 这里先调用super,会先计算好按钮里面控件的位置和尺寸
// 然后下面的代码再进行位置的相关调整
// 一定得搞清楚先后顺序
// 调整图片的位置和尺寸
self.imageView.y = 0;
self.imageView.centerX = self.width * 0.5;
// 调整文字的位置和尺寸
self.titleLabel.x = 0;
self.titleLabel.y = self.imageView.height;
self.titleLabel.width = self.width;
self.titleLabel.height = self.height - self.titleLabel.y;
}
@end
####三
- 登录界面的设计
- 设置手机号与密码两个文本框
- 用于有UIXiew“登录界面整体”的父容器
- 里面嵌套一个“文本输入框整体”的UIView
- 文本框“手机号”和“密码”的文字输入键盘设置不一样
-
设置登录按钮
- 登录按钮与“文本输入框整体”设置左右对齐,高为35,距离上面25
- 按钮里设置好图片就OK了
- 那么问题来了,怎么设置登录按钮的圆角呢,许多时候都用的着的
-
代码设置
- 拖线到登录界面,设置属性,然后
#import "CYLoginRegisterViewController.h"
@interface CYLoginRegisterViewController ()
//@property (weak, nonatomic) IBOutlet UIButton *loginButton;
@end
@implementation CYLoginRegisterViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 代码实现一:
self.loginButton.layer.cornerRadius = 5;
self.loginButton.layer.masksToBounds = YES;
// 代码实现二:
self.loginButton.layer.cornerRadius = 5;
self.loginButton.clipsToBounds = YES;
// 代码实现三:
[self.loginButton setValue:@5 forKeyPath:@"layer.cornerRadius"];
[self.loginButton setValue:@YES forKeyPath:@"layer.masksToBounds"];
}
- 从上面看出KVC赋值很方便,但是也可以不用代码
- 而是在Xib中用KVC
- 记住:凡是KVC能实现的东西,在Xib中都可以设置
####四
- 我们想要修改文本框里占位文字的颜色,光标等(系统的一般不能满足)
- 方法一:拖线两次,分别设置。(不推荐)
- 方法二:自定义文本框(推荐)到时候每个文本框继承于我自定义的文本框就可以了
自定义文本框TextFiled
- 当我们遇上不会的东西像这里需要设置的光标颜色,文字颜色。不知道该怎么去设置,就可以多试一下,进入UIColor的头文件,各种搜查,最后不就是会找到一个叫做TinClolor的属性,就可以设置光标的颜色了。遇到不会的多试试没准就找到方法了
- 那么又会发现占位文字的颜色找不到怎么修改
- 根据经验一般在placeholder的附近去找,你会发现有一个attributedPlaceholder
- 这也就是带有属性的占位文字(富文本)
- 占位文字默认是带有70%灰色的
- 而attributedPlaceholder就可以去设置了,进入头文件多找找嘛
- (void)awakeFromNib
{
// 文本框的光标颜色
self.tintColor = [UIColor whiteColor];
// 文字颜色
self.textColor = [UIColor whiteColor];
// 设置带有属性的占位文字(也称为富文本)
self.attributedPlaceholder = [[NSAttributedString alloc] initWithString:self.placeholder attributes:@{NSForegroundColorAttributeName : [UIColor grayColor]}];
//把我们以前普普通通的占位文字传进去(initWithString)变成一个带有属性的占位文字(字典attributes)
}
- 假如我们找不到相关属性,那这个时候我们该怎么办呢?这样的话,我们只能重写某些方法了
- 你在头文件里面搜索placeholder,你就会搜到drawPlaceholderInRect:这个方法
- 我们重写drawPlaceholderInRect:方法
- 这里有画占位文字的两种方法
#import "CYLoginRegisterTextField.h"
@implementation CYLoginRegisterTextField
- (void)awakeFromNib
{
// 文本框的光标颜色
self.tintColor = [UIColor whiteColor];
// 文字颜色
self.textColor = [UIColor whiteColor];
}
- (void)drawPlaceholderInRect:(CGRect)rect
{
// 占位文字画在哪个矩形框里面
CGRect placeholderRect = self.bounds;
placeholderRect.origin.y = (self.height - self.font.lineHeight) * 0.5;
// 文字属性
NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
attrs[NSForegroundColorAttributeName] = [UIColor redColor];
attrs[NSFontAttributeName] = self.font;
[self.placeholder drawInRect:placeholderRect withAttributes:attrs];
// 占位文字画在哪个位置
// CGPoint point;
// point.x = 0;
// point.y = (self.height - self.font.lineHeight) * 0.5;
//
// // 文字属性
// NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
// attrs[NSForegroundColorAttributeName] = [UIColor redColor];
// attrs[NSFontAttributeName] = self.font;
// [self.placeholder drawAtPoint:point withAttributes:attrs];
}
- 还有一种方法:利用运行时Runtime查找到有placeholderLabel这个对象,运用KVC对其属性进行赋值(可以根据自己的经验试试)
#import "CYLoginRegisterTextField.h"
#import <objc/runtime.h>
@implementation CYLoginRegisterTextField
- (void)awakeFromNib
{
// 文本框的光标颜色
self.tintColor = [UIColor whiteColor];
// 文字颜色
self.textColor = [UIColor whiteColor];
# pragma mark - 设置占位文字的相关属性--方法三-通过运行时拿到相关属性,再利用KVC进行赋值
// UILabel *placeholderLabel = [self valueForKeyPath:@"placeholderLabel"];
// placeholderLabel.textColor = [UIColor redColor];
[self setValue:[UIColor grayColor] forKeyPath:@"placeholderLabel.textColor"];
/**
1.什么是运行时(Runtime)?
* 运行时是苹果提供的纯C语言的开发库(是一种非常牛逼、开发中经常用到的底层技术)
2.运行时的作用?
* 能获得某个类的所有成员变量
* 能获得某个类的所有属性
* 能获得某个类的所有方法
* 交换方法实现
* 能动态添加一个成员变量
* 能动态添加一个属性
* 能动态添加一个方法
*/
// 成员变量的数量
unsigned int outCount = 0;
// 获得所有的成员变量
Ivar *ivars = class_copyIvarList([UITextField class], &outCount);
// 遍历所有的成员变量
for (int i = 0; i<outCount; i++) {
// 取出i位置对应的成员变量
Ivar ivar = ivars[i];
// 获得成员变量的名字
NSLog(@"%s", ivar_getName(ivar));
}
// 如果函数名中包含了copy\new\retain\create等字眼,那么这个函数返回的数据就需要手动释放
free(ivars);
}
- 上面将会打印出UITextFild的所有底层成员变量
- 通过KVC就可以直接赋值了
- 打印结果如下:
####五
-
下面补充一下 运行时Runtime
-
以下面简单举例
-
可以拿到所有的成员变量
-
CYPerson.h文件中:
#import <Foundation/Foundation.h>
@interface CYPerson : NSObject
{
int _test;
}
@property (nonatomic, assign) int age;
@property (nonatomic, copy) NSString *name;
@end
- CYPerson.m文件中:
#import "CYPerson.h"
@interface CYPerson()
{
int _no;
}
@property (nonatomic, assign) double height;
@end
@implementation CYPerson
{
int _money;
}
@end
- main.m文件中
#import <Foundation/Foundation.h>
#import "CYPerson.h"
#import <objc/runtime.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
// 成员变量的数量
unsigned int outCount = 0;
// 获得所有的成员变量
// ivars是一个指向成员变量的指针
// ivars默认指向第0个成员变量(最前面)
Ivar *ivars = class_copyIvarList([CYPerson class], &outCount);
NSLog(@"%zd",outCount);
//为什么用传outCount地址用&outCount指针呢?只有将这个outCount变量地址值传进去了,那我们的函数内部获取完你所有的成员变量能算出你的个数以后,根据你传进来的变量地址值找到你outCount这个变量外面的存储空间,把你的值改一改,这样才能改你的值
//
// 遍历所有的成员变量
for (int i = 0; i<outCount; i++) {
// 取出i位置对应的成员变量
// Ivar ivar = *(ivars + i);
Ivar ivar = ivars[i];
// C语言中如果这个指针指向首元素地址,就可以把它当做数组来用。
// 获得成员变量的名字
NSLog(@"%s", ivar_getName(ivar));
}
// 如果函数名中包含了copy\new\retain\create等字眼,那么这个函数返回的数据就需要手动释放。这里不是ARC是C语言
free(ivars);
// Ivar ivar = *ivars;
// *ivars表示取出这个指针指向的地址中的值
// Ivar ivar2 = *(ivars + 1);
// NSLog(@"%s %s", ivar_getName(ivar), ivar_getName(ivar2));
// 一个Ivar就代表一个成员变量Ivar(instance variable实例变量)
// int *p; 指向int类型的变量
// Ivar *ivars; 指向Ivar类型的变量
// 最后不管你开不开源,我们都能取出所有的成员变量
}
return 0;
}
####六
- 富文本相关使用
- 可以用于很多地方,文字的相关属性的改变(创建可变的属性文字)
富文本用法1 - 不可变的属性文字
- (void)awakeFromNib
{
// 文本框的光标颜色
self.tintColor = CYPlaceholderFocusColor;
// 文字颜色
self.textColor = CYPlaceholderFocusColor;
// 设置占位文字颜色为白色
NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
attrs[NSForegroundColorAttributeName] = [UIColor whiteColor];
// 设置占位文字是否有下划线(0是NO,1是YES)
attrs[NSUnderlineStyleAttributeName] = @1;
// 设置占位文字的下划线颜色为红色
attrs[NSUnderlineColorAttributeName] = [UIColor redColor];
self.attributedPlaceholder = [[NSAttributedString alloc] initWithString:self.placeholder attributes:attrs];
富文本用法2 - 可变的属性文字
- (void)awakeFromNib
{
// 文本框的光标颜色
self.tintColor = CYPlaceholderFocusColor;
// 文字颜色
self.textColor = CYPlaceholderFocusColor;
NSAttributedString和NSMutableAttributedString
// 一个是创建了就不可以修改属性了,另外一个还可以修改属性,所以使用NSMutableAttributedString在它创建的时候就修改属性
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:self.placeholder];
[string addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, 1)];
// 在0位置(第一个)文字截取1个长度并把它的文字颜色设置为红色(手机号的“手”,密码的“密”)
[string addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(1, 1)];
// 在1位置(第二个)文字截取1个长度并把它的文字颜色设置为绿色(手机号的“机”密码的“码”)
[string addAttribute:NSFontAttributeName value:[UIFont boldSystemFontOfSize:30] range:NSMakeRange(1, 1)];
// 在1位置(第二个)文字截取1个长度并把它的文字字体大小设置为30(手机号的“机”密码的“码”)
self.attributedPlaceholder = string;
富文本用法3 - 图文混排-常见于聊天的搞怪文字中
- (void)awakeFromNib
{
// 文本框的光标颜色
self.tintColor = CYPlaceholderFocusColor;
// 文字颜色
self.textColor = CYPlaceholderFocusColor;
// 将文字,图片,文字分为三段(后面它们的顺序可以调整),先把它们都包装成三个属性文字(NSAttributedString),再调用(NSMutableAttributedString)的appendAttributedString:方法,最后拼接起来
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] init];
// 第二段:图片
// attachment附件的意思,可以传图片
NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
attachment.image = [UIImage imageNamed:@"login_close_icon"];
// 可以调整图片的大小和位置
attachment.bounds = CGRectMake(0, 0, 16, 16);
NSAttributedString *subtring2 = [NSAttributedString attributedStringWithAttachment:attachment];
[string appendAttributedString:subtring2];
// 第一段:placeholder
NSAttributedString *substring1 = [[NSAttributedString alloc] initWithString:self.placeholder];
[string appendAttributedString:substring1];
// 第三段:哈哈
NSAttributedString *substring3 = [[NSAttributedString alloc] initWithString:@"哈哈"];
[string appendAttributedString:substring3];
self.attributedPlaceholder = string;
####七
- 点击文本框进行切换的时候占位文字颜色要发生改变(我想让它点击的时候颜色为白色,不点击的时候颜色为灰色)怎么做呢?
- 常规有三种方法,这里还增加一种
- 监听文本框UITextField的改变
- 1.通过代理(自己做自己的代理,代理的属性很容易被人覆盖,不合理,不推荐使用)
- 2.通过addTarget:方法(最简单)
- 3.通过通知监听(最后还得移除,麻烦)
- 4.第一响应者(额外方法,这里推荐)
- 监听文本框UITextField的改变
- 1.代理
@interface CYLoginRegisterTextField() <UITextFieldDelegate>
@end
@implementation CYLoginRegisterTextField
- (void)awakeFromNib
{
// 文本框的光标颜色
self.tintColor = [UIColor whiteColor];
// 文字颜色
self.textColor = [UIColor whiteColor];
// 设置占位文字的颜色
[self setValue:[UIColor grayColor] forKeyPath:@"placeholderLabel.textColor"];
self.delegate = self;
}
#pragma mark -UITextFieldDelegate
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
[self setValue:[UIColor whiteColor] forKeyPath:@"placeholderLabel.textColor"];
}
-(void)textFieldDidEndEditing:(UITextField *)textField
{
[self setValue:[UIColor grayColor] forKeyPath:@"placeholderLabel.textColor"];
}
- 2.addTarget:方法。
- 因为UITextField继承于UIControl
- UIControl给了UITextField四个方法
UIControlEventEditingDidBegin = 1 << 16, // UITextField
UIControlEventEditingChanged = 1 << 17,
UIControlEventEditingDidEnd = 1 << 18,
UIControlEventEditingDidEndOnExit = 1 << 19, // 'return key' ending
@implementation CYLoginRegisterTextField
- (void)awakeFromNib
{
// 文本框的光标颜色
self.tintColor = [UIColor whiteColor];
// 文字颜色
self.textColor = [UIColor whiteColor];
// 设置占位文字的颜色
[self setValue:[UIColor grayColor] forKeyPath:@"placeholderLabel.textColor"];
// 监听文本框的开始和结束
[self addTarget:self action:@selector(beginEditing) forControlEvents:UIControlEventEditingDidBegin];
[self addTarget:self action:@selector(endEditing) forControlEvents:UIControlEventEditingDidEnd];
}
-(void)beginEditing
{
[self setValue:[UIColor whiteColor] forKeyPath:@"placeholderLabel.textColor"];
}
-(void)endEditing
{
[self setValue:[UIColor grayColor] forKeyPath:@"placeholderLabel.textColor"];
}
- 3.通过通知监听文本框的开始与结束编辑
- 注意:里面的object为什么传self
- 因为传nil是监听所有文本框的编辑
- 这里只需要监听自己文本框的编辑就OK了
- 还有最后得移除dealloc
@implementation CYLoginRegisterTextField
- (void)awakeFromNib
{
// 文本框的光标颜色
self.tintColor = [UIColor whiteColor];
// 文字颜色
self.textColor = [UIColor whiteColor];
// 设置占位文字的颜色
[self setValue:[UIColor grayColor] forKeyPath:@"placeholderLabel.textColor"];
// 通过通知--监听文本框的开始和结束编辑
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(beginEditing) name:UITextFieldTextDidBeginEditingNotification object:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(endEditing) name:UITextFieldTextDidEndEditingNotification object:self];
}
-(void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
-(void)beginEditing
{
[self setValue:[UIColor whiteColor] forKeyPath:@"placeholderLabel.textColor"];
}
-(void)endEditing
{
[self setValue:[UIColor grayColor] forKeyPath:@"placeholderLabel.textColor"];
}
- 4.第一响应者
@implementation CYLoginRegisterTextField
- (void)awakeFromNib
{
// 文本框的光标颜色
self.tintColor = [UIColor whiteColor];
// 文字颜色
self.textColor = [UIColor whiteColor];
// 设置占位文字的颜色
[self setValue:[UIColor grayColor] forKeyPath:@"placeholderLabel.textColor"];
[self resignFirstResponder];
}
/**
* 文本框聚焦时调用(成为第一响应者)(弹出当前文本框对应的键盘时调用)
*/
- (BOOL)becomeFirstResponder
{
[self setValue:[UIColor whiteColor] forKeyPath:@"placeholderLabel.textColor"];
return [super becomeFirstResponder];
}
/**
* 文本框失去焦点时调用(成为第一响应者)(弹出当前文本框对应的键盘时调用)
*/
- (BOOL)resignFirstResponder
{
[self setValue:[UIColor grayColor] forKeyPath:@"placeholderLabel.textColor"];
return [super resignFirstResponder];
}
- 最后进行一下代码的抽取,抽出一个宏出来
- 今后要想定义聚焦(点击)和不点击(默认)时的占位文字光标和文字颜色,就只需要修改两个颜色了
- 最后这种方法是一个非主流的方法,但是很实用
@implementation CYLoginRegisterTextField
// 占位文字颜色
#define CYPlaceholderColorKey @"placeholderLabel.textColor"
// 默认的占位文字颜色
#define CYPlaceholderDefaultColor [UIColor grayColor]
// 聚焦的占位文字颜色
#define CYPlaceholderFocusColor [UIColor whiteColor]
- (void)awakeFromNib
{
// 文本框的光标颜色
self.tintColor = CYPlaceholderFocusColor;
// 文字颜色
self.textColor = CYPlaceholderFocusColor;
// 设置占位文字的颜色
[self setValue:CYPlaceholderDefaultColor forKeyPath:CYPlaceholderColorKey];
[self resignFirstResponder];
}
/**
* 文本框聚焦时调用(成为第一响应者)(弹出当前文本框对应的键盘时调用)
*/
- (BOOL)becomeFirstResponder
{
[self setValue:CYPlaceholderFocusColor forKeyPath:CYPlaceholderColorKey];
return [super becomeFirstResponder];
}
/**
* 文本框失去焦点时调用(成为第一响应者)(弹出当前文本框对应的键盘时调用)
*/
- (BOOL)resignFirstResponder
{
[self setValue:CYPlaceholderDefaultColor forKeyPath:CYPlaceholderColorKey];
return [super resignFirstResponder];
}
####八
-
有关于登录与注册界面的切换
- 仔细观察就可以看出登录与注册界面只有“登录”与“注册”按钮文字还有“注册账号”与“已有账号”按钮文字不同外,其余都是一样。
- 所以就可以知道登录与注册只是一个view宽度的动画效果
-
那我们如何设置相关约束呢?
- 1.拷贝一份,删除忘记密码
- 2.设置好占位文字
- 3.设置宽度一致,顶部与左边对齐
- 4.在Horizontal Space Constraint中设置“注册界面.Leading”(左边)与“登陆界面.Trailing”(右边)相等(Equal)
- 这个时候,注册界面就跑到登录界面右边去了(但是你看不到)他随时待命了
- 接下来就只要把它拽过来就可以了,所以我们要开始监听按钮点击
- 1.将“注册账号”拖线到CYloginRegisterViewController.m文件中。将按钮传给它,监听按钮点击(logingOrRegister)
- 2.找到“登录界面”与父控件的左约束。因为我们要让“注册界面 ”过来,就得要让它的左约束为一个负的view的宽度
- 3.同样拖线到CYloginRegisterViewController.m里面,设置“leftSpace”属性
- 4.由于前面把“登录界面”的约束,左右两边都已经定死。所以当我们设置负一个view的宽度的时候,会不起作用,只会拉伸view
- 所以我们要找到那个右边的约束,将其删除
- 然后设置“登录界面”与背景或者是控制器的view的宽度一致
- 或者把右边的约束也改为负值
- 有一个小细节
- 你会发现“注册账号”与“已有账号?”切换的时候会有省略号
- 所以你要将状态改为Custom,button尺寸设置大一些,文字大小调整一下,文字居右对齐。这是一个小技巧
- 可以让文字更好看,而且用户点击按钮范围也大些
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *leadingSpace;
- (IBAction)loginOrRegister:(UIButton *)button
{
// 修改约束
if (self.leadingSpace.constant == 0) {
self.leadingSpace.constant = - self.view.width;
[button setTitle:@"已有账号?" forState:UIControlStateNormal];
}else
{
self.leadingSpace.constant = 0;
[button setTitle:@"注册账号" forState:UIControlStateNormal];
}
[UIView animateWithDuration:0.25 animations:^{
[self.view layoutIfNeeded];
}];
}
- 还有一种方法,不用代码去设置按钮的文字。而在Xib中用状态“Default”--"注册账号"与“Selected”--“已有账号?”去设置它的文字
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *leadingSpace;
- (IBAction)loginOrRegister:(UIButton *)button
{
// 修改约束
if (self.leadingSpace.constant == 0) {
self.leadingSpace.constant = - self.view.width;
// [button setTitle:@"已有账号?" forState:UIControlStateNormal];
button.selected = YES;
}else
{
self.leadingSpace.constant = 0;
// [button setTitle:@"注册账号" forState:UIControlStateNormal];
button.selected = NO;
}
[UIView animateWithDuration:0.25 animations:^{
[self.view layoutIfNeeded];
}];
}
- 一个登录注册界面搞定了,所有的细节和技术点都在里面