Swift 3 cell展開/閉合動(dòng)畫小示例

先看示例圖

demo.gif

提前聲明:這個(gè)demo是仿照之前某個(gè)人用Objective-C寫的示例,點(diǎn)擊圓圈手指效果是用的一個(gè)第三方,可在demo中查看

核心技巧:

  • 灰色文字點(diǎn)擊變成黑色,并且cell文字展開: cell上添加兩個(gè)一模一樣的label,一個(gè)顯示灰色,一個(gè)顯示黑色,點(diǎn)擊刷新tableView,用UIView動(dòng)畫,使一個(gè)label的alpha為1,一個(gè)label的alpha為0

由于沒有復(fù)雜邏輯,直接貼代碼了

1.控制器

import UIKit
class ViewController: UIViewController {
    
    var modelArray : [DXCellModel] = []
    lazy var tableView: UITableView = {
       let table = UITableView.init(frame: CGRect.init(x: 0, y: 20, width: kScreenW, height: kScreenH-20), style: .plain)
        table.sectionHeaderHeight = 0
        table.sectionFooterHeight = 0
        table.dataSource = self
        table.delegate = self
        table.separatorStyle = .none
        return table
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let strings = ["AFNetworking is a delightful networking library for iOS and Mac OS X. It's built on top of the Foundation URL Loading System, extending the powerful high-level networking abstractions built into Cocoa. It has a modular architecture with well-designed, feature-rich APIs that are a joy to use. Perhaps the most important feature of all, however, is the amazing community of developers who use and contribute to AFNetworking every day. AFNetworking powers some of the most popular and critically-acclaimed apps on the iPhone, iPad, and Mac. Choose AFNetworking for your next project, or migrate over your existing projects—you'll be happy you did!",
        
        "歡迎使用 iPhone SE,迄今最高性能的 4 英寸 iPhone。在打造這款手機(jī)時(shí),我們?cè)谏畹萌诵牡?4 英寸設(shè)計(jì)基礎(chǔ)上,從里到外重新構(gòu)想。它所采用的 A9 芯片,正是在 iPhone 6s 上使用的先進(jìn)芯片。1200 萬像素的攝像頭能拍出令人嘆為觀止的精彩照片和 4K 視頻,而 Live Photos 則會(huì)讓你的照片栩栩如生。這一切,成就了一款外形小巧卻異常強(qiáng)大的 iPhone。",
        
        "★タクシー代がなかったので、家まで歩いて帰った?!铯猡肥鹿胜k生した場(chǎng)所、このレバーを引いて列車を止めてください。(丁)為了清楚地表示出一個(gè)短語或句節(jié),其后須標(biāo)逗號(hào)。如:★この薬を、夜寢る前に一度、朝起きてからもう一度、飲んでください?!锼饯稀⒖栅蝻wぶ鳥のように、自由に生きて行きたいと思った。*****為了清楚地表示詞語與詞語間的關(guān)系,須標(biāo)逗號(hào)。標(biāo)注位置不同,有時(shí)會(huì)使句子的意思發(fā)生變化。如:★その人は大きな音にびっくりして、橫から飛び出した子供にぶつかった?!铯饯稳摔?、大きな音にびっくりして橫から飛び出した子供に、ぶつかった。",
        
        "Two roads diverged in a yellow wood, And sorry I could not travel both And be one traveler, long I stood And looked down one as far as I could To where it bent in the undergrowth; Then took the other, as just as fair, And having perhaps the better claim, Because it was grassy and wanted wear; Though as for that the passing there Had worn them really about the same, And both that morning equally lay In leaves no step had trodden black. Oh, I kept the first for another day! Yet knowing how way leads on to way, I doubted if I should ever come back. I shall be telling this with a sigh Somewhere ages and ages hence: Two roads diverged in a wood, and I- I took the one less traveled by, And that has made all the difference. ",
        
        "Star \"https://github.com/boai\" :)",
        "AFNetworking is a delightful networking library for iOS and Mac OS X. It's built on top of the Foundation URL Loading System, extending the powerful high-level networking abstractions built into Cocoa. It has a modular architecture with well-designed, feature-rich APIs that are a joy to use. Perhaps the most important feature of all, however, is the amazing community of developers who use and contribute to AFNetworking every day. AFNetworking powers some of the most popular and critically-acclaimed apps on the iPhone, iPad, and Mac. Choose AFNetworking for your next project, or migrate over your existing projects—you'll be happy you did!",
        
        "歡迎使用 iPhone SE,迄今最高性能的 4 英寸 iPhone。在打造這款手機(jī)時(shí),我們?cè)谏畹萌诵牡?4 英寸設(shè)計(jì)基礎(chǔ)上,從里到外重新構(gòu)想。它所采用的 A9 芯片,正是在 iPhone 6s 上使用的先進(jìn)芯片。1200 萬像素的攝像頭能拍出令人嘆為觀止的精彩照片和 4K 視頻,而 Live Photos 則會(huì)讓你的照片栩栩如生。這一切,成就了一款外形小巧卻異常強(qiáng)大的 iPhone。",
        
        "★タクシー代がなかったので、家まで歩いて帰った。★もし事故が発生した場(chǎng)所、このレバーを引いて列車を止めてください。(?。榱饲宄乇硎境鲆粋€(gè)短語或句節(jié),其后須標(biāo)逗號(hào)。如:★この薬を、夜寢る前に一度、朝起きてからもう一度、飲んでください。★私は、空を飛ぶ鳥のように、自由に生きて行きたいと思った。*****為了清楚地表示詞語與詞語間的關(guān)系,須標(biāo)逗號(hào)。標(biāo)注位置不同,有時(shí)會(huì)使句子的意思發(fā)生變化。如:★その人は大きな音にびっくりして、橫から飛び出した子供にぶつかった?!铯饯稳摔?、大きな音にびっくりして橫から飛び出した子供に、ぶつかった。",
        
        "Two roads diverged in a yellow wood, And sorry I could not travel both And be one traveler, long I stood And looked down one as far as I could To where it bent in the undergrowth; Then took the other, as just as fair, And having perhaps the better claim, Because it was grassy and wanted wear; Though as for that the passing there Had worn them really about the same, And both that morning equally lay In leaves no step had trodden black. Oh, I kept the first for another day! Yet knowing how way leads on to way, I doubted if I should ever come back. I shall be telling this with a sigh Somewhere ages and ages hence: Two roads diverged in a wood, and I- I took the one less traveled by, And that has made all the difference. ",
        
        "Star \"https://github.com/boai\" :)"];
        
        for i in 0..<strings.count {
            let model = DXCellModel(contentStr : strings[i])
            modelArray.append(model)
        }
        view.addSubview(self.tableView)
    }
    
}

