美文网首页
iOS开发 - 哈哈给UITextView自定义了个placeh

iOS开发 - 哈哈给UITextView自定义了个placeh

作者: 俺不是大佬儿 | 来源:发表于2019-12-07 11:28 被阅读0次

    UITextView自定义placeholder属性

    自定义了个PTextView先上个效果

    PTextView效果

    PTextView.h文件

    #import <UIKit/UIKit.h>
    
    NS_ASSUME_NONNULL_BEGIN
    //返回实时的viewSize
    typedef void (^PTextViewSizeChangeBlock)(CGSize viewSize);
    
    @interface PTextView : UITextView 
    ///设置显示的最大行数,默认0 没有滑动效果 viewHeight 随内容改变
    ///maxLine > 0  viewHeight 最大为设置的最大行数高度  内容超出后有滑动效果
    @property (assign, nonatomic) NSInteger   maxLine;
    //placeholder font 和 PTextView font 一致 默认[UIFont systemFontOfSize:14.f]
    @property (strong, nonatomic) UIFont      *textFont;
    @property (copy, nonatomic)   NSString    *placeholder;
    @property (strong, nonatomic) UIColor     *placeholderColor;
    ///cornerRadius default value 8.f
    @property (assign, nonatomic) CGFloat     cornerRadius;
    
    @property (copy, nonatomic) PTextViewSizeChangeBlock viewSizeChangeBlock;
    
    @end
    
    NS_ASSUME_NONNULL_END;
    

    PTextView.m文件

    #import "PTextView.h"
    #define kText_LineSpacing 3.f
    @interface PTextView () <UITextViewDelegate>
    {
        CGRect _initFrame;//记录初始frame
        CGSize _selfViewSize;
    }
    
    @property (strong, nonatomic) UILabel *pLabel;
    
    @end
    
    @implementation PTextView
    
    - (void)awakeFromNib{
        [super awakeFromNib];
        [self initTextView];
        [self initPLabelView];
    }
    
    - (instancetype)initWithFrame:(CGRect)frame{
        self = [super initWithFrame:frame];
        if(self){
            _initFrame = self.frame;
            _selfViewSize = self.frame.size;
            [self initTextView];
            [self initPLabelView];
        }
        
        return self;
    }
    
    - (void)initTextView{
        _cornerRadius = 8.f;
        _maxLine = 0.f;
        self.textFont = [UIFont systemFontOfSize:14.f];
        self.delegate = self;
        self.layoutManager.allowsNonContiguousLayout = NO;
        self.scrollsToTop = NO;
        self.scrollEnabled = NO;
        self.textContainer.lineFragmentPadding = 0;
        self.textContainerInset = UIEdgeInsetsMake(10, _cornerRadius, 5, _cornerRadius);
        
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textViewTextDidChange:) name:UITextViewTextDidChangeNotification object:self];
    }
    
    - (void)setTextFont:(UIFont *)textFont{
        if(textFont){
            _textFont = textFont;
            self.font = _textFont;
            self.pLabel.font = _textFont;
            // 字体的行间距
            NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
            paragraphStyle.lineSpacing = kText_LineSpacing;
            NSDictionary *attributes = @{
                                         NSFontAttributeName:_textFont,
                                         NSParagraphStyleAttributeName:paragraphStyle
                                         };
            self.typingAttributes = attributes;
        }
    }
    
    - (void)setCornerRadius:(CGFloat)cornerRadius{
        if(_cornerRadius != cornerRadius){
            _cornerRadius = cornerRadius;
            [self.layer setMasksToBounds:YES];
            [self.layer setCornerRadius:cornerRadius];
            [self initPLabelView];
        }
    }
    
    - (void)initPLabelView{
        if(_viewSizeChangeBlock){
            _viewSizeChangeBlock(_selfViewSize);
        }
        self.textContainerInset = UIEdgeInsetsMake(10, _cornerRadius, 5, _cornerRadius);
        self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, _selfViewSize.width, _selfViewSize.height);
        self.pLabel.frame = CGRectMake(self.textContainerInset.left, 0.f, self.frame.size.width - (self.textContainerInset.left + self.textContainerInset.right), self.frame.size.height - (self.textContainerInset.top + self.textContainerInset.bottom));
        self.pLabel.centerY = self.frame.size.height / 2.f;
        self.pLabel.font = _textFont;
        self.pLabel.numberOfLines = 0;
        self.pLabel.textColor = [UIColor colorWithHexString:@"#BBBBBB"];
        [self addSubview:self.pLabel];
    }
    
    - (UILabel *)pLabel {
        if(!_pLabel){
            _pLabel = [[UILabel alloc] init];
        }
        return _pLabel;
    }
    
    - (void)textViewTextDidChange:(NSNotification *)sender{
        
        UITextView *textView = (UITextView *)sender.object;
        self.pLabel.hidden = textView.text.length;
        CGFloat height = _initFrame.size.height;
        
        if(textView.text.length){
            if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
                height = ceilf([self sizeThatFits:self.frame.size].height);
            }else{
                height = self.contentSize.height;
            }
            
            height = ceil(textView.textContainerInset.top + textView.textContainerInset.bottom + height);
        }
        
        CGFloat lineH = textView.font.lineHeight + kText_LineSpacing;
        CGFloat maxViewH = ceil(textView.textContainerInset.top + textView.textContainerInset.bottom + lineH * self.maxLine);
        CGFloat maxViewW = self.frame.size.width;
        CGSize  viewSize = CGSizeMake(maxViewW, self.maxLine > 0 ? (maxViewH >= height ? height: maxViewH) : height);
        _selfViewSize = viewSize;
        [self initPLabelView];
        if(self.maxLine > 0){
            self.scrollEnabled = (height > maxViewH);
            [self scrollRangeToVisible:NSMakeRange(textView.selectedRange.location, 1)];
        }
        NSLog(@"textView.text:%@",textView.text);
    }
    
    - (void)setPlaceholder:(NSString *)placeholder{
        self.pLabel.text = placeholder;
    }
    
    - (void)setPlaceholderColor:(UIColor *)placeholderColor{
        self.pLabel.textColor = placeholderColor;
    }
    
    //UITextView遵循了UITextInput协议,其中有返回光标frame的方法
    //- (CGRect)caretRectForPosition:(UITextPosition *)position
    //可以使用自定义的TextView,重写返回光标frame的方法避免光标扩大问题
    - (CGRect)caretRectForPosition:(UITextPosition *)position {
        CGRect originalRect = [super caretRectForPosition:position];
        originalRect.size.height = self.font.lineHeight + 2.f;
        originalRect.size.width = 2.f;
        return originalRect;
    }
    
    - (void)dealloc{
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    
    @end
    
    

    直接复制粘贴代码就可以用了,请给点个赞鼓励一哈子👍!

    相关文章

      网友评论

          本文标题:iOS开发 - 哈哈给UITextView自定义了个placeh

          本文链接:https://www.haomeiwen.com/subject/ypxugctx.html