利用autolayout計(jì)算自定義cell高度(swift3.0)

前言

大部分APP里面都會(huì)用到UITableView去展示一些列表糯彬,列表高度有固定和根據(jù)內(nèi)容確定的祸泪。之前做過很多高度不固定cell都是通過代碼去計(jì)算搓萧,經(jīng)常會(huì)遇到東西做完之后產(chǎn)品或者設(shè)計(jì)覺得不好又要改的档址,那之前寫的計(jì)算高度的代碼又要改很多景东,感覺很麻煩。這篇文章主要介紹怎樣利用autolayout幫我們計(jì)算不固定cell的高度捆探,再也不用擔(dān)心改動(dòng)很多了然爆。

最終效果

效果1.png

步驟

1.創(chuàng)建自定義cell

新建一個(gè)繼承UITableViewCell的自定義cell,我一般喜歡用xib來搭建UI黍图,可以少寫很多代碼曾雕。


1.png

2.拖控件設(shè)置添加約束,拖線

這里就不詳細(xì)介紹怎么添加約束了助被,實(shí)際工作中可以按照設(shè)計(jì)給的標(biāo)注添加約束剖张。將圖片距離父view最右邊的約束拖出來。

2.png

基本上UI相關(guān)的都完成了揩环,剩下的就是賦值和一些邏輯處理了搔弄。

3.cell賦值和計(jì)算邏輯

var isCalculateHeight = false // 用來標(biāo)記是否是計(jì)算高度的cell
var news : CellModel? { // model
        didSet { // 這里做一些賦值和計(jì)算操作
            lbTitle.text = news?.title
            lbDesc.text = news?.desc
            lbTime.text = news?.time
            var showImg = false
            if (news?.imageUrl?.characters.count)! == 0 {
                conImgRight.constant = -80 //如果沒有圖片則不顯示圖片 -80可以理解為圖片的maxX - 80 = 父試圖的最右邊(也就是寬度)
            }else {
                conImgRight.constant = 15
                showImg = true
            }
            layoutIfNeeded() // 當(dāng)內(nèi)容或者約束發(fā)生改變時(shí)會(huì)重新布局
            if isCalculateHeight == true {  // 只有需要計(jì)算高度時(shí)才執(zhí)行以下代碼
                var cellHeight = CGFloat(lbTime.frame.maxY + 12) // 時(shí)間label的底部 + 設(shè)計(jì)要求的高度
                if showImg == true { // 如果不需要顯示圖片的話就不用管是圖片距離底部最近還是時(shí)間距離底部最近了
                    if imgCover.frame.maxY > lbTime.frame.maxY {
                        cellHeight = CGFloat(imgCover.frame.maxY + 12)
                    }
                }
                news?.cellHeight = cellHeight
            }
        }
    }

4.利用cell自身去計(jì)算高度

創(chuàng)建計(jì)算cell方法

 static func createCalculateCell(maxHeight:CGFloat) -> TableViewCell{
        let cell = TableViewCell.createCell()
        cell.isCalculateHeight = true // 這里要標(biāo)記為true
        var newFrame = cell.frame
        newFrame.size.width = UIScreen.main.bounds.width // 這里注意一定要把cell寬度改為屏幕的寬度或者自己想要的寬度
        newFrame.size.height = maxHeight // ios7對(duì)autolayout的支持不是很好所以最好給一個(gè)最大高度
        cell.frame = newFrame
        return cell
    }

這里需要注意的是,從xib中加載出來的view的大小就是xib里面設(shè)置的大小检盼,所以計(jì)算高度的cell寬度一定要和屏幕一樣大不然計(jì)算出來的高度會(huì)不準(zhǔn)確

創(chuàng)建Cell方法


static func createCell()->TableViewCell {
        /* 注意肯污,這里有個(gè)坑。如果在cell里面又加了手勢(shì)的話吨枉,那就不能取數(shù)組的最后一個(gè)了蹦渣。因?yàn)樽詈笠粋€(gè)是手勢(shì)不是cell
         */
        if let newCell = Bundle.main.loadNibNamed(ID, owner: nil, options: nil)?.last as? TableViewCell {
            return newCell;
        }else {
            let cell = TableViewCell(style: .default, reuseIdentifier: ID)
            cell.textLabel?.text = "error"
            return cell;
        }
    }

可循環(huán)利用cell的創(chuàng)建

static func cell(tableView:UITableView!) -> TableViewCell {
        var cell = tableView.dequeueReusableCell(withIdentifier: ID)
        if cell == nil {
            cell = TableViewCell.createCell()
        }
        return cell as! TableViewCell
    }

5.外部使用

提供一個(gè)專門用來計(jì)算高度的cell,最好用懶加載的方式貌亭。如果一個(gè)頁面有很多種樣式的話柬唯,有些cell可能根本就沒有出現(xiàn)過所以就沒必要?jiǎng)?chuàng)建了

lazy var dataArray = Array<CellModel>() 
lazy var calculateCell = TableViewCell.createCalculateCell(maxHeight: 999)