extension ViewController : UITableViewDataSource,UITableViewDelegate {
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.modelArray.count
    }
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return self.modelArray[indexPath.row].cellHeigh
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = DXTableCell.cellWithTableView(tableView: tableView)
        cell.model = modelArray[indexPath.row] 
        return cell
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let cell = tableView.cellForRow(at: indexPath) as! DXTableCell
        cell.clickCell()
    }
}

2.自定義cell

import UIKit
enum DXShowCellTextType {
    case normal
    case expand
}

class DXTableCell: UITableViewCell {
    
    var normalLabel: UILabel!
    var expandLabel: UILabel!
    var superTableView: UITableView!
    var cellType : DXShowCellTextType
    
    static let identify = "cell"
    
    class func cellWithTableView(tableView : UITableView) -> DXTableCell {
        
        var cell = tableView.dequeueReusableCell(withIdentifier: identify) as? DXTableCell
        if cell == nil {
            cell = DXTableCell.init(style: .default, reuseIdentifier: identify)
            cell?.superTableView = tableView
        }
        return cell!
    }
    
    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        self.cellType = .normal
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        self.selectionStyle = UITableViewCellSelectionStyle.none
        setupContentView()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
   fileprivate func setupContentView() {
        normalLabel = UILabel.init(frame: CGRect.init(x: 10, y: 10, width: kScreenW-20, height: 0))
        expandLabel = UILabel.init(frame: CGRect.init(x: 10, y: 10, width: kScreenW-20, height: 0))
        
        normalLabel?.textColor = UIColor.gray
        expandLabel?.textColor = UIColor.black
        
        normalLabel?.font = UIFont.systemFont(ofSize: 14)
        expandLabel?.font = UIFont.systemFont(ofSize: 14)
        
        normalLabel?.numberOfLines = 4
        expandLabel?.numberOfLines = 0
        
        normalLabel?.alpha = 1
        expandLabel?.alpha = 0
        
        self.contentView.addSubview(normalLabel)
        self.contentView.addSubview(expandLabel)
    }
    
    var model : DXCellModel? {
        didSet{
            self.cellType = (model?.cellType)!
            if model?.cellType == .expand {
                normalLabel.alpha = 0
                expandLabel.alpha = 1
                normalLabel.frame = CGRect.init(x: 10, y: 10, width: kScreenW-20, height: 10)
                expandLabel.frame = CGRect.init(x: 10, y: 10, width: kScreenW-20, height: 10)
            }else{
                normalLabel.alpha = 1
                expandLabel.alpha = 0
                normalLabel.frame = CGRect.init(x: 10, y: 10, width: kScreenW-20, height: 10)
                expandLabel.frame = CGRect.init(x: 10, y: 10, width: kScreenW-20, height: 10)
            }
            normalLabel.text = model?.contentStr
            expandLabel.text = model?.contentStr
            
            normalLabel.sizeToFit()
            expandLabel.sizeToFit()
        }
    }
    
   open func clickCell() {
        
        switch cellType {
        case .normal:
            self.cellType = .expand
            self.model?.cellType = .expand
            self.model?.cellHeigh = (self.model?.expandHeigh)!
            cellAnimate(cellType: .normal)
            self.superTableView.beginUpdates()
            self.superTableView.endUpdates()
        case .expand:
            self.cellType = .normal
            self.model?.cellType = .normal
            self.model?.cellHeigh = (self.model?.normalHeigh)!
            cellAnimate(cellType: .expand)
            self.superTableView.beginUpdates()
            self.superTableView.endUpdates()
        default:
            break
        }
    }
    
    func cellAnimate(cellType : DXShowCellTextType){
        if cellType == .normal {
            UIView.animate(withDuration: 0.35, animations: { 
                self.expandLabel.alpha = 1
                self.normalLabel.alpha = 0
            })
        }else{
            UIView.animate(withDuration: 0.35, animations: {
                self.expandLabel.alpha = 0
                self.normalLabel.alpha = 1
            })
        }
    }

}

3.模型

import UIKit
public let kScreenW = UIScreen.main.bounds.size.width
public let kScreenH = UIScreen.main.bounds.size.height

class DXCellModel: NSObject {

    var contentStr : String?
    var cellHeigh : CGFloat = 0.0
    var normalHeigh : CGFloat = 0.0
    var expandHeigh : CGFloat = 0.0
    var cellType : DXShowCellTextType!
    
    
    init(contentStr : String) {
        
        self.contentStr = contentStr
        self.cellType = DXShowCellTextType.normal
        
        let height1 = DXCellModel.getSpaceLabelHeight(text: contentStr, font: 14, width: kScreenW-20.0)
        let height2 = DXCellModel.getSpaceLabelHeight(text: "one", font: 14, width: kScreenW-20.0)
        self.expandHeigh = height1 + 20.0
        
        let normalTextHeight = height1 >= 4*height2 ? 4*height2 : height1
        self.normalHeigh = normalTextHeight + 20
        self.cellHeigh = self.normalHeigh
    }
    
    //MARK: --計(jì)算文字的高度
     fileprivate class func getSpaceLabelHeight(text:String,font:CGFloat,width:CGFloat) -> CGFloat {
        
        let paraDic:[String : Any] = [NSFontAttributeName:UIFont.systemFont(ofSize: font)]
        let size = text.boundingRect(with: CGSize(width:width,height:CGFloat(MAXFLOAT)), options: .usesLineFragmentOrigin, attributes: paraDic, context: nil)
        return size.height;
    }
   
}

demo下載地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,102評(píng)論 4 61
  • 導(dǎo)讀: 在開始閱讀《窮爸爸富爸爸》這本書后,寫過第一篇閱讀筆記《窮人為錢工作,富人讓錢為自己工作》 在閱讀《窮爸爸...
    2018知行合一閱讀 672評(píng)論 0 0
  • 1.塊級(jí)元素與行內(nèi)元素分別有哪些?動(dòng)手測(cè)試并列出4條以上的特性區(qū)別 塊狀元素列表 行內(nèi)元素列表 可變?cè)亓斜?塊級(jí)...
    草鞋弟閱讀 891評(píng)論 0 0
  • 我愿意 攜一抹晨光 追尋你的背影 走在 你曾經(jīng)的足跡上 品位 那不一樣的靜謐心境
    海姆達(dá)爾閱讀 144評(píng)論 2 1
  • 示例在創(chuàng)建button的時(shí)候經(jīng)常需要在button上添加圖片和按鈕,而且一般情況下我們需要的都是圖片在上、標(biāo)題在下...
    MrFire_閱讀 48,536評(píng)論 46 144

友情鏈接更多精彩內(nèi)容