登錄注冊界面的設(shè)計過程

  • 在PCH文件中設(shè)置了一個全局顏色
#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開始由控制器來修改狀態(tài)欄樣式
/**
 * 讓狀態(tài)欄樣式為白色
 */
- (UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
}
/**
 * 讓狀態(tài)欄樣式為黑色
 */
- (UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleDefault;
}

  • 一個這樣的登錄注冊界面該如何做呢?它又會涉及到哪些技術(shù)點呢?
    • 下面我給大家總結(jié)一下
  • 從圖中可以看出上面的“登錄”部分和下面的“快速登錄”部分是固定死的

  • 當(dāng)你發(fā)現(xiàn)界面的布局是固定不變的時候就得想到要用Xib進行布局

  • 固定界面用Xib布局

    • 用一個UIView把它們綁在一起
    • UIView作為綁在一起的子控件的父控件(蘋果不推薦使用像UIImageView之類的控件作為父控件,而推薦使用UIView)
    • 也就是說容器一般就是UIView
  • 首先對于下面的布局該怎么做呢?


  • 先是整個一個大的“快速登錄整體”UIView(給定固定寬高,定好約束)里面嵌套兩個UIView(給定固定寬高)

    • 一個是快速登錄上部分,一個是其他快捷登錄部分
    • 將他們細分過來一步步做
    • 主要是設(shè)置好約束
  • 上部分的UIView

    • “快速登錄”的Lable加上兩個ImageView的左右線。
      • 設(shè)置約束,lable是先水平豎直居中,設(shè)置好大概的字體大小
      • lable設(shè)定死的寬高
      • 左線:距離左邊0,上邊0,下邊0,右邊5。
        • 里面的圖片設(shè)置屬性Mode為Right就OK了
      • 右線:距離左邊5,上邊0,下邊0,右邊0。
        • 里面的圖片設(shè)置屬性Mode為Left就OK了
    • 其他快捷登陸部分“QQ登錄”“新浪微博”“騰訊微博”
      • 就是三個Button
      • 先設(shè)置好“QQ登錄”這個按鈕,再復(fù)制兩個
      • 設(shè)置三個寬度一致
      • 再設(shè)置“QQ登錄”距離左邊0,上邊0,下邊0,右邊0
      • 再設(shè)置“新浪微博”距離不需要設(shè)置左邊,上邊0,下邊0,右邊0
      • 再設(shè)置“騰訊微博”距離不需要設(shè)置左邊,上邊0,下邊0,右邊0
  • 由于有設(shè)定的背景,所以這些UIView的背景都設(shè)置為ClearColor

  • 但是我們實際還需要去調(diào)整按鈕中圖片和文字的位置

  • 要調(diào)整Button里面的子控件,所以我們自定義這個Button
    • 自定義為CYQuickLoginButton,讓三個按鈕都繼承于它
      • 里面有ImageView和UILable
      • 我們調(diào)整他們的位置就是調(diào)整x,y,width,heiht等值
      • 為了方便我們這里封裝一個UIView的類別(類擴展)
        • 因為許多控件都是繼承自UIView的,所以對其進行封裝擴展可以更加方便的去改它的x,y,width,heiht等值

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 (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,會先計算好按鈕里面控件的位置和尺寸
    // 然后下面的代碼再進行位置的相關(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è)計
  • 設(shè)置手機號與密碼兩個文本框
    • 用于有UIXiew“登錄界面整體”的父容器
    • 里面嵌套一個“文本輸入框整體”的UIView
    • 文本框“手機號”和“密碼”的文字輸入鍵盤設(shè)置不一樣
  • 設(shè)置登錄按鈕

    • 登錄按鈕與“文本輸入框整體”設(shè)置左右對齊,高為35,距離上面25
    • 按鈕里設(shè)置好圖片就OK了
    • 那么問題來了,怎么設(shè)置登錄按鈕的圓角呢,許多時候都用的著的
  • 代碼設(shè)置

    • 拖線到登錄界面,設(shè)置屬性,然后
#import "CYLoginRegisterViewController.h"

@interface CYLoginRegisterViewController ()
//@property (weak, nonatomic) IBOutlet UIButton *loginButton;

@end

@implementation CYLoginRegisterViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // 代碼實現(xiàn)一:
    self.loginButton.layer.cornerRadius = 5;
    self.loginButton.layer.masksToBounds = YES;
    // 代碼實現(xiàn)二:
    self.loginButton.layer.cornerRadius = 5;
    self.loginButton.clipsToBounds = YES;
    // 代碼實現(xiàn)三:
    [self.loginButton setValue:@5 forKeyPath:@"layer.cornerRadius"];
    [self.loginButton setValue:@YES forKeyPath:@"layer.masksToBounds"];

}
  • 從上面看出KVC賦值很方便,但是也可以不用代碼
  • 而是在Xib中用KVC
    • 記住:凡是KVC能實現(xiàn)的東西,在Xib中都可以設(shè)置

  • 我們想要修改文本框里占位文字的顏色,光標(biāo)等(系統(tǒng)的一般不能滿足)
    • 方法一:拖線兩次,分別設(shè)置。(不推薦)
    • 方法二:自定義文本框(推薦)到時候每個文本框繼承于我自定義的文本框就可以了

