簡體   English   中英

我如何使自己的細胞自動調整大小?

[英]How do I get my cells to auto-size themselves?

盡管無處不在,但我仍然找不到解決此問題的解決方案。 我正在Xcode中創建一個todo應用程序,當我將標簽文本編輯得更長(多行)時,無法自動調整單元格的大小。 到目前為止,這是我所做的:

  • 將標簽的設置為0
  • 將標簽的換行符設置為自動換行
  • 將這些約束添加到單元格內部的標簽中
  • HomeTableViewController.swift內部添加了以下代碼:

     override func viewWillAppear(_ animated: Bool) { tableView.rowHeight = UITableViewAutomaticDimension tableView.estimatedRowHeight = 85.0 } 

不過,我仍然有這個問題...(注意第1行)

這真令人沮喪,如果有人可以幫助我,我將不勝感激!

整個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文件,請執行以下操作:

  1. 將一個新的空用戶界面文件添加到您的項目,將其命名為TACTableViewCell.xib。

  2. 打開XIB文件,然后將“ 表視圖單元格”添加到畫布。

  3. 在表視圖單元格中添加標簽(我將標簽拉伸到幾乎與表視圖單元格的寬度相等)。

標簽

  1. 通過添加四個約束,指定到標簽最近鄰居的間距。

間隔到最近的鄰居

新添加的約束顯示在畫布左側的停靠欄中。

在此處輸入圖片說明

  1. 將“標簽”的“線”屬性從1更改為0。

在此處輸入圖片說明

  1. 通過單擊下面顯示的行旁邊的空白處的圓並拖動到畫布中的Label,將TACTableViewCell類中名為Label的IBOutlet與Label連接起來。

在此處輸入圖片說明

此時,該應用應該可以成功構建並運行,並顯示與下面類似的內容。

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM