[英]how to get a UITableView row height to auto-size to the size of the UITableViewCell?
[英]How do I get my cells to auto-size themselves?
盡管無處不在,但我仍然找不到解決此問題的解決方案。 我正在Xcode中創建一個todo應用程序,當我將標簽文本編輯得更長(多行)時,無法自動調整單元格的大小。 到目前為止,這是我所做的:
在HomeTableViewController.swift內部添加了以下代碼:
override func viewWillAppear(_ animated: Bool) { tableView.rowHeight = UITableViewAutomaticDimension tableView.estimatedRowHeight = 85.0 }
這真令人沮喪,如果有人可以幫助我,我將不勝感激!
整個HomeViewController.swift代碼:
//
// HomeTableViewController.swift
// Do
//
// Created by Justin Owens on 12/16/17.
// Copyright © 2017 Justin Owens. All rights reserved.
//
import UIKit
class HomeTableViewController: UITableViewController, AddItemTableViewControllerDelegate {
// MARK:
func addItemTableViewControllerCanceled(_ controller: AddItemTableViewController) {
navigationController?.popViewController(animated: true)
}
func addItemTableViewController(_ controller: AddItemTableViewController, didFinishEditing item: DoItem) {
if let index = items.index(of: item)
{
let indexPath = IndexPath(row: index, section: 0)
if let cell = tableView.cellForRow(at: indexPath)
{
configureLabels(for: cell, with: item)
}
}
navigationController?.popViewController(animated: true)
}
func addItemTableViewController(_ controller: AddItemTableViewController, didFinishAdding item: DoItem) {
let newRowIndex = items.count
let indexPath = IndexPath(row: newRowIndex, section: 0)
let indexPaths = [indexPath]
items.append(item)
tableView.insertRows(at: indexPaths, with: .automatic)
navigationController?.popViewController(animated: true)
}
// MARK:
var groups = [""]
// MARK:
var items: [DoItem]
required init?(coder aDecoder: NSCoder)
{
items = [DoItem]()
let row0Item = DoItem()
row0Item.text = "NSA interview"
row0Item.checked = false
items.append(row0Item)
let row1Item = DoItem()
row1Item.text = "Work on app"
row1Item.checked = false
items.append(row1Item)
let row2Item = DoItem()
row2Item.text = "Do homework"
row2Item.checked = false
items.append(row2Item)
let row3Item = DoItem()
row3Item.text = "Catch up on Shameless"
row3Item.checked = false
items.append(row3Item)
super.init(coder: aDecoder)
}
// MARK:
override func viewDidLoad()
{
super.viewDidLoad()
navigationController?.navigationBar.prefersLargeTitles = true
}
override func viewWillAppear(_ animated: Bool)
{
super.viewWillAppear(animated)
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 85.0
}
// MARK:
override func numberOfSections(in tableView: UITableView) -> Int {
return groups.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "DoItemIdentifier", for: indexPath)
let item = items[indexPath.row]
configureLabels(for: cell, with: item)
configureCheckmark(for: cell, with: item)
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
if let cell = tableView.cellForRow(at: indexPath)
{
let item = items[indexPath.row]
item.toggleCheck()
configureCheckmark(for: cell, with: item)
}
tableView.deselectRow(at: indexPath, animated: true)
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
{
let indexPaths = [indexPath]
items.remove(at: indexPath.row)
tableView.deleteRows(at: indexPaths, with: .automatic)
}
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return true
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "Section \(section)"
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "AddItem"
{
let controller = segue.destination as! AddItemTableViewController
controller.delegate = self
}
else if segue.identifier == "EditItem"
{
let controller = segue.destination as! AddItemTableViewController
controller.delegate = self
if let indexPath = tableView.indexPath(for: sender as! UITableViewCell)
{
controller.itemToEdit = items[indexPath.row]
}
}
}
// MARK:
func configureLabels(for cell: UITableViewCell, with item: DoItem)
{
let mainLabel = cell.viewWithTag(1000) as! UILabel
mainLabel.text = item.text
}
func configureCheckmark(for cell: UITableViewCell, with item: DoItem)
{
let checkmark = cell.viewWithTag(1001)
if item.checked
{
checkmark?.isHidden = false
}
else
{
checkmark?.isHidden = true
}
}
// MARK:
@IBAction func addButtonAction(_ sender: Any)
{
let newRowIndex = items.count
let item = DoItem()
let indexPath = IndexPath(row: newRowIndex, section: 0)
let indexPaths = [indexPath]
item.text = ""
item.checked = false
items.append(item)
tableView.insertRows(at: indexPaths, with: .automatic)
}
}
PS我試圖在用戶在AddItemViewController屏幕上編輯標簽后按下“ 完成”按鈕時添加tableView.reloadData()
。 不用說,這沒有改變任何東西。
您錯過了底部約束。 單元格的contentView
不知道如何拉伸,方法是將標簽的底部限制在單元格的底部,這是告訴單元格根據標簽的大小調整自身大小。
請參閱我的其他答案以獲取更多詳細信息。
我可以在您的代碼中看到其他一些難聞的氣味。
首先,更改:
tableView.insertRows(at: indexPaths, with: .automatic)
至:
tableView.beginUpdates()
tableView.insertRows(at: indexPaths, with: .automatic)
tableView.endUpdates()
(同樣適用於刪除行)。
然后移動:
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 85.0
to viewDidLoad
剛開始配置一次就足夠了。
還要放下標簽width
約束-您已經將其設置為限制在前錨和尾錨上(還請確保未設置高度約束)。
最后,使用@IBOutlet
而不是使用標簽來標識在情節@IBOutlet
創建的視圖(我指的是您對單元配置的處理)。
我使用UITableView創建了一個基本應用程序,該應用程序的單元格可以顯示多行文本。
預先道歉,因為我的示例應用是用Objective-C編寫的。
表視圖控制器(TACTableViewController)在應用程序委托中創建。
//
// TACAppDelegate.m
// BasicTable
//
// Created by Steve Developer on 24/01/18.
// Copyright (c) 2018 The App Company. All rights reserved.
//
#import "TACAppDelegate.h"
#import "TACTableViewController.h"
@implementation TACAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
// Create table view controller
TACTableViewController *tableViewController = [[TACTableViewController alloc] init];
// Place table view controller's table view in the window hierarchy
self.window.rootViewController = tableViewController;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
...
表格視圖控制器(TACTableViewController)是UITableViewController的子類。
表格視圖控制器中的init和initWithStyle方法是初始化程序,希望可以自我解釋。
注意:對於此示例應用程序,我已經對方法numberOfRowsInSection返回的值進行了硬編碼。
NB 2:為了自定義表視圖中單元格的行為,我創建了一個XIB文件(TACTableViewCell.xib)和UITableViewCell的子類(TACTableViewCell)。
注意3: 僅覆蓋viewDidLoad方法,以便可以重用表視圖的單元格,在這種情況下,這是沒有意義的,因為只有兩個單元格。
//
// TACTableViewController.m
// BasicTable
//
// Created by Steve Developer on 24/01/18.
// Copyright (c) 2018 The App Company. All rights reserved.
//
#import "TACTableViewController.h"
#import "TACTableViewCell.h"
@implementation TACTableViewController
- (instancetype)init
{
// Call the superclass's designated initializer
self = [super initWithStyle:UITableViewStyleGrouped];
return self;
}
- (instancetype)initWithStyle:(UITableViewStyle)style
{
self = [self init];
return self;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 2;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Get a new or recycled cell
TACTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TACTableViewCell" forIndexPath:indexPath];
// You would normally retrieve data using your model class at this point
NSString *string = @"The quick brown fox jumped over the lazy dog.";
cell.label.text = string;
return cell;
}
// Required to override this method in order to recycle table view cells
- (void)viewDidLoad
{
[super viewDidLoad];
// Load the NIB file
UINib *nib = [UINib nibWithNibName:@"TACTableViewCell" bundle:nil];
// Register this NIB, which contains the cell
[self.tableView registerNib:nib forCellReuseIdentifier:@"TACTableViewCell"];
}
@end
TACTableViewCell是UITableViewCell的子類,其標頭和實現文件與標頭中的IBOutlet(稱為標簽)幾乎是空的。 該出口(將)指向TACTableViewCell.xib中的UILabel。
頭文件:
//
// TACTableViewCell.h
// BasicTable
//
// Created by Steve Developer on 24/01/18.
// Copyright (c) 2018 The App Company. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface TACTableViewCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UILabel *label;
@end
實現文件:
//
// TACTableViewCell.m
// BasicTable
//
// Created by Steve Developer on 24/01/18.
// Copyright (c) 2018 The App Company. All rights reserved.
//
#import "TACTableViewCell.h"
@implementation TACTableViewCell
@end
要創建TACTableViewCell.xib文件,請執行以下操作:
將一個新的空用戶界面文件添加到您的項目,將其命名為TACTableViewCell.xib。
打開XIB文件,然后將“ 表視圖單元格”添加到畫布。
在表視圖單元格中添加標簽(我將標簽拉伸到幾乎與表視圖單元格的寬度相等)。
新添加的約束顯示在畫布左側的停靠欄中。
此時,該應用應該可以成功構建並運行,並顯示與下面類似的內容。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.