自定義文本框TextFiled

  • 當(dāng)我們遇上不會的東西像這里需要設(shè)置的光標(biāo)顏色,文字顏色。不知道該怎么去設(shè)置,就可以多試一下,進入UIColor的頭文件,各種搜查,最后不就是會找到一個叫做TinClolor的屬性,就可以設(shè)置光標(biāo)的顏色了。遇到不會的多試試沒準(zhǔn)就找到方法了
  • 那么又會發(fā)現(xiàn)占位文字的顏色找不到怎么修改
    • 根據(jù)經(jīng)驗一般在placeholder的附近去找,你會發(fā)現(xiàn)有一個attributedPlaceholder
    • 這也就是帶有屬性的占位文字(富文本)
    • 占位文字默認是帶有70%灰色的
    • 而attributedPlaceholder就可以去設(shè)置了,進入頭文件多找找嘛
- (void)awakeFromNib
{
    // 文本框的光標(biāo)顏色
    self.tintColor = [UIColor whiteColor];
    // 文字顏色
    self.textColor = [UIColor whiteColor];
    // 設(shè)置帶有屬性的占位文字(也稱為富文本)
    self.attributedPlaceholder = [[NSAttributedString alloc] initWithString:self.placeholder attributes:@{NSForegroundColorAttributeName : [UIColor grayColor]}];
    //把我們以前普普通通的占位文字傳進去(initWithString)變成一個帶有屬性的占位文字(字典attributes)
}

  • 假如我們找不到相關(guān)屬性,那這個時候我們該怎么辦呢?這樣的話,我們只能重寫某些方法了
  • 你在頭文件里面搜索placeholder,你就會搜到drawPlaceholderInRect:這個方法
  • 我們重寫drawPlaceholderInRect:方法
    • 這里有畫占位文字的兩種方法
#import "CYLoginRegisterTextField.h"

@implementation CYLoginRegisterTextField

