iOS開發之自訂輸入框(利用UITextField及UITextView),自訂uitextfield

來源:互聯網
上載者:User

iOS開發之自訂輸入框(利用UITextField及UITextView),自訂uitextfield

最近在做項目的時候經常自訂一些輸入框,今天在這裡分享給大家。

我的思路就是繼承於系統的控制項然後利用drawRect重畫裡面的控制項。

那麼drawRect是怎麼工作的呢?

drawRect的工作原理:
首先蘋果是不推薦我們直接使用drawRect進行工作的,直接調用他也是沒有任何效果的。蘋果要求我們調用UIView類中的setNeedsDisplay方法,則程式會自動調用drawRect方法進行重繪。(調用setNeedsDisplay會自動調用drawRect)。

在UIView中,重寫drawRect: (CGRect) aRect方法,可以自己定義想要畫的圖案.且此方法一般情況下只會畫一次.也就是說這個drawRect方法一般情況下只會被調用一次。
當某些情況下想要手動重畫這個View,只需要掉用[self setNeedsDisplay]方法即可.
drawRect調用是在Controller->loadView, Controller->viewDidLoad 兩方法被調用之後調用的.所以不用擔心在控制器中,這些View的drawRect就開始畫了.這樣可以在控制器中設定一些值給View(如果這些View draw的時候需要用到某些變數值).

 

1.如果在UIView初始化時沒有設定rect大小,將直接導致drawRect不被自動調用。
2.該方法在調用sizeThatFits後被調用,所以可以先調用sizeToFit計算出size。然後系統自動調用drawRect:方法。
3.通過設定contentMode屬性值為UIViewContentModeRedraw。那麼將在每次設定或更改frame的時候自動調用drawRect:。
4.直接調用setNeedsDisplay,或者setNeedsDisplayInRect:觸發drawRect:,但是有個前提條件是rect不能為0.
以上1,2推薦;而3,4不提倡

 

1.首先是可以多行輸入的輸入框(繼承於UITextView,效果如下)

#pragma mark -- 初始化時調用 --- (instancetype)initWithFrame:(CGRect)frame {    if (self = [super initWithFrame:frame]) {        /**         *  初始化的時候為屬性設定預設值         */        self.placeholder      = @"請輸入文字";        self.placeholderColor = [UIColor lightGrayColor];        self.placeholderFont  = [UIFont systemFontOfSize:14];                /**         *  用textVeiw添加通知,當textView發生變化的時候會調用textChanged方法         */        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChanged:) name:UITextViewTextDidChangeNotification object:nil];    }    return self;}#pragma mark -- 重繪(為textVeiw加上placeholder) --- (void)drawRect:(CGRect)rect {    //如果文字消失了就會繪製placeholder    if (self.text.length == 0) {        CGRect placeholderRect = CGRectZero;        placeholderRect.origin.x = 10;        placeholderRect.origin.y = 5;        placeholderRect.size.width = self.frame.size.width-10;        placeholderRect.size.height = self.frame.size.height-5;        [self.placeholder drawInRect:placeholderRect withAttributes:@{                                                            NSFontAttributeName:_placeholderFont,                                                            NSForegroundColorAttributeName:_placeholderColor                                                            }];    }    [super drawRect:rect];}#pragma mark -- 文字改變的時候會調用該方法- (void)textChanged:(NSNotification *)notification {    /**     *  在文字改變的時候就重繪     */    [self setNeedsDisplay];}#pragma mark -- 移除通知- (void)dealloc {    [[NSNotificationCenter defaultCenter] removeObserver:self];}

如果想自訂更多樣式,可以給attribute多加一些屬性就可以了!!!

2.自訂符合要求的輸入框(繼承於UITextField,效果如下)

 

 上面左視圖只有兩個圓角而且離上下左都有1px的間距,並且placeholder是在右邊的。

