登錄注冊界面的設計過程

  • 在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
  • 由于有設定的背景,所以這些UIView的背景都設置為ClearColor

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

  • 要調整Button里面的子控件,所以我們自定義這個Button
    • 自定義為CYQuickLoginButton,讓三個按鈕都繼承于它
      • 里面有ImageView和UILable
      • 我們調整他們的位置就是調整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];
    // 這里先調用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
  • 最后就OK了



  • 登錄界面的設計
  • 設置手機號與密碼兩個文本框
    • 用于有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.第一響應者(額外方法,這里推薦)
  • 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];
    }];
}
  • 一個登錄注冊界面搞定了,所有的細節都在里面

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

  • 如果可以的話,Give me a star!
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

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