自定义tableView:角半径,减小宽度和阴影

Mic*_*ael 5 cocoa-touch objective-c uitableview ios

这就是我想要做的:

在此输入图像描述

如你所见,我想:

  1. 减小tableView的宽度(我想要比分组tableView提供的边缘更多的边距)

  2. 拐角半径(半径大于分组tableView的默认值)

  3. 在桌子周围投下阴影,在最后一个细胞下面留下一个特殊阴影

Fog*_*ter 4

您可以通过自己“绘制”单元格的背景视图来完成此操作。

我建议使用图像作为背景(如果单元格高度相同)。

您将需要三张图像。

顶角为圆角的“顶部”图像。“底部”图像,底角为圆形,阴影效果如您所愿。以及没有圆角的“中间”图像。

如果单元格内没有任何纹理或渐变,那么您可以使用可拉伸图像来减少它们的内存占用。

然后我将子类化 UITableViewCell 并覆盖 backgroundView 以添加 UIImageView。我还提供了一个访问器方法来更改单元格的类型(顶部、中间、底部)。

每个单元格可以具有 UIImage 的三个 placeHolder 属性(topImage、bottomImage 和 middleImage)。当单元格的类型更改时,可以访问它们(使用延迟实例化以确保它们仅在需要时加载一次),然后将 backgroundVIew 图像设置为所需的图像。

像这样的东西...

在 UITableViewCell 子类中定义一个类型枚举...

typedef enum {
    CellTypeTop,
    CellTypeMiddle,
    CellTypeBottom
} cellType;
Run Code Online (Sandbox Code Playgroud)

然后是该类型的属性...

@property (nonatomic) cellType cellType
Run Code Online (Sandbox Code Playgroud)

然后在.m...

定义更多内部属性...

@property UIImageView *bgImageView;
@property UIImage *topImage;
@property UIImage *middleImage;
@property UIImage *bottomImage;
Run Code Online (Sandbox Code Playgroud)

然后添加imageView(仅一次)...

- (void)awakeFromNib //or in the init depends how you are initialising the cell
{
    self.bgImageView = [[UIImageView alloc] initWithFrame:blah];

    [self.backgroundView addSubView:self.bgImageView];
}
Run Code Online (Sandbox Code Playgroud)

现在当类型改变时......

- (void)setCellType:(cellType)cellType
{
    switch(cellType) {
        case CellTypeTop:
            self.bgImageView.image = self.topImage;
            break;
        case CellTypeMiddle:
            self.bgImageView.image = self.middleImage;
            break;
        case CellTypeBottom:
            self.bgImageView.image = self.bottomImage;
            break;
    }
}
Run Code Online (Sandbox Code Playgroud)

最后是图像的惰性实例化......

- (UIImage *)topImage
{
    if (_topImage == nil) {
        _topImage = [UIImage imageNamed:@"topImage"];
        //alternatively...
        _topImage = [[UIImage imageNamed:@"topImage"] stretchableImageWith...
    }

    return _topImage;
}
Run Code Online (Sandbox Code Playgroud)

现在对其他图像重复这些操作。

这将比使用 CALayer 替代方案性能更高(在很大程度上),并且特别是在使用可拉伸图像的情况下,将具有非常小的内存占用。

其他几位用户表示,这对性能、内存、设计等都不利,但与 CALayers 相比,这确实是获得 UserExperience 最佳性能的最佳方式。是的,它会比 CALayers 使用更多的内存,但只是少量的,并且会达到极限,因为只创建了一些可出队的单元。

几个链接解释了在滚动视图中使用 CALayers 时的性能问题...

http://www.quora.com/iOS-Development/What-is-the-best-way-to-optimize-the-performance-of-a-non-paging-but-view-recycling-UIScrollView-involving-加载可能缓存和显示捆绑图像

加载 3 个视图控制器(使用 CALayer 绘制)的滚动视图性能不佳

::编辑:: 编辑回答迈克尔的问题。

  1. 在故事板中创建一个 UITableViewController (在检查器中重命名该类,以便它与您的子类 UITableViewController 相匹配 - 我将其称为 MyTableViewController)。

  2. 在代码中创建 UITableViewCell 的子类(我将称之为 MyTableViewCell)(即 .h 和 .m)。

  3. 将以上与属性、类型和 imageView 相关的代码添加到 MyTableViewCell.h 文件中。

  4. 在情节提要中,选择 TableViewController 中的单元格并将该类重命名为 MyTableViewCell。还要在其上设置重用标识符。

  5. 在 MyTableViewController 代码中,您将需要这样的函数......

    -(UITableViewCell*)tableView:(UITabelView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
    {
        MyTableViewCell *cell = [tableView dequeueCellWithReuseIdentifier:@"Cell"];
    
        cell.cellType = CellTypeTop; //or whichever it needs to be
        cell.textLabel.text = @"Blah";
    
        return cell;
    }
    
    Run Code Online (Sandbox Code Playgroud)

哦,另一件事,在情节提要中,您将能够按照您想要的方式布局单元格,并链接所有标签和图像视图等...确保将 IBOutlet 添加到 UIImageView,以便可以将其链接到故事板。