如何让我的细胞自动调整大小?

时间:2018-01-18 23:03:02

标签: ios swift

我到处寻找,但是,我仍然无法找到解决这个问题的方法。我正在Xcode中创建一个todo应用程序,当我将标签文本编辑为更长(多行)时,我无法让我的单元格自动调整大小。以下是我到目前为止所做的事情:

  • 将标签的设置为 0
  • 将标签的换行符设置为自动换行
  • Added these constraints to the label inside of the cell
  • HomeTableViewController.swift 中添加了以下代码:

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

Still, I'm having this problem... (notice line 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)
    }
}

P.S。每当用户在 AddItemViewController 屏幕上编辑标签后按完成按钮,我就会尝试添加tableView.reloadData();不用说,这并没有改变任何事情。

2 个答案:

答案 0 :(得分:2)

你错过了底线约束。单元格的img = Image.open(image, mode='r')不知道如何拉伸,通过将标签的底部约束到单元格底部,告诉单元格根据标签大小调整自身大小。

有关详细信息,请参阅my other answer

我可以在你的代码中看到其他一些难闻的气味。

首先,改变:

contentView

为:

tableView.insertRows(at: indexPaths, with: .automatic)

(同样适用于删除行)。

然后移动:

tableView.beginUpdates()
tableView.insertRows(at: indexPaths, with: .automatic)
tableView.endUpdates()

tableView.rowHeight = UITableViewAutomaticDimension tableView.estimatedRowHeight = 85.0 - 它足以在开头配置一次。

同时删除标签viewDidLoad约束 - 您已将其设置为约束前导和尾随锚点(同时确保未设置高度约束)。

最后,使用width而不是使用标签来识别在故事板中创建的视图(我指的是您对单元配置的处理)。

答案 1 :(得分:0)

我使用UITableView创建了一个基本应用程序,其单元格可以显示多行文本。

提前道歉,因为我的示例应用程序是用Objective-C编写的。

表视图控制器(TACTableViewController)在app delegate中创建。

//
//  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方法是初始化程序,希望能够自我解释。

NB 1:对于这个示例应用程序,我对方法numberOfRowsInSection返回的值进行了硬编码。

注意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. 将标签添加到表视图单元格(我将标签拉伸到几乎与表格视图单元格相同的宽度)。

  4. Label

    1. 通过添加四个约束来指定标签最近邻居的间距。
    2. Spacing to its nearest neighbour

      新添加的约束显示在画布左侧的停靠栏中。

      enter image description here

      1. 将Label的Lines属性从1更改为0.
      2. enter image description here

        1. 通过单击下面显示的行旁边的边框并拖动到画布中的标签,将TACTableViewCell类中的IBOutlet(名称标签)与Interface Builder中的Label连接起来。
        2. enter image description here

          此时应用程序应该构建并成功运行并显示类似于下面的内容。

          enter image description here