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

2019-12-07  本文已影响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

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

上一篇下一篇

猜你喜欢

热点阅读