如何以动态单元格高度和自动布局以编程方式创建一个非常基本的UITableView?

阿文什高尔

请注意:我知道类似行上有很多示例。我正在寻找所需的最少设置的最基本的解决方案。

我正在尝试自己创建一个,但我知道我还有一段路要走。

    #import "ViewController.h"

    @interface ViewController () <UITableViewDataSource, UITableViewDelegate>

    @property(strong, nonatomic) UITableView *tableView;
    @property(strong, nonatomic) NSMutableArray *dataArray;
    @property (strong, nonatomic) UITableViewCell *customCell;

    @end

    @implementation ViewController

    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) style:UITableViewStylePlain];
        [self.tableView setDataSource:self];
        [self.tableView setDelegate:self];
        [self.tableView setShowsVerticalScrollIndicator:NO];
        self.tableView.translatesAutoresizingMaskIntoConstraints = NO;
        self.tableView.rowHeight = UITableViewAutomaticDimension;
        [self.view addSubview:self.tableView];

        self.dataArray = [@[@"For the past 33 years, I have looked in the mirror every morning and asked myself: 'If today were the last day of my life, would I want to do what I am about to do today?' And whenever the answer has been 'No' for too many days in a row, I know I need to change something. -Steve Jobs",
                         @"Be a yardstick of quality. Some people aren't used to an environment where excellence is expected. - Steve Jobs",
                         @"Innovation distinguishes between a leader and a follower. -Steve Jobs"] mutableCopy];


    }

    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

        return [self.dataArray count];
    }

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        NSString *cellIdentifier = @"CustomCell";
        UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];

        if (cell == nil)
        {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        }

        cell.backgroundColor = [UIColor colorWithRed:249.0/255 green:237.0/255 blue:224.0/255 alpha:1.0];

        int dataIndex = (int) indexPath.row % [self.dataArray count];
        cell.textLabel.text = self.dataArray[dataIndex];
        cell.textLabel.numberOfLines = 0;
        cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;

        NSDictionary *views = @{@"label":cell.textLabel};
        NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[label]|"
                                                                       options:0
                                                                       metrics:nil
                                                                         views:views];
        [cell.contentView addConstraints:constraints];

        constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[label]|"
                                                              options: 0
                                                              metrics:nil
                                                                views:views];
        [cell.contentView addConstraints:constraints];

        return cell;

    }

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
        // Calculate a height based on a cell
        if(!self.customCell) {
            self.customCell = [self.tableView dequeueReusableCellWithIdentifier:@"CustomCell"];
        }

        // Configure the cell
        int dataIndex = (int) indexPath.row % [self.dataArray count];
        self.customCell.textLabel.text = self.dataArray[dataIndex];

        // auto layout

        NSDictionary *views = @{@"label":self.customCell.textLabel};
        NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[label]|"
                                                                       options:0
                                                                       metrics:nil
                                                                         views:views];
        [self.customCell.contentView addConstraints:constraints];

        constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[label]|"
                                                              options: 0
                                                              metrics:nil
                                                                views:views];
        [self.customCell.contentView addConstraints:constraints];

        // Layout the cell

        [self.customCell layoutIfNeeded];

        // Get the height for the cell

        CGFloat height = [self.customCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

        // Padding of 1 point (cell separator)
        CGFloat separatorHeight = 1;

        return height + separatorHeight;
    }

    - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {

        return 140;

    }


    @end
阿文什高尔

因此,在浏览了许多示例之后,我终于明白了哪里出了问题。这是其中缺少一行将整个代码弄乱的那些事情之一。对我来说,

cell.bodyLabel.preferredMaxLayoutWidth = tableView.bounds.size.width;

我们需要在heightForRowAtIndexPath方法中添加它,否则会产生约束错误。

感谢这里对这个惊人答案的评论之一,我找到了解决方案尽管在答案中给出的示例代码中,上面的代码行在cellForRowAtIndexPath函数中,而不是在heightForRowAtIndexPath函数中。但是我的代码无法那样运行。

因此,基本代码是

// RJCell.h

#import <UIKit/UIKit.h>

@interface RJTableViewCell : UITableViewCell

@property (strong, nonatomic) UILabel *titleLabel;
@property (strong, nonatomic) UILabel *bodyLabel;

@end

// RJCell.m

#import "RJTableViewCell.h"

@interface RJTableViewCell ()

@property (nonatomic, assign) BOOL didSetupConstraints;

@end