- (instancetype)initWithFrame:(CGRect)frame {    if (self = [super initWithFrame:frame]) {        /**         *  初始化屬性,設定預設值         */        _placeholderFont = [UIFont systemFontOfSize:16];        _placeholderColor = [UIColor lightGrayColor];                CGFloat height = frame.size.height;        UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 1, height-1, height-2)];        leftView.backgroundColor = [UIColor redColor];                UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Icon"]];        imageView.frame = CGRectMake(0, 0, height-1, height-2);        [leftView addSubview:imageView];                //利用這個方法可以使左視圖只有兩個圓角        UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:leftView.bounds byRoundingCorners:UIRectCornerBottomLeft|UIRectCornerTopLeft cornerRadii:CGSizeMake(5, 5)];        CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];        maskLayer.frame = leftView.bounds;        maskLayer.path = maskPath.CGPath;        leftView.layer.mask = maskLayer;        self.leftView = leftView;        self.leftViewMode = UITextFieldViewModeAlways;                        NSLog(@"%s",__func__);    }    return self;}//這兩個方法我也不知道有什麼用,如果有知道的可以聯絡我告訴我一下/*#pragma mark -- 重設邊界地區- (CGRect)borderRectForBounds:(CGRect)bounds {    CGRect borderRect = [super borderRectForBounds:bounds];        return borderRect;}#pragma mark -- 重設文字地區- (CGRect)textRectForBounds:(CGRect)bounds {    CGRect textRect = [super textRectForBounds:bounds];        return textRect;}*/#pragma mark -- 重設placeholder- (CGRect)placeholderRectForBounds:(CGRect)bounds {    CGRect placeholderRect = [super placeholderRectForBounds:bounds];    /**     *  使placeholder居右     */    CGFloat placeholderWidth = [self.placeholder boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:_placeholderFont} context:nil].size.width;    placeholderRect.origin.x += placeholderRect.size.width-placeholderWidth-5;    return placeholderRect;}#pragma mark -- 重設編輯地區- (CGRect)editingRectForBounds:(CGRect)bounds {    CGRect editingRect = [super editingRectForBounds:bounds];    return editingRect;}#pragma mark -- 重設刪除按鈕地區- (CGRect)clearButtonRectForBounds:(CGRect)bounds {    CGRect clearButtonRect = [super clearButtonRectForBounds:bounds];        return clearButtonRect;}#pragma mark -- 重設左視圖地區- (CGRect)leftViewRectForBounds:(CGRect)bounds {    CGRect leftViewRect = [super leftViewRectForBounds:bounds];    leftViewRect.origin.x += 1;    return leftViewRect;}#pragma mark -- 重設右視圖地區- (CGRect)rightViewRectForBounds:(CGRect)bounds {    CGRect rightViewRect = [super rightViewRectForBounds:bounds];        return rightViewRect;}#pragma mark -- 重繪文字(這個方法他成為第一響應者之後才調用的)- (void)drawTextInRect:(CGRect)rect {    [super drawTextInRect:rect];    self.textColor = [UIColor purpleColor];}#pragma mark -- 重繪placeholder

//在第一次顯示的時候是先調用了placeholderRectForBounds:這個方法,然後再調用該方法

//之後顯示的時候都是在調用了placeholderRectForBounds:方法之後,調用該方法,之後再調用placeholderRectForBounds:方法,這就會使placeholder的位置發生位移(當他成為第一響應者的時候就不會置中對齊了,如果有知道怎麼解決的,請聯絡我一下,謝謝!!!)
- (void)drawPlaceholderInRect:(CGRect)rect {    [super drawPlaceholderInRect:rect];    /**     *  調用kvo修改系統的_placeholderLabel的屬性     */    [self setValue:_placeholderColor forKeyPath:@"_placeholderLabel.textColor"];    [self setValue:_placeholderFont  forKeyPath:@"_placeholderLabel.font"];}

如果有需要這個demo的,可以去我的空間下載,也可以加我qq:357898849,一起交流一下哦!!!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.