- (void)awakeFromNib
{
    // 文本框的光標(biāo)顏色
    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對其屬性進行賦值(可以根據(jù)自己的經(jīng)驗試試)
#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ān)屬性,再利用KVC進行賦值

    //    UILabel *placeholderLabel = [self valueForKeyPath:@"placeholderLabel"];
    //    placeholderLabel.textColor = [UIColor redColor];
    [self setValue:[UIColor grayColor] forKeyPath:@"placeholderLabel.textColor"];

    /**
     1.什么是運行時(Runtime)?
     * 運行時是蘋果提供的純C語言的開發(fā)庫(是一種非常牛逼、開發(fā)中經(jīng)常用到的底層技術(shù))

     2.運行時的作用?
     * 能獲得某個類的所有成員變量
     * 能獲得某個類的所有屬性
     * 能獲得某個類的所有方法
     * 交換方法實現(xiàn)
     * 能動態(tài)添加一個成員變量
     * 能動態(tài)添加一個屬性
     * 能動態(tài)添加一個方法
     */

    // 成員變量的數(shù)量
    unsigned int outCount = 0;

    // 獲得所有的成員變量
    Ivar *ivars = class_copyIvarList([UITextField class], &outCount);

    // 遍歷所有的成員變量
    for (int i = 0; i<outCount; i++) {
        // 取出i位置對應(yīng)的成員變量
        Ivar ivar = ivars[i];
        // 獲得成員變量的名字
        NSLog(@"%s", ivar_getName(ivar));
    }

    // 如果函數(shù)名中包含了copy\new\retain\create等字眼,那么這個函數(shù)返回的數(shù)據(jù)就需要手動釋放
    free(ivars);
}
  • 上面將會打印出UITextFild的所有底層成員變量
    • 通過KVC就可以直接賦值了
    • 打印結(jié)果如下:

  • 下面補充一下
    運行時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 {
        // 成員變量的數(shù)量
        unsigned int outCount = 0;

        // 獲得所有的成員變量
        // ivars是一個指向成員變量的指針
        // ivars默認指向第0個成員變量(最前面)
        Ivar *ivars = class_copyIvarList([CYPerson class], &outCount);
        NSLog(@"%zd",outCount);

        //為什么用傳outCount地址用&outCount指針呢?只有將這個outCount變量地址值傳進去了,那我們的函數(shù)內(nèi)部獲取完你所有的成員變量能算出你的個數(shù)以后,根據(jù)你傳進來的變量地址值找到你outCount這個變量外面的存儲空間,把你的值改一改,這樣才能改你的值
        //
        // 遍歷所有的成員變量
        for (int i = 0; i<outCount; i++) {
            // 取出i位置對應(yīng)的成員變量
            //            Ivar ivar = *(ivars + i);
            Ivar ivar = ivars[i];
            //            C語言中如果這個指針指向首元素地址,就可以把它當(dāng)做數(shù)組來用。
            // 獲得成員變量的名字
            NSLog(@"%s", ivar_getName(ivar));
        }

        // 如果函數(shù)名中包含了copy\new\retain\create等字眼,那么這個函數(shù)返回的數(shù)據(jù)就需要手動釋放。這里不是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;
}

  • 打印結(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
    // 一個是創(chuàng)建了就不可以修改屬性了,另外一個還可以修改屬性,所以使用NSMutableAttributedString在它創(chuàng)建的時候就修改屬性
    NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:self.placeholder];
    [string addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, 1)];
    // 在0位置(第一個)文字截取1個長度并把它的文字顏色設(shè)置為紅色(手機號的“手”,密碼的“密”)
    [string addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(1, 1)];
    // 在1位置(第二個)文字截取1個長度并把它的文字顏色設(shè)置為綠色(手機號的“機”密碼的“碼”)
    [string addAttribute:NSFontAttributeName value:[UIFont boldSystemFontOfSize:30] range:NSMakeRange(1, 1)];
    // 在1位置(第二個)文字截取1個長度并把它的文字字體大小設(shè)置為30(手機號的“機”密碼的“碼”)

    
    self.attributedPlaceholder = string;

富文本用法3 - 圖文混排-常見于聊天的搞怪文字中

- (void)awakeFromNib
{
    // 文本框的光標(biāo)顏色
    self.tintColor = CYPlaceholderFocusColor;
    // 文字顏色
    self.textColor = CYPlaceholderFocusColor;
    // 將文字,圖片,文字分為三段(后面它們的順序可以調(diào)整),先把它們都包裝成三個屬性文字(NSAttributedString),再調(diào)用(NSMutableAttributedString)的appendAttributedString:方法,最后拼接起來
    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;

  • 點擊文本框進行切換的時候占位文字顏色要發(fā)生改變(我想讓它點擊的時候顏色為白色,不點擊的時候顏色為灰色)怎么做呢?
  • 常規(guī)有三種方法,這里還增加一種
    • 監(jiān)聽文本框UITextField的改變
      • 1.通過代理(自己做自己的代理,代理的屬性很容易被人覆蓋,不合理,不推薦使用)
      • 2.通過addTarget:方法(最簡單)
      • 3.通過通知監(jiān)聽(最后還得移除,麻煩)
      • 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:方法。
    • 因為UITextField繼承于UIControl
    • UIControl給了UITextField四個方法
    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)聽文本框的開始和結(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.通過通知監(jiān)聽文本框的開始與結(jié)束編輯
    • 注意:里面的object為什么傳self
    • 因為傳nil是監(jiān)聽所有文本框的編輯
    • 這里只需要監(jiān)聽自己文本框的編輯就OK了
    • 還有最后得移除dealloc
@implementation CYLoginRegisterTextField

- (void)awakeFromNib
{
    // 文本框的光標(biāo)顏色
    self.tintColor = [UIColor whiteColor];
    // 文字顏色
    self.textColor = [UIColor whiteColor];
    // 設(shè)置占位文字的顏色
    [self setValue:[UIColor grayColor] forKeyPath:@"placeholderLabel.textColor"];
    // 通過通知--監(jiān)聽文本框的開始和結(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];
}

/**
 *  文本框聚焦時調(diào)用(成為第一響應(yīng)者)(彈出當(dāng)前文本框?qū)?yīng)的鍵盤時調(diào)用)
 */
- (BOOL)becomeFirstResponder
{
    [self setValue:[UIColor whiteColor] forKeyPath:@"placeholderLabel.textColor"];
    return [super becomeFirstResponder];
}

/**
 *  文本框失去焦點時調(diào)用(成為第一響應(yīng)者)(彈出當(dāng)前文本框?qū)?yīng)的鍵盤時調(diào)用)
 */
- (BOOL)resignFirstResponder
{
    [self setValue:[UIColor grayColor] forKeyPath:@"placeholderLabel.textColor"];
    return [super resignFirstResponder];
}
  • 最后進行一下代碼的抽取,抽出一個宏出來
  • 今后要想定義聚焦(點擊)和不點擊(默認)時的占位文字光標(biāo)和文字顏色,就只需要修改兩個顏色了
  • 最后這種方法是一個非主流的方法,但是很實用
@implementation CYLoginRegisterTextField

// 占位文字顏色
#define CYPlaceholderColorKey @"placeholderLabel.textColor"
// 默認的占位文字顏色
#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];
}

