这就是我想要做的:
如您所见,我想:
减小 tableView 的宽度(我希望侧面的边距比分组的 tableView 提供的更多)
角半径(比分组 tableView 的默认值更大的半径)
在桌子周围投下阴影,最后一个单元格下方有一个特殊的阴影
这就是我想要做的:
如您所见,我想:
减小 tableView 的宽度(我希望侧面的边距比分组的 tableView 提供的更多)
角半径(比分组 tableView 的默认值更大的半径)
在桌子周围投下阴影,最后一个单元格下方有一个特殊的阴影
您可以通过自己“绘制”单元格的 backgroundView 来做到这一点。
我建议将图像用作背景(如果单元格的高度相同)。
你需要三张图片。
顶部圆角的“顶部”图像。一个“底部”图像,底角是圆形的,阴影是你想要的。还有一个没有圆角的“中间”图像。
如果单元格中没有任何纹理或渐变,那么您可以使用可拉伸图像来减少它们的内存占用。
然后我将子类化 UITableViewCell 并覆盖 backgroundView 以添加 UIImageView。我还将提供一个访问器方法来更改单元格的类型(顶部、中间、底部)。
然后每个单元格可以具有 UIImage 的三个 placeHolder 属性(topImage、bottomImage 和 middleImage)。当单元格的类型改变时,这些可以被访问(使用惰性实例化来确保它们只在需要时加载一次),然后将 backgroundVIew 图像设置为所需的图像。
像这样的东西...
在 UITableViewCell 子类中定义一个类型枚举...
typedef enum {
CellTypeTop,
CellTypeMiddle,
CellTypeBottom
} cellType;
然后类型的属性...
@property (nonatomic) cellType cellType
然后在.m ...
定义更多内部属性...
@property UIImageView *bgImageView;
@property UIImage *topImage;
@property UIImage *middleImage;
@property UIImage *bottomImage;
然后添加 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];
}
现在当类型改变时......
- (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;
}
}
最后是图像的懒惰实例化......
- (UIImage *)topImage
{
if (_topImage == nil) {
_topImage = [UIImage imageNamed:@"topImage"];
//alternatively...
_topImage = [[UIImage imageNamed:@"topImage"] stretchableImageWith...
}
return _topImage;
}
现在对其他图像重复这些。
这将比使用 CALayer 替代方案更高效(在很长的路上),尤其是在使用可拉伸图像时,内存占用非常小。
其他几位用户表示,这对性能、内存、设计等都不利,但它确实是为 UserExperience 获得最佳性能的最佳方式,而不是 CALayers。是的,它会比 CALayers 使用更多的内存,但只是很小的一部分,并且它会达到一个限制,因为只创建了几个可出队的单元格。
几个链接解释了在滚动视图中使用 CALayers 时的性能问题......
加载了 3 个视图控制器的滚动视图性能不佳,使用 CALayer 绘制
::EDIT:: 编辑回答迈克尔的问题。
在情节提要中创建一个 UITableViewController(重命名检查器中的类,使其与您的子类 UITableViewController 匹配 - 我将其称为 MyTableViewController)。
在代码(即.h 和.m)中创建UITableViewCell 的子类(我将调用我的MyTableViewCell)。
将上面的代码添加到您的 MyTableViewCell.h 文件中,以处理属性和类型以及 imageViews。
在情节提要中,选择 TableViewController 中的单元格并将类重命名为 MyTableViewCell。还要在其上设置重用标识符。
在 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;
}
哦,另一件事,在情节提要中,您将能够按照您希望的方式布局您的单元格并链接所有标签和图像视图等...确保将 IBOutlet 添加到 UIImageView 以便您可以将其链接到故事板。
确保你已经#import <QuartzCore/QuartzCore.h>
导入,然后你就可以开始访问 UITableView 的图层了。
UITableView *yourTable = [[UITableView alloc] initWithStyle:UITableViewStyleGrouped];
[[yourTable layer] setCornerRadius:10.0f];
[[yourTable layer] setShadowColor:[[UIColor blackColor] CGColor]];
[[yourTable layer] setShadowOffset:CGSizeMake([CALayer ShadowOffSetWidthWithFloat:10.0f], [CALayer ShadowOffSetWidthWithFloat:10.0f])];
[[yourTable layer] setShadowOpacity:[CALayer ShadowOpacity:1]];
[[yourTable layer] setMasksToBounds:NO];
UIBezierPath *path = [UIBezierPAth bezierPathWithRect:yourTable.bounds];
[[yourTable layer] setShadowPath:[path CGPath]];
这将为您的表格视图添加阴影效果,阴影不会被遮蔽到 的边界UITableView
,setCornerRadius
您可以将表格的角设置为您想要的任何内容。你也可以frame
通过UITableView
做设置
[yourTable setFrame:CGRectMake(CGFloat x, CGFloat y, CGFloat width, CGFloat height)];
编辑
正如另一位用户试图指出的那样CALayer
非常慢,事实并非如此
引入CALayer是为了帮助解决围绕动画的性能问题。请阅读文档。直接加载图像似乎是个好主意,但从长远来看会占用更多内存。请这个关于图像内存分配的问题。如您所见,它可能看起来更快,但它占用了2.25 MByte of memory
每张图片,在加载每张图片多次后,您的应用程序将开始变慢。