zoukankan      html  css  js  c++  java
  • iOS开发之自定义输入框(利用UITextField及UITextView)

    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
    - (void)drawPlaceholderInRect:(CGRect)rect {
        [super drawPlaceholderInRect:rect];
        /**
         *  调用kvo修改系统的_placeholderLabel的属性
         */
        [self setValue:_placeholderColor forKeyPath:@"_placeholderLabel.textColor"];
        [self setValue:_placeholderFont  forKeyPath:@"_placeholderLabel.font"];
    }
  • 相关阅读:
    try catch finally语句块中存在return语句时的运行流程
    【Java学习】异常
    【Java学习】面向对象(二)——封装、继承、多态、抽象
    【ASP.NET开发Web项目】vs2019新建ASP.NET空网站,没有出现Default.aspx
    【ASP.NET开发Web项目】VS2019项目模板中没有ASP.NET空网站
    【Java学习】面向对象(一)
    【Java学习】数组的初始化、特点及基础操作(冒泡排序)
    Jmeter接口测试和压力测试的配置和使用
    【Java学习】递归算法之斐波那契数列、100以内的阶乘
    【Java学习】进制转换、二进制原码反码补码和位运算
  • 原文地址:https://www.cnblogs.com/starainDou/p/5152401.html
Copyright © 2011-2022 走看看