背景:項目中出現了 文本框設定為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)
? ? ? ? }
? ? }
}