BookTextView

效果

说明

1. 支持富文本

2. 支持自定义view

3. 支持阅读百分比

源码

https://github.com/YouXianMing/UI-Component-Collection

//
// BookTextView.h
// InTheQuietNight
//
// Created by YouXianMing on 15/5/18.
// Copyright (c) 2015年 XianMingYou. All rights reserved.
// #import <UIKit/UIKit.h>
#import "ExclusionView.h"
#import "ConfigAttributedString.h" @interface BookTextView : UIView // 要显示的文本
@property (nonatomic, strong) NSString *textString; // 段落样式的设置
@property (nonatomic, strong) NSDictionary *paragraphAttributes; // 富文本参数数组(ConfigAttributedString对象的数组)
@property (nonatomic, strong) NSArray *attributes; // 计算出的文本的高度
@property (nonatomic, readonly) CGFloat textHeight; // 当前文本已读百分比
@property (nonatomic, readonly) CGFloat currentPercent; // 存储的图文混排的views
@property (nonatomic, strong) NSArray *exclusionViews; /**
* 构建出组件(设置完所有参数后再做)
*/
- (void)buildWidgetView; /**
* 移动到指定的位置(此方法只有延时执行才有效果,比如延时执行0.01s)
*
* @param position 文本的高度位置
*/
- (void)moveToTextPosition:(CGFloat)position; /**
* 移动到指定的百分比(此方法只有延时执行才有效果,比如延时执行0.01s)
*
* @param percent 百分比
*/
- (void)moveToTextPercent:(CGFloat)percent; @end
//
// BookTextView.m
// InTheQuietNight
//
// Created by YouXianMing on 15/5/18.
// Copyright (c) 2015年 XianMingYou. All rights reserved.
// #import "BookTextView.h" typedef enum : NSUInteger {
EBOOK_NONE, // 什么也不做
EBOOK_CALCULATE_HEIGHT, // 计算文本高度
} EBookTextViewStatus; @interface BookTextView ()<UITextViewDelegate> {
EBookTextViewStatus _bookStatus; CGFloat _tmpOffsetY;
CGFloat _tmpPercent;
} @property (nonatomic, strong) UITextView *textView;
@property (nonatomic) CGFloat textHeight;
@property (nonatomic) CGFloat currentPercent; @end @implementation BookTextView - (void)buildWidgetView { // 获取长宽
CGFloat width = self.frame.size.width;
CGFloat height = self.frame.size.height; // 创建文本容器并设置段落样式
NSTextStorage *storage = [[NSTextStorage alloc] initWithString:self.textString
attributes:self.paragraphAttributes]; // 设置富文本
for (int count = ; count < _attributes.count; count++) {
ConfigAttributedString *oneConfig = _attributes[count];
[storage addAttribute:oneConfig.attribute
value:oneConfig.value
range:oneConfig.range];
} // 管理器
NSLayoutManager *layoutManager = [NSLayoutManager new];
[storage addLayoutManager:layoutManager]; // 显示的容器
NSTextContainer *textContainer = [NSTextContainer new];
CGSize size = CGSizeMake(width, MAXFLOAT);
textContainer.size = size;
[layoutManager addTextContainer:textContainer]; // 给TextView添加带有内容和布局的容器
self.textView = [[UITextView alloc] initWithFrame:CGRectMake(, , width, height)
textContainer:textContainer];
self.textView.scrollEnabled = YES;
self.textView.editable = NO;
self.textView.selectable = NO;
self.textView.layer.masksToBounds = YES;
self.textView.showsVerticalScrollIndicator = NO;
self.textView.delegate = self; // 如果有额外的views
if (self.exclusionViews) { NSMutableArray *pathArray = [NSMutableArray arrayWithCapacity:_exclusionViews.count]; // 添加view + 添加path
for (int count = ; count < _exclusionViews.count; count++) { // 添加view
ExclusionView *tmpView = _exclusionViews[count];
[_textView addSubview:tmpView]; // 添加path
[pathArray addObject:tmpView.createUIBezierPath];
} textContainer.exclusionPaths = pathArray;
} // 添加要显示的view
[self addSubview:self.textView]; // 存储文本高度
[self storeBookHeight];
} - (void)storeBookHeight { // 先偏移到文本末尾位置
_bookStatus = EBOOK_CALCULATE_HEIGHT;
[UIView setAnimationsEnabled:NO];
[self.textView scrollRangeToVisible:NSMakeRange([self.textView.text length], )];
[UIView setAnimationsEnabled:YES];
_bookStatus = EBOOK_NONE; // 再偏移到文本开头位置
[UIView setAnimationsEnabled:NO];
[self.textView scrollRangeToVisible:NSMakeRange(, )];
[UIView setAnimationsEnabled:YES];
} - (void)moveToTextPosition:(CGFloat)position {
[self.textView setContentOffset:CGPointMake(, position) animated:NO];
} - (void)moveToTextPercent:(CGFloat)percent { // 计算出百分比
CGFloat position = .f;
if (percent >= && percent <= ) {
position = percent * _textHeight;
} else if (percent < ) {
position = .f;
} else {
position = _textHeight;
} // 移动到指定的位置
[self.textView setContentOffset:CGPointMake(, position) animated:NO];
} - (void)scrollViewDidScroll:(UIScrollView *)scrollView { // Y轴偏移量
_tmpOffsetY = scrollView.contentOffset.y;
if (_bookStatus == EBOOK_NONE) { _tmpPercent = _tmpOffsetY / _textHeight;
if (_tmpPercent >= && _tmpPercent <= ) {
_currentPercent = _tmpPercent;
} else if (_tmpPercent < ) {
_currentPercent = .f;
} else {
_currentPercent = .f;
} NSLog(@"%f", _currentPercent); } else if (_bookStatus == EBOOK_CALCULATE_HEIGHT) {
self.textHeight = scrollView.contentOffset.y;
}
} @end

最新文章

  1. sqlldr
  2. 免费在线loading生成。
  3. mm/vmalloc.c
  4. 在VS2012中采用C++中调用DLL中的函数 (4)
  5. c#学习汇总-----------------多态
  6. [转]dos命令 cd命令使用说明[图文说明]
  7. CSS 入门
  8. YouTube为什么打不开?以及简便的訪问的方法/解决方式!
  9. [Lyft Level 5 Challenge 2018 - Elimination Round][Codeforces 1033D. Divisors]
  10. codeforces703B
  11. 6、js初识
  12. [UFLDL] Dimensionality Reduction
  13. 【刷题】BZOJ 4945 [Noi2017]游戏
  14. node学习笔记8——发布npm包
  15. nginx中实现把所有http的请求都重定向到https
  16. Asp.net MVC]Asp.net MVC5系列——实现编辑、删除与明细信息视图
  17. Spring在Web容器启动时执行初始化方法
  18. HAProxy负载均衡原理及企业级实例部署haproxy集群
  19. 编程之美 set 5 寻找数组中最大值和最小值
  20. 深入浅出MySQL-DDL语句

热门文章

  1. R语言中常用包(二)
  2. 用css实现在横线中间插入文字
  3. jvm间歇性崩溃分析
  4. [笔记] Python字典
  5. ADB故障时的一些命令
  6. linux下mysql安装报错及修改密码登录等等
  7. 深入了解Java虚拟机(3)类文件结构
  8. ADO五大对象(转载)
  9. SpringBoot(四) Core Features: Logging
  10. yum 安装php7.1