背景:项目中出现了 文本框设定为n行,超出n行,则在UILabel后边添加 ...全文 按钮字样。
0.先看一下效果图
1.首先得解决判断文本框是否出现了...,在此,写了一个延展用来判定UILabel是否被截断。
2.在知道了UILabel是否被截断之后,需要添加一个 ...全文字样。在这里,我采用了协议的方式进行处理。
3.使用方法,如下图
以下为源码:
import UIKit
public protocol TruncatedText {
var showInLabel:UILabel? {get}
}
extension TruncatedText {
///设置查看全文的label
public func showTruncatedText(omit: String = "...", text: String = "全文 ", omitColor: UIColor? = UIColor.green, textColor: UIColor? = UIColor.green, backgroundColor: UIColor? = UIColor.red, target: Any?, action: Selector?) {
guard let label =self.showInLabel else { return }
let isTruncated = label.isTruncated
if !isTruncated { return }
let truncatedlabel = UILabel(frame:CGRect(x:0, y:0, width:0, height:0))
let att1 = NSAttributedString(string: omit, attributes: [NSAttributedString.Key.foregroundColor : (omitColor ?? UIColor.blue), NSAttributedString.Key.font : label.font!])
let att2 = NSAttributedString(string: text, attributes: [NSAttributedString.Key.foregroundColor : (textColor ?? UIColor.blue), NSAttributedString.Key.font : label.font!])
let att = NSMutableAttributedString()
att.append(att1)
att.append(att2)
truncatedlabel.attributedText= att
truncatedlabel.font= label.font
truncatedlabel.textAlignment= .left
label.addSubview(truncatedlabel)
truncatedlabel.sizeToFit()
truncatedlabel.bottom= label.height
truncatedlabel.right= label.width
truncatedlabel.backgroundColor= backgroundColor
if let act = action {
label.isUserInteractionEnabled = true
truncatedlabel.isUserInteractionEnabled=true
let tap =UITapGestureRecognizer(target: target, action: act)
truncatedlabel.addGestureRecognizer(tap)
}
}
}
class ViewController: UIViewController, TruncatedText {
var showInLabel:UILabel? {
return self.label
}
private var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.title = "呵呵"
self.view.backgroundColor = UIColor.white
letw =self.view.frame.width-15*2
label=UILabel(frame:CGRect(x:15, y:100, width: w, height:40))
label.text = "测试测试测试测试测试我依稀爱萨芬了多少加蓝飞,测试测试测试测试测试我依稀爱萨芬了多少加蓝飞。我说了哈哈哈哈"
label.textColor = UIColor.black
label.font=UIFont.systemFont(ofSize:14)
label.textAlignment = .left
label.backgroundColor = UIColor.yellow
self.view.addSubview(label)
label.numberOfLines = 2
label.sizeToFit()
label.width= w
letisT =label.isTruncated
if isT {
self.showTruncatedText(omitColor:UIColor.red, textColor:UIColor.blue, backgroundColor:UIColor.white, target:self, action:#selector(self.trunctate(_:)))
}
}
@objc private func trunctate(_send:UILabel) {
print("看全文去")
}
}
extension UILabel {
///判断label文字是否被截断(是否出现了...)
var isTruncated: Bool {
guard let labelText = text else{
return false
}
guard let font =self.font else{
return false
}
let rect =CGSize(width:self.bounds.width, height:CGFloat
.greatestFiniteMagnitude)
let labelTextSize = (labelText as NSString).boundingRect(with: rect, options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: font], context:nil)
let labelTextLines = Int(ceil(CGFloat(labelTextSize.height)/self.font.lineHeight))
var labelShowLines = Int(floor(CGFloat(bounds.size.height) / self.font.lineHeight))
if self.numberOfLines != 0 {
labelShowLines =min(labelShowLines,self.numberOfLines)
}
return labelTextLines > labelShowLines
}
}
最后,附上 UIView的延展
extension UIView {
///获取视图的控制器
public var viewController:UIViewController? {
var next:UIResponder?
next =self.next
repeat{
if (nextas?UIViewController)!=nil {
return (nextas?UIViewController)
}else{
next = next?.next
}
}while next!=nil
return (next as? UIViewController)
}
///高度
public var height: CGFloat {
get{
return self.frame.size.height
}
set{
self.frame=CGRect(x:self.frame.origin.x, y:self.frame.origin.y, width:self.frame.width, height: newValue)
}
}
///宽度
public var width: CGFloat {
get{
return self.frame.size.width
}
set{
self.frame=CGRect(x:self.frame.origin.x, y:self.frame.origin.y, width: newValue, height:self.frame.height)
}
}
///顶部y
public var top: CGFloat {
get{
return self.frame.origin.y
}
set{
self.frame=CGRect(x:self.frame.origin.x, y: newValue, width:self.frame.width, height:self.frame.height)
}
}
///底部y
public var bottom: CGFloat {
get{
return self.frame.origin.y + self.frame.height
}
set{
let y = newValue-self.frame.height
self.frame=CGRect(x:self.frame.origin.x, y: y, width:self.frame.width, height:self.frame.height)
}
}
///左边x
public var left: CGFloat {
get{
return self.frame.origin.x
}
set{
self.frame=CGRect(x: newValue, y:self.frame.origin.y, width:self.frame.width, height:self.frame.height)
}
}
///右边x
public var right: CGFloat {
get{
return self.frame.origin.x + self.frame.width
}
set{
let x = newValue-self.frame.width
self.frame=CGRect(x: x, y:self.frame.origin.y, width:self.frame.width, height:self.frame.height)
}
}
}