上一个博客写了获取textview高度的方法 这边接下来写一个如何获得textview的内容是否滑到底的方法,一般在让用户阅读协议后签字,用来判断用户是否看完协议内容。
因为Demo写的还是比较详细的,所以直接上代码。
如果textview的内容掉下来了那么加这句代码
self.automaticallyAdjustsScrollViewInsets = false
关于这个方法的意思 之前做过专门的介绍。
xcode 7.3.1 swift 2.2
import UIKit
//因为UITextView 是UIScrollView 的子类 所以scrollView的代理他也可以用
class TextViewIsScrollToBottomDemo: UIViewController,UITextViewDelegate,UIScrollViewDelegate {
/// 显示的textview
private var textView:UITextView!
/// 约束集合
private lazy var layout:QK_ConstraintCollection = QK_ConstraintCollection()
override func viewDidLoad() {
super.viewDidLoad()
//构造界面
buildAllControlsAndConstraints()
}
//****1.封装获取textview的内容高度的方法
/**
获取UITextView 的内容高度
- parameter textView: 目标textView
- parameter textWidth: 目标textview的宽度
- returns: textView的高度
*/
func heightForString(textView:UITextView,textWidth:CGFloat) ->CGFloat
{
//获取想要的view的size 这边是固定宽度为textview的宽度 高度自适应
let getSize:CGSize = textView.sizeThatFits(CGSize.init(width: textWidth, height: CGFloat(MAXFLOAT)))
//获取textView的高度
return getSize.height
}
//****2.获取textView的偏移量 这边用懒加载 因为这个数据要时刻计算所以用懒加载之创建一次 比较省内存 说句体外话 swift 3.0 取消了GCD中的 dispatch_once 这个方法 官方文档说的取代方法 就是用懒加载来解决的
private lazy var textViewOffset:CGFloat = {
let offset:CGFloat = 0
return offset
}()
//2.1 获取内容的高度 这边的一个注意点是 在懒加载里面的方法和属性都得用self来引导 为什么呢 因为懒加载其实是一个简易的闭包 (即oc中的block)在swift 中闭包内都要用self 防止memoryLeak 内存泄露
private lazy var textViewcontentHeight:CGFloat = {
let contentHeight = self.heightForString(self.textView, textWidth:self.textView.bounds.width )
return contentHeight
}()
/// 获取textview的高度 重复使用多的最好用懒加载 注:获取textview自身的范围属性的时候要确保在viewDidAppear之后 因为纯代码约束 生效比较慢
private lazy var textViewHeight:CGFloat = {
let textViewH = self.textView.bounds.height
return textViewH
}()
//MARK:scrollView的代理 textView可以用父类的代理
//滑动完后的操作
func scrollViewDidScroll(scrollView: UIScrollView) {
//****3.滑动后比较偏移量和高度的值 当偏移量y等于 内容高度 - 界面高度 说明滑到底了
textViewOffset = textView.contentOffset.y
//3.1判断下内容的高度是否大于自身界面的高度 这边是个小细节 就是textview的默认文字内容设置使 上下边距 8 左右边距 0 所以这边判断是以文字全部显示为标准的
if textViewcontentHeight > textViewHeight + 8
{
//3.1.1 这边用大于等于号确保方法只执行一次 也可以定义一个常量进行限制 便宜量可能与底部有一个 0.5的 误差
if textViewOffset >= textViewcontentHeight - textViewHeight
{
//3.1.1 这边可以执行你想要的操作了 我这边就提示一下
print("textview 已经滑到底部了")
}
}
else
{
//3.2
//这边文字内容本身就小于textview frame
}
}
}
//MARK:这边是拓展部分 跟主体一样
extension TextViewIsScrollToBottomDemo{
//创建界面
func buildAllControlsAndConstraints()
{
//界面
//背景色
view.backgroundColor = UIColor.whiteColor()
//1.创建textview
textView = UITextView()
textView.layer.borderWidth = 1
textView.layer.borderColor = UIColor.orangeColor().CGColor
textView.bounces = false
textView.delegate = self
textView.text = "test\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\ntest\n"
view.addSubview(textView)
//2.约束
//注:这边的约束子我自己封装的autolayout 大家可以用frame代替 或者直接拉控件
layout.qk_SetSubSquareDistance(textView, reference: view, leftDis: 15, topDis: 79, rightDis: -15, bottomDis: 1.20)
layout.qk_SetWidthAndHeight(textView, Width: 1.20, height: 200)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}