/**
 *  文本框聚焦時調(diào)用(成為第一響應(yīng)者)(彈出當(dāng)前文本框?qū)?yīng)的鍵盤時調(diào)用)
 */
- (BOOL)becomeFirstResponder
{
    [self setValue:CYPlaceholderFocusColor forKeyPath:CYPlaceholderColorKey];
    return [super becomeFirstResponder];
}

/**
 *  文本框失去焦點時調(diào)用(成為第一響應(yīng)者)(彈出當(dāng)前文本框?qū)?yīng)的鍵盤時調(diào)用)
 */
- (BOOL)resignFirstResponder
{
    [self setValue:CYPlaceholderDefaultColor forKeyPath:CYPlaceholderColorKey];
    return [super resignFirstResponder];
}

  • 有關(guān)于登錄與注冊界面的切換

    • 仔細觀察就可以看出登錄與注冊界面只有“登錄”與“注冊”按鈕文字還有“注冊賬號”與“已有賬號”按鈕文字不同外,其余都是一樣。
    • 所以就可以知道登錄與注冊只是一個view寬度的動畫效果
  • 那我們?nèi)绾卧O(shè)置相關(guān)約束呢?

    • 1.拷貝一份,刪除忘記密碼
    • 2.設(shè)置好占位文字
    • 3.設(shè)置寬度一致,頂部與左邊對齊
    • 4.在Horizontal Space Constraint中設(shè)置“注冊界面.Leading”(左邊)與“登陸界面.Trailing”(右邊)相等(Equal)
      • 這個時候,注冊界面就跑到登錄界面右邊去了(但是你看不到)他隨時待命了
  • 接下來就只要把它拽過來就可以了,所以我們要開始監(jiān)聽按鈕點擊
    • 1.將“注冊賬號”拖線到CYloginRegisterViewController.m文件中。將按鈕傳給它,監(jiān)聽按鈕點擊(logingOrRegister)
    • 2.找到“登錄界面”與父控件的左約束。因為我們要讓“注冊界面 ”過來,就得要讓它的左約束為一個負的view的寬度
    • 3.同樣拖線到CYloginRegisterViewController.m里面,設(shè)置“l(fā)eftSpace”屬性
    • 4.由于前面把“登錄界面”的約束,左右兩邊都已經(jīng)定死。所以當(dāng)我們設(shè)置負一個view的寬度的時候,會不起作用,只會拉伸view
      • 所以我們要找到那個右邊的約束,將其刪除
      • 然后設(shè)置“登錄界面”與背景或者是控制器的view的寬度一致
      • 或者把右邊的約束也改為負值
  • 有一個小細節(jié)
    • 你會發(fā)現(xiàn)“注冊賬號”與“已有賬號?”切換的時候會有省略號
    • 所以你要將狀態(tài)改為Custom,button尺寸設(shè)置大一些,文字大小調(diào)整一下,文字居右對齊。這是一個小技巧
    • 可以讓文字更好看,而且用戶點擊按鈕范圍也大些
@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];
    }];
}
  • 還有一種方法,不用代碼去設(shè)置按鈕的文字。而在Xib中用狀態(tài)“Default”--"注冊賬號"與“Selected”--“已有賬號?”去設(shè)置它的文字
@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];
    }];
}
  • 一個登錄注冊界面搞定了,所有的細節(jié)都在里面

項目地址:https://github.com/Tuberose621/LoginAndRegister--

  • 如果可以的話,Give me a star!
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,156評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,401評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,069評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,873評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,635評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,128評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,203評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,365評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,881評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,733評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,935評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,475評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,172評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,582評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,821評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,595評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,908評論 2 372

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

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