Swift iOS : self sized cell

RecoReco發表於2018-12-14

根據Cell內的內容,動態調整Cell高度,是常用的技術。在iOS 8 或者以上的版本內,這個技術不再需要自己計算行高,而是變得簡單無比。

如下案例,假設一個Cell內有兩個Label,其中一個單行,第二個多行,根據第二個Label的內容的不同,高度也會不同,這個高度的變大,會導致Cell跟著變高。

具體程式碼如下:

    import UIKit
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
        var window: UIWindow?
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
            // Override point for customization after application launch.
            window = UIWindow(frame: UIScreen.main.bounds)
            window?.makeKeyAndVisible()
            window?.rootViewController = Page()
            return true
        }
    }
    class Data: NSObject {
        class func bookList() -> [Book] {
            let bookList = [
                Book(name: "1", details: "Short Text Short Text"),
                Book(name: "2", details: "Long Text Long Text Long Text Long Text Long Text Long Text Long Text Long Text Long Text "),
                ]
            return bookList
        }
    }
    class Page: UIViewController {
        fileprivate let reuserId = "BookTableViewCellIdentifier"
        fileprivate let bookList = Data.bookList()
        fileprivate let tableview = UITableView()
        override func viewDidLoad() {
            super.viewDidLoad()
            title = "Books"
            configureTableView()
        }
        func configureTableView() {
            tableview.dataSource = self
            // key code 1 
            tableview.estimatedRowHeight = 100
            // key code 2
            tableview.rowHeight = UITableViewAutomaticDimension
            tableview.register(Cell.self, forCellReuseIdentifier: reuserId)
            view.addSubview(tableview)
            tableview.frame = self.view.frame
        }
    }
    extension Page : UITableViewDataSource {
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return bookList.count
        }
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableview.dequeueReusableCell(withIdentifier: reuserId, for: indexPath) as! Cell
            let book = bookList[(indexPath as NSIndexPath).row]
            cell.nameLabel.text = book.name
            cell.detailLabel.text = book.details
            return cell
        }
    }
    class Cell: UITableViewCell {
        let nameLabel = UILabel()
        let detailLabel = UILabel()
        override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
            super.init(style: style, reuseIdentifier: reuseIdentifier)
            contentView.addSubview(nameLabel)
            nameLabel.translatesAutoresizingMaskIntoConstraints = false
            nameLabel.numberOfLines = 0
            // key code 3
            detailLabel.numberOfLines = 0
            detailLabel.textColor = UIColor.lightGray
            contentView.addSubview(detailLabel)
            detailLabel.translatesAutoresizingMaskIntoConstraints = false
            let view1 = detailLabel
            let view2 = nameLabel
            let views = ["view1":view1,"view2":view2]
            let hConstraint1=NSLayoutConstraint.constraints(withVisualFormat: "H:|-[view1]-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)
            self.contentView.addConstraints(hConstraint1)
            let hConstraint2=NSLayoutConstraint.constraints(withVisualFormat: "H:|-[view2]-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)
            self.contentView.addConstraints(hConstraint2)
            let vConstraint=NSLayoutConstraint.constraints(withVisualFormat: "V:|-[view2]-5-[view1]-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)
            self.contentView.addConstraints(vConstraint)
        }
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }
    class Book: NSObject {
        let name: String
        let details: String
        init(name: String, details: String) {
            self.name = name
            self.details = details
        }
    }複製程式碼

此程式碼中,關鍵點有三個,分別標註在程式碼體內。

  1. 設定估計行高和行高設定為UITableViewAutomaticDimension。此程式碼設定後,動態調整能力就會起作用。儘管名字和功能並不那麼相符,但是確實就需要設定它才可以

    tableview.estimatedRowHeight = 100
    tableview.rowHeight = UITableViewAutomaticDimension

  2. 設定第二個Label可以多行

    detailLabel.numberOfLines = 0

    這樣,多餘一行的內容才會擴充套件到下一行。這個高度的增加才能撐大Cell

相關文章