重寫tableView cell高度的代理方法

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if indexPath.row < dataArray.count {
            let news = dataArray[indexPath.row]
            if news.cellHeight <= 0 { // 只有當(dāng)沒有高度時(shí)才需要計(jì)算
                calculateCell.calculate(model: news)
            }
            return news.cellHeight
        }
        return 0
    }

取模型的時(shí)候最好是判斷一下數(shù)組越界的問題

橫屏效果

效果2.png

屏幕旋轉(zhuǎn)處理

/*
 *首先注冊(cè)屏幕旋轉(zhuǎn)通知
 */
func initListener() {
        NotificationCenter.default.addObserver(self, selector: #selector(TableViewController.orientationDidChange(noti:)), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
 }
 deinit {
        NotificationCenter.default.removeObserver(self)
  }
/*
 *屏幕寬度改變時(shí)也要改變計(jì)算cell的寬度,把已經(jīng)算好的高度改為0(也可以多增加一個(gè)屬性這樣橫豎屏算一次高度就可以了)
 */
 func orientationDidChange(noti:Notification) {
        dataArray.foreach { (news) in
            news.cellHeight = 0
        }
        calculateCell.updateWidth(maxHeight: 999)
        tableView.reloadData()
    }

源碼

點(diǎn)擊這里下載源代碼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末圃庭,一起剝皮案震驚了整個(gè)濱河市锄奢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌剧腻,老刑警劉巖拘央,帶你破解...
    沈念sama閱讀 223,126評(píng)論 6 520
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異书在,居然都是意外死亡灰伟,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,421評(píng)論 3 400
  • 文/潘曉璐 我一進(jìn)店門儒旬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來栏账,“玉大人,你說我怎么就攤上這事栈源〉簿簦” “怎么了?”我有些...
    開封第一講書人閱讀 169,941評(píng)論 0 366
  • 文/不壞的土叔 我叫張陵甚垦,是天一觀的道長(zhǎng)茶鹃。 經(jīng)常有香客問我涣雕,道長(zhǎng),這世上最難降的妖魔是什么前计? 我笑而不...
    開封第一講書人閱讀 60,294評(píng)論 1 300
  • 正文 為了忘掉前任胞谭,我火速辦了婚禮垃杖,結(jié)果婚禮上男杈,老公的妹妹穿的比我還像新娘。我一直安慰自己调俘,他們只是感情好伶棒,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,295評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著彩库,像睡著了一般肤无。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上骇钦,一...
    開封第一講書人閱讀 52,874評(píng)論 1 314
  • 那天宛渐,我揣著相機(jī)與錄音,去河邊找鬼眯搭。 笑死窥翩,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的鳞仙。 我是一名探鬼主播寇蚊,決...
    沈念sama閱讀 41,285評(píng)論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼棍好!你這毒婦竟也來了仗岸?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,249評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤借笙,失蹤者是張志新(化名)和其女友劉穎扒怖,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體业稼,經(jīng)...
    沈念sama閱讀 46,760評(píng)論 1 321
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡盗痒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,840評(píng)論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盼忌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片积糯。...
    茶點(diǎn)故事閱讀 40,973評(píng)論 1 354
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖谦纱,靈堂內(nèi)的尸體忽然破棺而出看成,到底是詐尸還是另有隱情,我是刑警寧澤跨嘉,帶...
    沈念sama閱讀 36,631評(píng)論 5 351
  • 正文 年R本政府宣布川慌,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏梦重。R本人自食惡果不足惜兑燥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,315評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望琴拧。 院中可真熱鬧降瞳,春花似錦、人聲如沸蚓胸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,797評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沛膳。三九已至扔枫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間锹安,已是汗流浹背短荐。 一陣腳步聲響...
    開封第一講書人閱讀 33,926評(píng)論 1 275
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留叹哭,地道東北人忍宋。 一個(gè)月前我還...
    沈念sama閱讀 49,431評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像话速,于是被迫代替她去往敵國(guó)和親讶踪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,982評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫泊交、插件乳讥、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,128評(píng)論 4 61
  • 我們?cè)谏弦黄锻ㄟ^代碼自定義不等高cell》中學(xué)習(xí)了tableView的相關(guān)知識(shí),本文將在上文的基礎(chǔ)上廓俭,利用sto...
    啊世ka閱讀 1,512評(píng)論 2 7
  • 2017.02.22 可以練習(xí)云石,每當(dāng)這個(gè)時(shí)候,腦袋就犯困研乒,我這腦袋真是神奇呀汹忠,一說讓你做事情,你就犯困雹熬,你可不要太...
    Carden閱讀 1,349評(píng)論 0 1
  • 1.xib方式創(chuàng)建 每個(gè)cell的顯示的內(nèi)容都是固定的竿报,也就是cell的高度都是相同的 加載數(shù)據(jù) 有plist文件...
    WeiHing閱讀 6,881評(píng)論 0 6
  • 在三月溫暖的陽光下铅乡,懶懶的翻開日歷,三月十六日烈菌,今天是母親去世兩個(gè)月了阵幸,更忽然已經(jīng)發(fā)現(xiàn)三十歲去哪兒了花履,在三十年來我...
    思想聚焦的原創(chuàng)閱讀 192評(píng)論 0 0