- 在PCH文件中設(shè)置了一個(gè)全局顏色
#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)
- 修改狀態(tài)欄樣式
// iOS7之前修改狀態(tài)欄樣式
[UIApplication sharedApplication].statusBarStyle;
// iOS7開(kāi)始由控制器來(lái)修改狀態(tài)欄樣式
/**
* 讓狀態(tài)欄樣式為白色
*/
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
/**
* 讓狀態(tài)欄樣式為黑色
*/
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleDefault;
}
一
- 一個(gè)這樣的登錄注冊(cè)界面該如何做呢汞舱?它又會(huì)涉及到哪些技術(shù)點(diǎn)呢捌刮?
- 下面我給大家總結(jié)一下
從圖中可以看出上面的“登錄”部分和下面的“快速登錄”部分是固定死的
當(dāng)你發(fā)現(xiàn)界面的布局是固定不變的時(shí)候就得想到要用Xib進(jìn)行布局
-
固定界面用Xib布局
- 用一個(gè)UIView把它們綁在一起
- UIView作為綁在一起的子控件的父控件(蘋(píng)果不推薦使用像UIImageView之類(lèi)的控件作為父控件,而推薦使用UIView)
- 也就是說(shuō)容器一般就是UIView
-
首先對(duì)于下面的布局該怎么做呢?
-
先是整個(gè)一個(gè)大的“快速登錄整體”UIView(給定固定寬高,定好約束)里面嵌套兩個(gè)UIView(給定固定寬高)
- 一個(gè)是快速登錄上部分,一個(gè)是其他快捷登錄部分
- 將他們細(xì)分過(guò)來(lái)一步步做
- 主要是設(shè)置好約束
-
上部分的UIView
- “快速登錄”的Lable加上兩個(gè)ImageView的左右線谆级。
- 設(shè)置約束,lable是先水平豎直居中讼积,設(shè)置好大概的字體大小
- lable設(shè)定死的寬高
- 左線:距離左邊0肥照,上邊0,下邊0勤众,右邊5舆绎。
- 里面的圖片設(shè)置屬性Mode為Right就OK了
- 右線:距離左邊5,上邊0们颜,下邊0国裳,右邊0拯啦。
- 里面的圖片設(shè)置屬性Mode為L(zhǎng)eft就OK了
- 其他快捷登陸部分“QQ登錄”“新浪微博”“騰訊微博”
- 就是三個(gè)Button
- 先設(shè)置好“QQ登錄”這個(gè)按鈕顺饮,再?gòu)?fù)制兩個(gè)
- 設(shè)置三個(gè)寬度一致
- 再設(shè)置“QQ登錄”距離左邊0今布,上邊0,下邊0阻问,右邊0
- 再設(shè)置“新浪微博”距離不需要設(shè)置左邊梧税,上邊0,下邊0则拷,右邊0
- 再設(shè)置“騰訊微博”距離不需要設(shè)置左邊贡蓖,上邊0,下邊0煌茬,右邊0
- “快速登錄”的Lable加上兩個(gè)ImageView的左右線谆级。
由于有設(shè)定的背景,所以這些UIView的背景都設(shè)置為ClearColor
但是我們實(shí)際還需要去調(diào)整按鈕中圖片和文字的位置
-
要調(diào)整Button里面的子控件彻桃,所以我們自定義這個(gè)Button
- 自定義為CYQuickLoginButton坛善,讓三個(gè)按鈕都繼承于它
- 里面有ImageView和UILable
- 我們調(diào)整他們的位置就是調(diào)整x,y,width,heiht等值
- 為了方便我們這里封裝一個(gè)UIView的類(lèi)別(類(lèi)擴(kuò)展)
- 因?yàn)樵S多控件都是繼承自UIView的,所以對(duì)其進(jìn)行封裝擴(kuò)展可以更加方便的去改它的x,y,width,heiht等值
- 自定義為CYQuickLoginButton坛善,讓三個(gè)按鈕都繼承于它
二
UIView的類(lèi)別(類(lèi)擴(kuò)展)
- 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文件中
+重寫(xiě)它們的GET和SET方法
#import "UIView+CYExtension.h"
@implementation UIView (CYExtension)
- (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];
// 這里先調(diào)用super,會(huì)先計(jì)算好按鈕里面控件的位置和尺寸
// 然后下面的代碼再進(jìn)行位置的相關(guān)調(diào)整
// 一定得搞清楚先后順序
// 調(diào)整圖片的位置和尺寸
self.imageView.y = 0;
self.imageView.centerX = self.width * 0.5;
// 調(diào)整文字的位置和尺寸
self.titleLabel.x = 0;
self.titleLabel.y = self.imageView.height;
self.titleLabel.width = self.width;
self.titleLabel.height = self.height - self.titleLabel.y;
}
@end
-
最后就OK了
三
- 登錄界面的設(shè)計(jì)
- 設(shè)置手機(jī)號(hào)與密碼兩個(gè)文本框
- 用于有UIXiew“登錄界面整體”的父容器
- 里面嵌套一個(gè)“文本輸入框整體”的UIView
- 文本框“手機(jī)號(hào)”和“密碼”的文字輸入鍵盤(pán)設(shè)置不一樣
-
設(shè)置登錄按鈕
- 登錄按鈕與“文本輸入框整體”設(shè)置左右對(duì)齊邻眷,高為35眠屎,距離上面25
- 按鈕里設(shè)置好圖片就OK了
- 那么問(wèn)題來(lái)了,怎么設(shè)置登錄按鈕的圓角呢肆饶,許多時(shí)候都用的著的
-
代碼設(shè)置
- 拖線到登錄界面改衩,設(shè)置屬性,然后
#import "CYLoginRegisterViewController.h"
@interface CYLoginRegisterViewController ()
//@property (weak, nonatomic) IBOutlet UIButton *loginButton;
@end
@implementation CYLoginRegisterViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 代碼實(shí)現(xiàn)一:
self.loginButton.layer.cornerRadius = 5;
self.loginButton.layer.masksToBounds = YES;
// 代碼實(shí)現(xiàn)二:
self.loginButton.layer.cornerRadius = 5;
self.loginButton.clipsToBounds = YES;
// 代碼實(shí)現(xiàn)三:
[self.loginButton setValue:@5 forKeyPath:@"layer.cornerRadius"];
[self.loginButton setValue:@YES forKeyPath:@"layer.masksToBounds"];
}
- 從上面看出KVC賦值很方便驯镊,但是也可以不用代碼
- 而是在Xib中用KVC
- 記缀健:凡是KVC能實(shí)現(xiàn)的東西竭鞍,在Xib中都可以設(shè)置
四
- 我們想要修改文本框里占位文字的顏色,光標(biāo)等(系統(tǒng)的一般不能滿足)
- 方法一:拖線兩次橄镜,分別設(shè)置偎快。(不推薦)
- 方法二:自定義文本框(推薦)到時(shí)候每個(gè)文本框繼承于我自定義的文本框就可以了
自定義文本框TextFiled
- 當(dāng)我們遇上不會(huì)的東西像這里需要設(shè)置的光標(biāo)顏色,文字顏色洽胶。不知道該怎么去設(shè)置晒夹,就可以多試一下,進(jìn)入U(xiǎn)IColor的頭文件姊氓,各種搜查丐怯,最后不就是會(huì)找到一個(gè)叫做TinClolor的屬性,就可以設(shè)置光標(biāo)的顏色了翔横。遇到不會(huì)的多試試沒(méi)準(zhǔn)就找到方法了
- 那么又會(huì)發(fā)現(xiàn)占位文字的顏色找不到怎么修改
- 根據(jù)經(jīng)驗(yàn)一般在placeholder的附近去找响逢,你會(huì)發(fā)現(xiàn)有一個(gè)attributedPlaceholder
- 這也就是帶有屬性的占位文字(富文本)
- 占位文字默認(rèn)是帶有70%灰色的
- 而attributedPlaceholder就可以去設(shè)置了,進(jìn)入頭文件多找找嘛
- (void)awakeFromNib
{
// 文本框的光標(biāo)顏色
self.tintColor = [UIColor whiteColor];
// 文字顏色
self.textColor = [UIColor whiteColor];
// 設(shè)置帶有屬性的占位文字(也稱為富文本)
self.attributedPlaceholder = [[NSAttributedString alloc] initWithString:self.placeholder attributes:@{NSForegroundColorAttributeName : [UIColor grayColor]}];
//把我們以前普普通通的占位文字傳進(jìn)去(initWithString)變成一個(gè)帶有屬性的占位文字(字典attributes)
}
- 假如我們找不到相關(guān)屬性棕孙,那這個(gè)時(shí)候我們?cè)撛趺崔k呢舔亭?這樣的話,我們只能重寫(xiě)某些方法了
- 你在頭文件里面搜索placeholder蟀俊,你就會(huì)搜到drawPlaceholderInRect:這個(gè)方法
- 我們重寫(xiě)drawPlaceholderInRect:方法
- 這里有畫(huà)占位文字的兩種方法
#import "CYLoginRegisterTextField.h"
@implementation CYLoginRegisterTextField
- (void)awakeFromNib
{
// 文本框的光標(biāo)顏色
self.tintColor = [UIColor whiteColor];
// 文字顏色
self.textColor = [UIColor whiteColor];
}
- (void)drawPlaceholderInRect:(CGRect)rect
{
// 占位文字畫(huà)在哪個(gè)矩形框里面
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];
// 占位文字畫(huà)在哪個(gè)位置
// 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];
}
- 還有一種方法:利用運(yùn)行時(shí)Runtime查找到有placeholderLabel這個(gè)對(duì)象钦铺,運(yùn)用KVC對(duì)其屬性進(jìn)行賦值(可以根據(jù)自己的經(jīng)驗(yàn)試試)
#import "CYLoginRegisterTextField.h"
#import <objc/runtime.h>
@implementation CYLoginRegisterTextField
- (void)awakeFromNib
{
// 文本框的光標(biāo)顏色
self.tintColor = [UIColor whiteColor];
// 文字顏色
self.textColor = [UIColor whiteColor];
# pragma mark - 設(shè)置占位文字的相關(guān)屬性--方法三-通過(guò)運(yùn)行時(shí)拿到相關(guān)屬性,再利用KVC進(jìn)行賦值
// UILabel *placeholderLabel = [self valueForKeyPath:@"placeholderLabel"];
// placeholderLabel.textColor = [UIColor redColor];
[self setValue:[UIColor grayColor] forKeyPath:@"placeholderLabel.textColor"];
/**
1.什么是運(yùn)行時(shí)(Runtime)?
* 運(yùn)行時(shí)是蘋(píng)果提供的純C語(yǔ)言的開(kāi)發(fā)庫(kù)(是一種非常牛逼肢预、開(kāi)發(fā)中經(jīng)常用到的底層技術(shù))
2.運(yùn)行時(shí)的作用矛洞?
* 能獲得某個(gè)類(lèi)的所有成員變量
* 能獲得某個(gè)類(lèi)的所有屬性
* 能獲得某個(gè)類(lèi)的所有方法
* 交換方法實(shí)現(xiàn)
* 能動(dòng)態(tài)添加一個(gè)成員變量
* 能動(dòng)態(tài)添加一個(gè)屬性
* 能動(dòng)態(tài)添加一個(gè)方法
*/
// 成員變量的數(shù)量
unsigned int outCount = 0;
// 獲得所有的成員變量
Ivar *ivars = class_copyIvarList([UITextField class], &outCount);
// 遍歷所有的成員變量
for (int i = 0; i<outCount; i++) {
// 取出i位置對(duì)應(yīng)的成員變量
Ivar ivar = ivars[i];
// 獲得成員變量的名字
NSLog(@"%s", ivar_getName(ivar));
}
// 如果函數(shù)名中包含了copy\new\retain\create等字眼,那么這個(gè)函數(shù)返回的數(shù)據(jù)就需要手動(dòng)釋放
free(ivars);
}
- 上面將會(huì)打印出UITextFild的所有底層成員變量
- 通過(guò)KVC就可以直接賦值了
- 打印結(jié)果如下:
五
下面補(bǔ)充一下
運(yùn)行時(shí)Runtime以下面簡(jiǎn)單舉例
可以拿到所有的成員變量
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 {
// 成員變量的數(shù)量
unsigned int outCount = 0;
// 獲得所有的成員變量
// ivars是一個(gè)指向成員變量的指針
// ivars默認(rèn)指向第0個(gè)成員變量(最前面)
Ivar *ivars = class_copyIvarList([CYPerson class], &outCount);
NSLog(@"%zd",outCount);
//為什么用傳outCount地址用&outCount指針呢烫映?只有將這個(gè)outCount變量地址值傳進(jìn)去了沼本,那我們的函數(shù)內(nèi)部獲取完你所有的成員變量能算出你的個(gè)數(shù)以后,根據(jù)你傳進(jìn)來(lái)的變量地址值找到你outCount這個(gè)變量外面的存儲(chǔ)空間锭沟,把你的值改一改抽兆,這樣才能改你的值
//
// 遍歷所有的成員變量
for (int i = 0; i<outCount; i++) {
// 取出i位置對(duì)應(yīng)的成員變量
// Ivar ivar = *(ivars + i);
Ivar ivar = ivars[i];
// C語(yǔ)言中如果這個(gè)指針指向首元素地址,就可以把它當(dāng)做數(shù)組來(lái)用族淮。
// 獲得成員變量的名字
NSLog(@"%s", ivar_getName(ivar));
}
// 如果函數(shù)名中包含了copy\new\retain\create等字眼辫红,那么這個(gè)函數(shù)返回的數(shù)據(jù)就需要手動(dòng)釋放。這里不是ARC是C語(yǔ)言
free(ivars);
// Ivar ivar = *ivars;
// *ivars表示取出這個(gè)指針指向的地址中的值
// Ivar ivar2 = *(ivars + 1);
// NSLog(@"%s %s", ivar_getName(ivar), ivar_getName(ivar2));
// 一個(gè)Ivar就代表一個(gè)成員變量Ivar(instance variable實(shí)例變量)
// int *p; 指向int類(lèi)型的變量
// Ivar *ivars; 指向Ivar類(lèi)型的變量
// 最后不管你開(kāi)不開(kāi)源祝辣,我們都能取出所有的成員變量
}
return 0;
}
-
打印結(jié)果
六
- 富文本相關(guān)使用
- 可以用于很多地方贴妻,文字的相關(guān)屬性的改變(創(chuàng)建可變的屬性文字)
富文本用法1 - 不可變的屬性文字
- (void)awakeFromNib
{
// 文本框的光標(biāo)顏色
self.tintColor = CYPlaceholderFocusColor;
// 文字顏色
self.textColor = CYPlaceholderFocusColor;
// 設(shè)置占位文字顏色為白色
NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
attrs[NSForegroundColorAttributeName] = [UIColor whiteColor];
// 設(shè)置占位文字是否有下劃線(0是NO,1是YES)
attrs[NSUnderlineStyleAttributeName] = @1;
// 設(shè)置占位文字的下劃線顏色為紅色
attrs[NSUnderlineColorAttributeName] = [UIColor redColor];
self.attributedPlaceholder = [[NSAttributedString alloc] initWithString:self.placeholder attributes:attrs];
富文本用法2 - 可變的屬性文字
- (void)awakeFromNib
{
// 文本框的光標(biāo)顏色
self.tintColor = CYPlaceholderFocusColor;
// 文字顏色
self.textColor = CYPlaceholderFocusColor;
NSAttributedString和NSMutableAttributedString
// 一個(gè)是創(chuàng)建了就不可以修改屬性了蝙斜,另外一個(gè)還可以修改屬性名惩,所以使用NSMutableAttributedString在它創(chuàng)建的時(shí)候就修改屬性
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:self.placeholder];
[string addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, 1)];
// 在0位置(第一個(gè))文字截取1個(gè)長(zhǎng)度并把它的文字顏色設(shè)置為紅色(手機(jī)號(hào)的“手”,密碼的“密”)
[string addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(1, 1)];
// 在1位置(第二個(gè))文字截取1個(gè)長(zhǎng)度并把它的文字顏色設(shè)置為綠色(手機(jī)號(hào)的“機(jī)”密碼的“碼”)
[string addAttribute:NSFontAttributeName value:[UIFont boldSystemFontOfSize:30] range:NSMakeRange(1, 1)];
// 在1位置(第二個(gè))文字截取1個(gè)長(zhǎng)度并把它的文字字體大小設(shè)置為30(手機(jī)號(hào)的“機(jī)”密碼的“碼”)
self.attributedPlaceholder = string;
富文本用法3 - 圖文混排-常見(jiàn)于聊天的搞怪文字中
- (void)awakeFromNib
{
// 文本框的光標(biāo)顏色
self.tintColor = CYPlaceholderFocusColor;
// 文字顏色
self.textColor = CYPlaceholderFocusColor;
// 將文字孕荠,圖片娩鹉,文字分為三段(后面它們的順序可以調(diào)整)攻谁,先把它們都包裝成三個(gè)屬性文字(NSAttributedString),再調(diào)用(NSMutableAttributedString)的appendAttributedString:方法底循,最后拼接起來(lái)
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] init];
// 第二段:圖片
// attachment附件的意思巢株,可以傳圖片
NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
attachment.image = [UIImage imageNamed:@"login_close_icon"];
// 可以調(diào)整圖片的大小和位置
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;
七
- 點(diǎn)擊文本框進(jìn)行切換的時(shí)候占位文字顏色要發(fā)生改變(我想讓它點(diǎn)擊的時(shí)候顏色為白色,不點(diǎn)擊的時(shí)候顏色為灰色)怎么做呢熙涤?
- 常規(guī)有三種方法阁苞,這里還增加一種
- 監(jiān)聽(tīng)文本框UITextField的改變
- 1.通過(guò)代理(自己做自己的代理,代理的屬性很容易被人覆蓋祠挫,不合理那槽,不推薦使用)
- 2.通過(guò)addTarget:方法(最簡(jiǎn)單)
- 3.通過(guò)通知監(jiān)聽(tīng)(最后還得移除,麻煩)
- 4.第一響應(yīng)者(額外方法等舔,這里推薦)
- 監(jiān)聽(tīng)文本框UITextField的改變
- 1.代理
@interface CYLoginRegisterTextField() <UITextFieldDelegate>
@end
@implementation CYLoginRegisterTextField
- (void)awakeFromNib
{
// 文本框的光標(biāo)顏色
self.tintColor = [UIColor whiteColor];
// 文字顏色
self.textColor = [UIColor whiteColor];
// 設(shè)置占位文字的顏色
[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:方法骚灸。
- 因?yàn)閁ITextField繼承于UIControl
- UIControl給了UITextField四個(gè)方法
UIControlEventEditingDidBegin = 1 << 16, // UITextField
UIControlEventEditingChanged = 1 << 17,
UIControlEventEditingDidEnd = 1 << 18,
UIControlEventEditingDidEndOnExit = 1 << 19, // 'return key' ending
@implementation CYLoginRegisterTextField
- (void)awakeFromNib
{
// 文本框的光標(biāo)顏色
self.tintColor = [UIColor whiteColor];
// 文字顏色
self.textColor = [UIColor whiteColor];
// 設(shè)置占位文字的顏色
[self setValue:[UIColor grayColor] forKeyPath:@"placeholderLabel.textColor"];
// 監(jiān)聽(tīng)文本框的開(kāi)始和結(jié)束
[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.通過(guò)通知監(jiān)聽(tīng)文本框的開(kāi)始與結(jié)束編輯
- 注意:里面的object為什么傳self
- 因?yàn)閭鱪il是監(jiān)聽(tīng)所有文本框的編輯
- 這里只需要監(jiān)聽(tīng)自己文本框的編輯就OK了
- 還有最后得移除dealloc
@implementation CYLoginRegisterTextField
- (void)awakeFromNib
{
// 文本框的光標(biāo)顏色
self.tintColor = [UIColor whiteColor];
// 文字顏色
self.textColor = [UIColor whiteColor];
// 設(shè)置占位文字的顏色
[self setValue:[UIColor grayColor] forKeyPath:@"placeholderLabel.textColor"];
// 通過(guò)通知--監(jiān)聽(tīng)文本框的開(kāi)始和結(jié)束編輯
[[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.第一響應(yīng)者
@implementation CYLoginRegisterTextField
- (void)awakeFromNib
{
// 文本框的光標(biāo)顏色
self.tintColor = [UIColor whiteColor];
// 文字顏色
self.textColor = [UIColor whiteColor];
// 設(shè)置占位文字的顏色
[self setValue:[UIColor grayColor] forKeyPath:@"placeholderLabel.textColor"];
[self resignFirstResponder];
}
/**
* 文本框聚焦時(shí)調(diào)用(成為第一響應(yīng)者)(彈出當(dāng)前文本框?qū)?yīng)的鍵盤(pán)時(shí)調(diào)用)
*/
- (BOOL)becomeFirstResponder
{
[self setValue:[UIColor whiteColor] forKeyPath:@"placeholderLabel.textColor"];
return [super becomeFirstResponder];
}
/**
* 文本框失去焦點(diǎn)時(shí)調(diào)用(成為第一響應(yīng)者)(彈出當(dāng)前文本框?qū)?yīng)的鍵盤(pán)時(shí)調(diào)用)
*/
- (BOOL)resignFirstResponder
{
[self setValue:[UIColor grayColor] forKeyPath:@"placeholderLabel.textColor"];
return [super resignFirstResponder];
}
- 最后進(jìn)行一下代碼的抽取,抽出一個(gè)宏出來(lái)
- 今后要想定義聚焦(點(diǎn)擊)和不點(diǎn)擊(默認(rèn))時(shí)的占位文字光標(biāo)和文字顏色慌植,就只需要修改兩個(gè)顏色了
- 最后這種方法是一個(gè)非主流的方法甚牲,但是很實(shí)用
@implementation CYLoginRegisterTextField
// 占位文字顏色
#define CYPlaceholderColorKey @"placeholderLabel.textColor"
// 默認(rèn)的占位文字顏色
#define CYPlaceholderDefaultColor [UIColor grayColor]
// 聚焦的占位文字顏色
#define CYPlaceholderFocusColor [UIColor whiteColor]
- (void)awakeFromNib
{
// 文本框的光標(biāo)顏色
self.tintColor = CYPlaceholderFocusColor;
// 文字顏色
self.textColor = CYPlaceholderFocusColor;
// 設(shè)置占位文字的顏色
[self setValue:CYPlaceholderDefaultColor forKeyPath:CYPlaceholderColorKey];
[self resignFirstResponder];
}
/**
* 文本框聚焦時(shí)調(diào)用(成為第一響應(yīng)者)(彈出當(dāng)前文本框?qū)?yīng)的鍵盤(pán)時(shí)調(diào)用)
*/
- (BOOL)becomeFirstResponder
{
[self setValue:CYPlaceholderFocusColor forKeyPath:CYPlaceholderColorKey];
return [super becomeFirstResponder];
}
/**
* 文本框失去焦點(diǎn)時(shí)調(diào)用(成為第一響應(yīng)者)(彈出當(dāng)前文本框?qū)?yīng)的鍵盤(pán)時(shí)調(diào)用)
*/
- (BOOL)resignFirstResponder
{
[self setValue:CYPlaceholderDefaultColor forKeyPath:CYPlaceholderColorKey];
return [super resignFirstResponder];
}
八
-
有關(guān)于登錄與注冊(cè)界面的切換
- 仔細(xì)觀察就可以看出登錄與注冊(cè)界面只有“登錄”與“注冊(cè)”按鈕文字還有“注冊(cè)賬號(hào)”與“已有賬號(hào)”按鈕文字不同外,其余都是一樣蝶柿。
- 所以就可以知道登錄與注冊(cè)只是一個(gè)view寬度的動(dòng)畫(huà)效果
-
那我們?nèi)绾卧O(shè)置相關(guān)約束呢丈钙?
- 1.拷貝一份,刪除忘記密碼
- 2.設(shè)置好占位文字
- 3.設(shè)置寬度一致交汤,頂部與左邊對(duì)齊
- 4.在Horizontal Space Constraint中設(shè)置“注冊(cè)界面.Leading”(左邊)與“登陸界面.Trailing”(右邊)相等(Equal)
- 這個(gè)時(shí)候雏赦,注冊(cè)界面就跑到登錄界面右邊去了(但是你看不到)他隨時(shí)待命了
- 接下來(lái)就只要把它拽過(guò)來(lái)就可以了,所以我們要開(kāi)始監(jiān)聽(tīng)按鈕點(diǎn)擊
- 1.將“注冊(cè)賬號(hào)”拖線到CYloginRegisterViewController.m文件中芙扎。將按鈕傳給它星岗,監(jiān)聽(tīng)按鈕點(diǎn)擊(logingOrRegister)
- 2.找到“登錄界面”與父控件的左約束。因?yàn)槲覀円尅白?cè)界面 ”過(guò)來(lái)戒洼,就得要讓它的左約束為一個(gè)負(fù)的view的寬度
- 3.同樣拖線到CYloginRegisterViewController.m里面俏橘,設(shè)置“l(fā)eftSpace”屬性
- 4.由于前面把“登錄界面”的約束,左右兩邊都已經(jīng)定死施逾。所以當(dāng)我們?cè)O(shè)置負(fù)一個(gè)view的寬度的時(shí)候敷矫,會(huì)不起作用,只會(huì)拉伸view
- 所以我們要找到那個(gè)右邊的約束汉额,將其刪除
- 然后設(shè)置“登錄界面”與背景或者是控制器的view的寬度一致
- 或者把右邊的約束也改為負(fù)值
- 有一個(gè)小細(xì)節(jié)
- 你會(huì)發(fā)現(xiàn)“注冊(cè)賬號(hào)”與“已有賬號(hào)?”切換的時(shí)候會(huì)有省略號(hào)
- 所以你要將狀態(tài)改為Custom榨汤,button尺寸設(shè)置大一些蠕搜,文字大小調(diào)整一下,文字居右對(duì)齊收壕。這是一個(gè)小技巧
- 可以讓文字更好看妓灌,而且用戶點(diǎn)擊按鈕范圍也大些
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *leadingSpace;
- (IBAction)loginOrRegister:(UIButton *)button
{
// 修改約束
if (self.leadingSpace.constant == 0) {
self.leadingSpace.constant = - self.view.width;
[button setTitle:@"已有賬號(hào)轨蛤?" forState:UIControlStateNormal];
}else
{
self.leadingSpace.constant = 0;
[button setTitle:@"注冊(cè)賬號(hào)" forState:UIControlStateNormal];
}
[UIView animateWithDuration:0.25 animations:^{
[self.view layoutIfNeeded];
}];
}
- 還有一種方法,不用代碼去設(shè)置按鈕的文字虫埂。而在Xib中用狀態(tài)“Default”--"注冊(cè)賬號(hào)"與“Selected”--“已有賬號(hào)祥山?”去設(shè)置它的文字
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *leadingSpace;
- (IBAction)loginOrRegister:(UIButton *)button
{
// 修改約束
if (self.leadingSpace.constant == 0) {
self.leadingSpace.constant = - self.view.width;
// [button setTitle:@"已有賬號(hào)?" forState:UIControlStateNormal];
button.selected = YES;
}else
{
self.leadingSpace.constant = 0;
// [button setTitle:@"注冊(cè)賬號(hào)" forState:UIControlStateNormal];
button.selected = NO;
}
[UIView animateWithDuration:0.25 animations:^{
[self.view layoutIfNeeded];
}];
}
- 一個(gè)登錄注冊(cè)界面搞定了掉伏,所有的細(xì)節(jié)都在里面
項(xiàng)目地址:https://github.com/Tuberose621/LoginAndRegister--
- 如果可以的話缝呕,Give me a star!