有時候,須要動態調整UITableView的Cell高度,好比內部有一個TextView,內容由用戶決定,可長可短的狀況下,確定是但願Cell和TextView能夠展現所有內容,所以也須要Cell高度也跟着同步越高了。swift
以下代碼,展現一個長度變化的TextView,當內容變化時,Cell高度會跟着變化。當經過UITableView.reloadData加載數據時,會觸發高度計算函數:app
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat複製代碼
代碼以下: ide
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
let page = Page()
page.view.backgroundColor = .blue
self.window!.rootViewController = page
self.window?.makeKeyAndVisible()
return true
}
}
class Table : UITableView,UITableViewDataSource,UITableViewDelegate{
let oldstr = "swift"
let newstr = "The powerful programming language that is also easy to learn. Swift is a powerful and intuitive programming language for macOS, iOS, watchOS and tvOS."
var arr = [""]
var textView : UITextView = UITextView()
override init(frame: CGRect, style: UITableViewStyle) {
super.init(frame:frame,style:style)
arr = [oldstr]
self.dataSource = self
self.delegate = self
}
required init?(coder aDecoder: NSCoder) {
super.init(coder:aDecoder)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let a = UITableViewCell(style: .default, reuseIdentifier: nil)
textView.frame = a.contentView.frame
textView.text = arr[indexPath.row]
a.contentView.addSubview(textView)
return a
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat{
textView.frame.size.height = textHeight()
return textView.frame.height
}
func textHeight()-> CGFloat{
let size = textView.sizeThatFits(CGSize(width: textView.frame.size.width, height: CGFloat.greatestFiniteMagnitude))
return size.height
}
}
class Page: UIViewController {
var a : Table!
override func viewDidLoad() {
super.viewDidLoad()
a = Table()
a.frame = CGRect(x: 0,y: 100,width: 300,height: 100)
self.view.addSubview(a)
let btn = UIButton()
btn.frame = CGRect(x: 0,y: 200,width: 100,height: 20)
btn.setTitle("BigString", for: .normal)
btn.addTarget(self, action: #selector(tap), for: .touchDown)
self.view.addSubview(btn)
}
func tap(){
if a.arr == [a.newstr]{
a.arr = [a.oldstr]
}else{
a.arr = [a.newstr]
}
a.reloadData()
}
}複製代碼
還有一種比較超脫的方式,就是監視textView.contentSize的變化,而後通知TableView從新裝入數據,從而引起高度的從新計算。代碼以下:函數
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
let page = Page()
page.view.backgroundColor = .blue
self.window!.rootViewController = page
self.window?.makeKeyAndVisible()
return true
}
}
class Table : UITableView,UITableViewDataSource,UITableViewDelegate{
let oldstr = "swift"
let newstr = "The powerful programming language that is also easy to learn. Swift is a powerful and intuitive programming language for macOS, iOS, watchOS and tvOS."
var arr = [""]
var textView : UITextView = UITextView()
override init(frame: CGRect, style: UITableViewStyle) {
super.init(frame:frame,style:style)
arr = [oldstr]
self.dataSource = self
self.delegate = self
self.kvoController.observe(self.textView, keyPath: "contentSize", options: [.new]) {
[weak self] (observe, observer, change) -> Void in
self!.reloadData()
}
}
required init?(coder aDecoder: NSCoder) {
super.init(coder:aDecoder)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let a = UITableViewCell(style: .default, reuseIdentifier: nil)
textView.frame = a.contentView.frame
textView.text = arr[indexPath.row]
a.contentView.addSubview(textView)
return a
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat{
textView.frame.size.height = textHeight()
return textView.frame.height
}
func textHeight()-> CGFloat{
let size = textView.sizeThatFits(CGSize(width: textView.frame.size.width, height: CGFloat.greatestFiniteMagnitude))
return size.height
}
}
class Page: UIViewController {
var a : Table!
override func viewDidLoad() {
super.viewDidLoad()
a = Table()
a.frame = CGRect(x: 0,y: 100,width: 300,height: 100)
self.view.addSubview(a)
let btn = UIButton()
btn.frame = CGRect(x: 0,y: 200,width: 100,height: 20)
btn.setTitle("BigString", for: .normal)
btn.addTarget(self, action: #selector(tap), for: .touchDown)
self.view.addSubview(btn)
}
func tap(){
if a.arr == [a.newstr]{
a.arr = [a.oldstr]
}else{
a.arr = [a.newstr]
}
a.textView.text = a.arr[0]
}
}複製代碼
這裏使用了一個組件,是facebook開源的KVOController。所以須要使用Pod加入依賴並安裝它。ui