@implementation RJTableViewCell

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Initialization code

        self.titleLabel = [[UILabel alloc] init];
        [self.titleLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
        [self.titleLabel setLineBreakMode:NSLineBreakByTruncatingTail];
        [self.titleLabel setNumberOfLines:1];
        [self.titleLabel setTextAlignment:NSTextAlignmentLeft];
        [self.titleLabel setTextColor:[UIColor blackColor]];
        [self.titleLabel setBackgroundColor:[UIColor clearColor]];
        [self.contentView addSubview:self.titleLabel];

        // Add this label to the button
        self.bodyLabel = [[UILabel alloc] init];
        [self.bodyLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
        [self.bodyLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
        [self.bodyLabel setLineBreakMode:NSLineBreakByTruncatingTail];
        [self.bodyLabel setNumberOfLines:0];
        [self.bodyLabel setTextAlignment:NSTextAlignmentLeft];
        [self.bodyLabel setTextColor:[UIColor darkGrayColor]];
        [self.bodyLabel setBackgroundColor:[UIColor clearColor]];
        [self.contentView addSubview:self.bodyLabel];
    }

    return self;
}

- (void)updateConstraints {
    [super updateConstraints];

    if (self.didSetupConstraints) return;

    // Get the views dictionary
    NSDictionary *viewsDictionary =
        @{
            @"titleLabel" : self.titleLabel,
            @"bodyLabel" : self.bodyLabel
        };

    NSString *format;
    NSArray *constraintsArray;

    //Create the constraints using the visual language format
    format = @"V:|-10-[titleLabel]-10-[bodyLabel]-10-|";
    constraintsArray = [NSLayoutConstraint constraintsWithVisualFormat:format options:0 metrics:nil views:viewsDictionary];
    [self.contentView addConstraints:constraintsArray];

    format = @"|-10-[titleLabel]-10-|";
    constraintsArray = [NSLayoutConstraint constraintsWithVisualFormat:format options:0 metrics:nil views:viewsDictionary];
    [self.contentView addConstraints:constraintsArray];

    format = @"|-10-[bodyLabel]-10-|";
    constraintsArray = [NSLayoutConstraint constraintsWithVisualFormat:format options:0 metrics:nil views:viewsDictionary];
    [self.contentView addConstraints:constraintsArray];

    self.didSetupConstraints = YES;
}

@end

// RJTableViewController.h

#import <UIKit/UIKit.h>

@interface RJTableViewController : UITableViewController

@end

// RJTableViewController.m

#import "RJTableViewController.h"
#import "RJTableViewCell.h"

static NSString *CellIdentifier = @"CellIdentifier";

@interface RJTableViewController ()

@property(strong,nonatomic) NSMutableArray *titleArray;
@property(strong,nonatomic) NSMutableArray *bodyArray;

@end

@implementation RJTableViewController

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
        self.title = @"Table View Controller";
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self.tableView registerClass:[RJTableViewCell class] forCellReuseIdentifier:CellIdentifier];
    self.titleArray = [[UIFont familyNames] mutableCopy];
    for(int i = 0; i < 100; i++) {
        [self.titleArray addObjectsFromArray:[UIFont familyNames]];
    }
    self.bodyArray = [@[@"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",@"Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",@"Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.",@"Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."] mutableCopy];
}

