小说绘上架版本

This commit is contained in:
xtfei2011
2021-02-07 11:24:08 +08:00
commit ee5c1c8b12
1762 changed files with 115892 additions and 0 deletions
@@ -0,0 +1,41 @@
//
// CXCustomTextView.h
// CXTextView_Example
//
// Created by caixiang on 2019/5/6.
// Copyright © 2019年 616704162@qq.com. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface CXCustomTextView : UITextView
/**
占位文字
*/
@property (nonatomic, copy) NSString *placeholder;
/**
占位文字的颜色
*/
@property (nonatomic, strong) UIColor *placeholderColor;
/**
占位符的文字位置
*/
@property(nonatomic,assign)CGPoint placePoint;
/**
最大字数
*/
@property (nonatomic, assign)NSInteger maxLength;
/**
文字改变的回调(只是赋值的回调,编辑的改变不回调 有KVO监听)
*/
@property(nonatomic,copy)void (^textDidChangeHandlerBlock)(CXCustomTextView *textView);
/**
触发到最大字数的回调
*/
@property(nonatomic,copy)void (^textLengthDidMaxHandlerBlock)(CXCustomTextView *textView);
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,168 @@
//
// CXCustomTextView.m
// CXTextView_Example
//
// Created by caixiang on 2019/5/6.
// Copyright © 2019年 616704162@qq.com. All rights reserved.
//
#import "CXCustomTextView.h"
#import "TFKeyboardManager.h"
@interface CXCustomTextView()
#pragma mark - Data Perproty
@property (nonatomic, assign) BOOL isNameTextFieldEnbable;
@end
@implementation CXCustomTextView
#pragma mark - life Cycle
-(instancetype)initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if (self) {
[self initilize];
}
return self;
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self initilize];
}
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self removeObserver:self forKeyPath:@"text"];
}
- (void)drawRect:(CGRect)rect{
if (self.hasText) return;
// 文字属性
NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
attrs[NSFontAttributeName] = self.font;
attrs[NSForegroundColorAttributeName] = self.placeholderColor?self.placeholderColor:[UIColor grayColor];
// 画文字
CGFloat x = self.placePoint.x;
CGFloat w = rect.size.width - 2 * x;
CGFloat y = self.placePoint.y;
CGFloat h = rect.size.height - 2 * y;
CGRect placeholderRect = CGRectMake(x, y, w, h);
[self.placeholder drawInRect:placeholderRect withAttributes:attrs];
}
#pragma mark - NSNotification
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
//返回删除键
if ([text isEqualToString:@"\n"]) {
//切换下一个
return NO;
}
if ([text isEqualToString:@""]) {
return YES;
}else{
return _isNameTextFieldEnbable;
}
}
#pragma mark - Notification
/**
* 监听文字改变
*/
- (void)textDidChange:(NSNotification *)notification {
self.isNameTextFieldEnbable = YES;
UITextInputMode *mode = (UITextInputMode *)[UITextInputMode activeInputModes][0];
NSString *lang = mode.primaryLanguage;
//汉字
if ([lang isEqualToString:@"zh-Hans"]) {
UITextRange *selectedRange = [self markedTextRange];
UITextPosition *position = [self positionFromPosition:selectedRange.start offset:0];
if (!position) {
if (self.text.length > self.maxLength) {
self.text = [self.text substringToIndex:self.maxLength];
self.isNameTextFieldEnbable = NO;
!self.textLengthDidMaxHandlerBlock?:self.textLengthDidMaxHandlerBlock(self);
}
}
}
//非汉字状态
else{
if (self.text.length > self.maxLength) {
self.text = [self.text substringToIndex:self.maxLength];
self.isNameTextFieldEnbable = NO;
!self.textLengthDidMaxHandlerBlock?:self.textLengthDidMaxHandlerBlock(self);
}
}
// 重绘(重新调用)
[self setNeedsDisplay];
}
#pragma mark - private
-(void)initilize{
if (@available(iOS 11.0, *)) {
self.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChange:) name:UITextViewTextDidChangeNotification object:self];
self.returnKeyType = UIReturnKeySend;
self.placePoint = CGPointMake(5, 0);
[self addObserver:self forKeyPath:@"text" options:NSKeyValueObservingOptionNew context:nil];
UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 40)];
toolBar.barStyle = UIBarStyleDefault;
UIBarButtonItem *flexibleSpaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithTitle:TFLocalizedString(@"完成") style:UIBarButtonItemStyleDone target:self action:@selector(hideKeyboard)];
[toolBar setItems:@[flexibleSpaceItem, doneItem]];
self.inputAccessoryView = toolBar;
}
- (void)hideKeyboard
{
[TFKeyboardManager hideKeyboard];
}
#pragma mark -KVO
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
if (object == self && [keyPath isEqualToString:@"text"]) {
!self.textDidChangeHandlerBlock?:self.textDidChangeHandlerBlock(self);
}
}
#pragma mark - getter & setter
- (void)setPlaceholder:(NSString *)placeholder {
_placeholder = [placeholder copy];
[self setNeedsDisplay];
}
- (void)setPlaceholderColor:(UIColor *)placeholderColor {
_placeholderColor = placeholderColor;
[self setNeedsDisplay];
}
- (void)setText:(NSString *)text {
[super setText:text];
//为了让kvo 监听的textviewb内容变化 能撑起contentSize,默认只是对self.text赋值self.scrollEnabled = NO;
self.scrollEnabled = YES;
//如果输入的文字超出最大行数,清零的时候需要将contentSizeOffset置空,可以让绘制的placeholde位置能正确显示
if (text.length == 0) {
[self setContentOffset:CGPointZero];
}
[self setNeedsDisplay];
}
- (void)setFont:(UIFont *)font {
[super setFont:font];
[self setNeedsDisplay];
}
-(void)setPlacePoint:(CGPoint)placePoint{
_placePoint = placePoint;
[self setNeedsDisplay];
}
@end
@@ -0,0 +1,94 @@
//
// CXTextView.h
// CXTextView_Example
//
// Created by caixiang on 2019/5/6.
// Copyright © 2019年 616704162@qq.com. All rights reserved.
//
#import <UIKit/UIKit.h>
@class CXCustomTextView;
NS_ASSUME_NONNULL_BEGIN
@interface CXTextView : UIView
/**
真实的textView
*/
@property (nonatomic, strong) CXCustomTextView *textView;
/**
竖直方向上下间距 默认为8
*/
@property (nonatomic, assign)CGFloat v_margin;
/**
水平方向上下间距 默认为0
*/
@property(nonatomic,assign)CGFloat h_margin;
/**
初始需要展示的行数 默认为1
*/
@property(nonatomic,assign)NSInteger initiLine;
/**
最大行数 默认为无穷大
*/
@property(nonatomic,assign)NSInteger maxLine;
/**
占位文字
*/
@property(nonatomic,strong)NSString *placeholder;
/**
占位文字的颜色
*/
@property (nonatomic, strong) UIColor *placeholderColor;
/**
最大字数
*/
@property (nonatomic, assign)NSInteger maxLength;
/**
默认为17
*/
@property(nonatomic,strong)UIFont *font;
/**
置占位符的位置,竖直方向设置v_margin即可 CGPointMake(5, 0);//占位文字的起始位置
*/
@property(nonatomic,assign)CGPoint placePoint;
/**
文字
*/
@property (copy, nonatomic) NSString *text;
/**
文字颜色
*/
@property (strong, nonatomic) UIColor *textColor;
/**
高度变化回调
*/
@property(nonatomic,copy)void (^textHeightChangeBlock)(CGFloat height);
/**
开始编辑回调
*/
@property(nonatomic,copy)void (^textViewDidBeginEditingBlock)(UITextView *textView);
/**
结束编辑回调
*/
@property(nonatomic,copy)void (^textViewDidEndEditingBlock)(UITextView *textView);
/**
最大值回调
*/
@property(nonatomic,copy)void (^textLengthDidMaxHandlerBlock)(UITextView *textView);
/**
文字变动改变回调
*/
@property(nonatomic,copy)void (^textDidChangeHandlerBlock)(UITextView *textView);
/**
发送按钮
*/
@property (nonatomic, copy) void(^returnHandlerBlock)(void);
- (void)textViewBecomeFirstResponder;
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,205 @@
//
// CXTextView.m
// CXTextView_Example
//
// Created by caixiang on 2019/5/6.
// Copyright © 2019年 616704162@qq.com. All rights reserved.
//
#import "CXTextView.h"
#import "CXCustomTextView.h"
@interface CXTextView()<UITextViewDelegate>
@end
@implementation CXTextView
@synthesize text = _text;
#pragma mark - life Cycle
- (instancetype)initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder: aDecoder];
if (self) {
[self initilize];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
[self initilize];
}
return self;
}
- (void)layoutSubviews{
[super layoutSubviews];
self.textView.width = self.frame.size.width - 2 *self.h_margin;
}
#pragma mark - UITextViewDelegate
-(void)textViewDidChange:(UITextView *)textView{
!self.textDidChangeHandlerBlock?:self.textDidChangeHandlerBlock(textView);
[self updateTextViewHeight];
!self.textHeightChangeBlock?:self.textHeightChangeBlock(self.height);
[textView scrollRangeToVisible:NSMakeRange(textView.selectedRange.location, 1)];
}
- (void)textViewDidBeginEditing:(UITextView *)textView {
!self.textViewDidBeginEditingBlock?:self.textViewDidBeginEditingBlock(textView);
}
- (void)textViewDidEndEditing:(UITextView *)textView {
!self.textViewDidEndEditingBlock?:self.textViewDidEndEditingBlock(textView);
}
- (BOOL)textView:(YYTextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if ([text isEqualToString:@"\n"]){
NSString *sendMessage = [textView.text stringByReplacingOccurrencesOfString:@" " withString:@""];
if (sendMessage.length > 0) {
if (self.returnHandlerBlock) {
self.returnHandlerBlock();
}
}
return NO;
}
return YES;
}
- (void)updateTextViewHeight {
CGFloat contentSizeH = ceilf(self.textView.contentSize.height);
//内容高度
if (self.textView.text.length == 0) {
contentSizeH = ceilf(self.font.lineHeight * self.initiLine);
}
//最大高度
CGFloat maxHeight = ceilf(self.font.lineHeight * self.maxLine);
//初始高度
CGFloat initiTextViewHeight = ceilf(self.initiLine *self.font.lineHeight);
if (contentSizeH <= maxHeight) {
if (contentSizeH <= initiTextViewHeight) {
self.textView.height = ceilf(initiTextViewHeight);
}else{
self.textView.height = ceilf(contentSizeH);
}
}else{
self.textView.height = ceilf(maxHeight);
}
self.height = self.textView.height + 2 * self.v_margin;
}
#pragma mark - private
//初始化
- (void)initilize{
self.h_margin = 0;
self.v_margin = 8;
self.initiLine = 1;
self.maxLine = CGFLOAT_MAX;
self.maxLength = CGFLOAT_MAX;
self.font = [UIFont systemFontOfSize:16];
[self addSubview:self.textView];
}
- (void)updateTextViewFrame{
self.textView.frame = CGRectMake(self.h_margin, self.v_margin, self.frame.size.width - 2 *self.h_margin, ceilf(self.initiLine *self.font.lineHeight));
self.height = self.v_margin *2 + ceilf(self.initiLine *self.font.lineHeight);
}
- (void)textViewBecomeFirstResponder
{
[self.textView becomeFirstResponder];
}
#pragma mark - getter & setter
- (void)setMaxLine:(NSInteger)maxLine{
_maxLine = maxLine;
}
- (void)setH_margin:(CGFloat)h_margin{
_h_margin = h_margin;
[self updateTextViewFrame];
}
- (void)setV_margin:(CGFloat)v_margin{
_v_margin = v_margin;
[self updateTextViewFrame];
}
- (void)setInitiLine:(NSInteger)initiLine{
_initiLine = initiLine;
[self updateTextViewFrame];
}
- (void)setFont:(UIFont *)font{
_font = font;
self.textView.font = font;
[self updateTextViewFrame];
}
- (void)setPlaceholderColor:(UIColor *)placeholderColor {
_placeholderColor = placeholderColor;
self.textView.placeholderColor = placeholderColor;
}
- (void)setTextColor:(UIColor *)textColor {
_textColor = textColor;
self.textView.textColor = textColor;
}
- (void)setPlaceholder:(NSString *)placeholder{
_placeholder = placeholder;
self.textView.placeholder = placeholder;
}
- (void)setPlacePoint:(CGPoint)placePoint{
_placePoint = placePoint;
self.textView.placePoint = placePoint;
}
-(void)setMaxLength:(NSInteger)maxLength {
_maxLength = maxLength;
self.textView.maxLength = maxLength;
}
- (void)setText:(NSString *)text {
_text = [text copy];
self.textView.text = text;
}
- (NSString *)text {
return self.textView.text;
}
- (CXCustomTextView *)textView{
if (!_textView) {
_textView = [[CXCustomTextView alloc] initWithFrame:CGRectMake(self.h_margin, self.v_margin, self.frame.size.width - 2 *self.h_margin, self.initiLine *self.font.lineHeight)];
_textView.textContainerInset = UIEdgeInsetsZero;
_textView.delegate = self;
_textView.backgroundColor = [UIColor whiteColor];
_textView.textColor = [UIColor blackColor];
_textView.placeholder = TFLocalizedString(@"请输入");
__weak __typeof(self)weakSelf = self;
_textView.textLengthDidMaxHandlerBlock = ^(CXCustomTextView *textView) {
__strong __typeof(weakSelf)sSelf = weakSelf;
!sSelf.textLengthDidMaxHandlerBlock?:sSelf.textLengthDidMaxHandlerBlock(textView);
};
_textView.textDidChangeHandlerBlock = ^(CXCustomTextView *textView) {
__strong __typeof(weakSelf)sSelf = weakSelf;
!sSelf.textDidChangeHandlerBlock?:sSelf.textDidChangeHandlerBlock(textView);
[sSelf updateTextViewHeight];
if (textView.text.length > 0) {
!sSelf.textHeightChangeBlock?:sSelf.textHeightChangeBlock(sSelf.height);
} else {
!sSelf.textHeightChangeBlock?:sSelf.textHeightChangeBlock(self.v_margin *2 + ceilf(self.initiLine *self.font.lineHeight));
}
};
}
return _textView;
}
@end
@@ -0,0 +1,46 @@
//
// CXTextViewHelper.h
// CXTextView
//
// Created by caixiang on 2019/5/7.
// Copyright © 2019年 616704162@qq.com. All rights reserved.
//
#import <UIKit/UIKit.h>
#ifndef CXTextViewHelper_h
#define CXTextViewHelper_h
//#import "UIView+CXPostion.h"
#import "CXTextView.h"
#import "CXCustomTextView.h"
UIKIT_STATIC_INLINE UIEdgeInsets cx_viewSafeArea(UIView *view) {
#ifdef __IPHONE_11_0
if (@available(iOS 11.0, *)) {
return view.safeAreaInsets;
}
#endif
return UIEdgeInsetsZero;
}
UIKIT_STATIC_INLINE UIColor *CXRGBA(NSInteger r,NSInteger g,NSInteger b,CGFloat a) {
return [UIColor colorWithRed:(float)r/255.0f green:(float)g/255.0f blue:(float)b/255.0f alpha:a];
}
UIKIT_STATIC_INLINE UIColor *CXRGB(NSInteger r,NSInteger g,NSInteger b) {
return CXRGBA(r,g,b,1.0f);
}
UIKIT_STATIC_INLINE UIColor *CXUIColorFromRGBA(uint32_t rgbValue, CGFloat a) {
return [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0f
green:((float)((rgbValue & 0xFF00) >> 8))/255.0f
blue:((float)(rgbValue & 0xFF))/255.0f
alpha:a];
}
UIKIT_STATIC_INLINE UIColor *CXUIColorFromRGB(uint32_t rgbValue) {
return CXUIColorFromRGBA(rgbValue,1.0f);
}
#endif /* CXTextViewHelper_h */