登錄注冊(cè)界面的設(shè)計(jì)過(guò)程

  • 在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
  • 由于有設(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等值

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)者(額外方法等舔,這里推薦)
  • 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!
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市斧散,隨后出現(xiàn)的幾起案子供常,更是在濱河造成了極大的恐慌,老刑警劉巖鸡捐,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件栈暇,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡箍镜,警方通過(guò)查閱死者的電腦和手機(jī)源祈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)色迂,“玉大人香缺,你說(shuō)我怎么就攤上這事〗挪荩” “怎么了赫悄?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)馏慨。 經(jīng)常有香客問(wèn)我埂淮,道長(zhǎng),這世上最難降的妖魔是什么写隶? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任倔撞,我火速辦了婚禮,結(jié)果婚禮上慕趴,老公的妹妹穿的比我還像新娘痪蝇。我一直安慰自己,他們只是感情好冕房,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布躏啰。 她就那樣靜靜地躺著,像睡著了一般耙册。 火紅的嫁衣襯著肌膚如雪给僵。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,763評(píng)論 1 307
  • 那天,我揣著相機(jī)與錄音帝际,去河邊找鬼蔓同。 笑死,一個(gè)胖子當(dāng)著我的面吹牛蹲诀,可吹牛的內(nèi)容都是我干的斑粱。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼脯爪,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼则北!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起披粟,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤咒锻,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后守屉,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體惑艇,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年拇泛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了滨巴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡俺叭,死狀恐怖恭取,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情熄守,我是刑警寧澤蜈垮,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站裕照,受9級(jí)特大地震影響攒发,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜晋南,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一惠猿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧负间,春花似錦偶妖、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至董虱,卻和暖如春腹缩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背空扎。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工藏鹊, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人转锈。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓盘寡,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親撮慨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子竿痰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件砌溺、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,109評(píng)論 4 62
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,189評(píng)論 25 707
  • 耳邊傳來(lái)呼呼的風(fēng)聲影涉,太陽(yáng)很刺眼,查爾緩緩地睜開(kāi)眼睛规伐,入目的是一片亮白蟹倾。 “這是哪里?我在哪兒猖闪?” 他伸手去摸周?chē)?..
    渺小沙閱讀 441評(píng)論 0 2
  • 像風(fēng)走了八千里 不問(wèn)歸期 像云漂泊九萬(wàn)里 不曾歇息像太陽(yáng)升了落去 無(wú)論朝夕像深山夕照深秋雨 情深幾許像日落前灑下余...
    安二汶閱讀 361評(píng)論 0 3
  • 我愛(ài)著 什么也不說(shuō) 我愛(ài)著 只我心里知覺(jué) 我珍惜我的秘密 我也珍惜我的痛苦 我曾宣誓 我愛(ài)著 不懷抱任何希望 但并...
    青金素衣閱讀 218評(píng)論 0 1