- (void)contentSizeCategoryChanged:(NSNotification *)notification
{
    [self.tableView reloadData];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return [self.titleArray count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    RJTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    int dataIndex = (int) indexPath.row % [self.bodyArray count];
    cell.titleLabel.text =  self.titleArray[indexPath.row];
    cell.bodyLabel.text = self.bodyArray[dataIndex];

    // Make sure the constraints have been added to this cell, since it may have just been created from scratch
    [cell setNeedsUpdateConstraints];

    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{

    RJTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    int dataIndex = (int) indexPath.row % [self.bodyArray count];
    cell.titleLabel.text =  self.titleArray[indexPath.row];
    cell.bodyLabel.text = self.bodyArray[dataIndex];

    cell.bodyLabel.preferredMaxLayoutWidth = tableView.bounds.size.width - (20.0 * 2.0f);

    [cell setNeedsUpdateConstraints];
    [cell updateConstraintsIfNeeded];
    [cell.contentView setNeedsLayout];

    [cell.contentView layoutIfNeeded];

    CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

    return height;
}

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 200.0f;
}

@end

基本上,棘手的部分在两个地方,首先是设置约束。其次,实现heightForRowAtIndexPath和cellForRowAtIndexPath方法。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何以动态单元格高度和自动布局以编程方式创建一个非常基本的UITableView?

来自分类Dev

具有自动布局和动态类型标签的动态UITableView单元格高度

来自分类Dev

如何以编程方式增加iPhone中的UITableView单元格的高度?

来自分类Dev

如何以编程方式选择uitableview单元格?

来自分类Dev

如何以编程方式为iOS中的集合视图单元格提供宽度和高度,Swift 3

来自分类Dev

在Swift中以编程方式IOS7动态绘制UITableView单元格高度

来自分类Dev

一个单元格的HTML表动态高度

来自分类Dev

如何以编程方式选择UITableView单元格(快速2)

来自分类Dev

点击UITableView单元格将创建一个新单元格

来自分类Dev

如何在iOS中使用自动布局处理动态单元格高度

来自分类Dev

如何以编程方式设置单元格颜色epplus?

来自分类Dev

如何以编程方式在Excel中使用图表中的第n个单元格

来自分类Dev

如何以编程方式更新jtable单元格和TableModel?

来自分类Dev

自动布局错误的单元格高度

来自分类Dev

如何使用多个具有静态和动态高度的单元格对UITableView进行约束?

来自分类Dev

如何以编程方式设置 UITableView 的高度

来自分类Dev

如何为UItableView的Section的第一个和最后一个单元格设置圆角

来自分类Dev

如何在UITableView静态单元格中动态更改单元格高度

来自分类Dev

标识UITableView中的最后一个和第一个单元格

来自分类Dev

Excel如何合并多个单元格创建一个单元格

来自分类Dev

以编程方式创建自定义单元格时,ContentView 高度是否等于单元格高度?

来自分类Dev

wpf datagrid以编程方式选择第一个单元格

来自分类Dev

虽然我有一个以编程方式选择的单元格,但indexPathForSelectedRow返回nil

来自分类Dev

以编程方式使用自适应布局来调整hCompact静态单元格高度的大小

来自分类Dev

如何在动态UITableView中创建原型单元格?

来自分类Dev

Android:表格单元格的高度应获取上一个单元格的高度

来自分类Dev

Android:表格单元格的高度应获取上一个单元格的高度

来自分类Dev

ListView以编程方式创建单元格

来自分类Dev

如何以编程方式创建布局约束

Related 相关文章

  1. 1

    如何以动态单元格高度和自动布局以编程方式创建一个非常基本的UITableView?

  2. 2

    具有自动布局和动态类型标签的动态UITableView单元格高度

  3. 3

    如何以编程方式增加iPhone中的UITableView单元格的高度?

  4. 4

    如何以编程方式选择uitableview单元格?

  5. 5

    如何以编程方式为iOS中的集合视图单元格提供宽度和高度,Swift 3

  6. 6

    在Swift中以编程方式IOS7动态绘制UITableView单元格高度

  7. 7

    一个单元格的HTML表动态高度

  8. 8

    如何以编程方式选择UITableView单元格(快速2)

  9. 9

    点击UITableView单元格将创建一个新单元格

  10. 10

    如何在iOS中使用自动布局处理动态单元格高度

  11. 11

    如何以编程方式设置单元格颜色epplus?

  12. 12

    如何以编程方式在Excel中使用图表中的第n个单元格

  13. 13

    如何以编程方式更新jtable单元格和TableModel?

  14. 14

    自动布局错误的单元格高度

  15. 15

    如何使用多个具有静态和动态高度的单元格对UITableView进行约束?

  16. 16

    如何以编程方式设置 UITableView 的高度

  17. 17

    如何为UItableView的Section的第一个和最后一个单元格设置圆角

  18. 18

    如何在UITableView静态单元格中动态更改单元格高度

  19. 19

    标识UITableView中的最后一个和第一个单元格

  20. 20

    Excel如何合并多个单元格创建一个单元格

  21. 21

    以编程方式创建自定义单元格时,ContentView 高度是否等于单元格高度?

  22. 22

    wpf datagrid以编程方式选择第一个单元格

  23. 23

    虽然我有一个以编程方式选择的单元格,但indexPathForSelectedRow返回nil

  24. 24

    以编程方式使用自适应布局来调整hCompact静态单元格高度的大小

  25. 25

    如何在动态UITableView中创建原型单元格?

  26. 26

    Android:表格单元格的高度应获取上一个单元格的高度

  27. 27

    Android:表格单元格的高度应获取上一个单元格的高度

  28. 28

    ListView以编程方式创建单元格

  29. 29

    如何以编程方式创建布局约束

热门标签

归档