如何添加UITableViewCell之间的间距

有没有办法在UITableViewCell之间添加空格?

我已经创建了一个表,每个单元格只包含一个图像。图像被这样分配给单元格:

cell.imageView.image = [myImages objectAtIndex:indexPath.row];

但这使得图像放大并适合整个细胞,并且图像之间没有间隔。

或者让我们这样说,图像的高度是50,我想在图像之间增加20的间距。有什么办法可以做到吗?

351394 次浏览

你必须为你的图像设置框架。未测试的代码是

cell.imageView.frame = CGRectOffset(cell.frame, 10, 10);

我可以想到三种方法:

  1. 创建一个自定义表格单元格,该单元格以所需的方式显示整个单元格的视图

  2. 而不是将图像添加到 图像视图,清除子视图 图像视图,自定义创建 视图,为图像和另一个视图添加一个UIImageView,也许是一个简单的UIView,提供所需的间距,并添加它作为子视图 李图像视图。< / p > < / >
  3. 我想建议你直接操纵UIImageView来设置一个固定的大小/填充,但我没有接近Xcode,所以我不能确认这是否/如何工作。

明白吗?

如果您还没有使用节页眉(或页脚),您可以使用它们为表单元格添加任意间距。与其创建一个有n行的section,不如创建一个有n个section,每个section都有一行的表。

实现tableView:heightForHeaderInSection:方法来控制间距。

你可能还想实现tableView:viewForHeaderInSection:来控制空格的样子。

我需要做相同的概念,让UITableCells之间有一个“空间”。因为你不能在单元格之间添加空间,你可以通过操纵UITableView的单元格高度来伪造它,然后添加一个UIView到你的单元格的contentView。这是我在另一个测试项目中模拟的一个原型的屏幕截图:

 UITableViewCells间距

下面是一些代码(注意:为了演示目的,有很多硬编码的值)

首先,我需要设置heightForRowAtIndexPath来允许UITableViewCell上的不同高度。

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


NSString *text = [self.newsArray  objectAtIndex:[indexPath row]];
if ([text isEqual:@"December 2012"])
{
return 25.0;
}


return 80.0;
}

接下来,我想操纵UITableViewCells的外观,所以我在willDisplayCell:(NewsUITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath方法中做到了这一点。

- (void)tableView:(UITableView *)tableView willDisplayCell:(NewsUITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (cell.IsMonth)
{
UIImageView *av = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20, 20, 20)];
av.backgroundColor = [UIColor clearColor];
av.opaque = NO;
av.image = [UIImage imageNamed:@"month-bar-bkgd.png"];
UILabel *monthTextLabel = [[UILabel alloc] init];
CGFloat font = 11.0f;
monthTextLabel.font = [BVFont HelveticaNeue:&font];


cell.backgroundView = av;
cell.textLabel.font = [BVFont HelveticaNeue:&font];
cell.textLabel.textColor = [BVFont WebGrey];
}




if (indexPath.row != 0)
{
cell.contentView.backgroundColor = [UIColor clearColor];
UIView *whiteRoundedCornerView = [[UIView alloc] initWithFrame:CGRectMake(10,10,300,70)];
whiteRoundedCornerView.backgroundColor = [UIColor whiteColor];
whiteRoundedCornerView.layer.masksToBounds = NO;
whiteRoundedCornerView.layer.cornerRadius = 3.0;
whiteRoundedCornerView.layer.shadowOffset = CGSizeMake(-1, 1);
whiteRoundedCornerView.layer.shadowOpacity = 0.5;
[cell.contentView addSubview:whiteRoundedCornerView];
[cell.contentView sendSubviewToBack:whiteRoundedCornerView];


}
}

注意,我使我的whiteRoundedCornerView高度70.0,这就是模拟空间的原因,因为单元格的高度实际上是80.0,但我的contentView是70.0,这给了它外观。

也许还有其他更好的方法,但这就是我找到的方法。我希望它能帮助到其他人。

我实现在单元格之间增加间距的方法是使numberOfSections =“您的数组计数”,并使每个部分只包含一行。然后定义headerView和它的height。

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return yourArry.count;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}


-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return cellSpacingHeight;
}


-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *v = [UIView new];
[v setBackgroundColor:[UIColor clearColor]];
return v;
}

在单元格中添加一个内部视图,然后将自己的视图添加到单元格中。

试着看看 ——(UIEdgeInsets) layoutMargins; 在

单元格上

斯威夫特版本

Swift 3更新

为了方便以后的观众,这个答案比原来的问题更一般。它是基本Swift的UITableView示例的补充示例。

enter image description here

概述

基本思想是为每个数组项创建一个新节(而不是新行)。然后,可以使用节头高度对节进行间隔。

怎么做

  • 按照Swift的UITableView示例中的描述设置你的项目。(也就是说,添加一个UITableView并将tableView出口连接到视图控制器)。

  • 在界面构建器中,将主视图背景颜色更改为浅蓝色,并将UITableView背景颜色更改为clear。

  • 用以下代码替换ViewController.swift代码。

ViewController.swift

import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    

// These strings will be the data for the table view cells
let animals: [String] = ["Horse", "Cow", "Camel", "Sheep", "Goat"]
    

let cellReuseIdentifier = "cell"
let cellSpacingHeight: CGFloat = 5
    

@IBOutlet var tableView: UITableView!
    

override func viewDidLoad() {
super.viewDidLoad()
        

// These tasks can also be done in IB if you prefer.
self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellReuseIdentifier)
tableView.delegate = self
tableView.dataSource = self
}
    

// MARK: - Table View delegate methods
    

func numberOfSections(in tableView: UITableView) -> Int {
return self.animals.count
}
    

// There is just one row in every section
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
    

// Set the spacing between sections
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return cellSpacingHeight
}
    

// Make the background color show through
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView()
headerView.backgroundColor = UIColor.clear
return headerView
}
    

// create a cell for each table view row
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        

let cell:UITableViewCell = self.tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as UITableViewCell!
        

// note that indexPath.section is used rather than indexPath.row
cell.textLabel?.text = self.animals[indexPath.section]
        

// add border and color
cell.backgroundColor = UIColor.white
cell.layer.borderColor = UIColor.black.cgColor
cell.layer.borderWidth = 1
cell.layer.cornerRadius = 8
cell.clipsToBounds = true
        

return cell
}
    

// method to run when table view cell is tapped
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// note that indexPath.section is used rather than indexPath.row
print("You tapped cell number \(indexPath.section).")
}
}

注意,使用indexPath.section而不是indexPath.row来获取数组元素的正确值和点击位置。

你是如何在右边和左边得到额外的填充/空间的?

我得到它的方法和你给任何视图加空格的方法是一样的。我使用了自动布局约束。只需使用接口生成器中的销工具来为开头和结尾约束添加空格。

我的情况是我使用自定义UIView viewForHeader在节也hightforheader在节返回常量高度说40,问题是当没有数据时,所有的头视图被彼此触摸。所以我想在没有数据的部分之间留出空间,所以我通过将“tableview style”平面改为“Group”来固定。这对我很有效。

我的简单解决方案使用斯威夫特:

// Inside UITableViewCell subclass


override func layoutSubviews() {
super.layoutSubviews()


contentView.frame = contentView.frame.inset(by: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10))
}

< >强结果 enter image description here < / p >

我认为最直接的解决方案,如果你只是寻找一点空间,可能最便宜的将是简单地设置单元格边框颜色为您的表格背景颜色,然后设置边框宽度,以获得所需的结果!

    cell.layer.borderColor = blueColor.CGColor
cell.layer.borderWidth = 3

我认为这是最干净的解决方案:

class MyTableViewCell: UITableViewCell {
override func awakeFromNib() {
super.awakeFromNib()
layoutMargins = UIEdgeInsetsMake(8, 0, 8, 0)
}
}

是的,你可以增加或减少间距(填充)之间的两个单元格通过创建一个基本视图的内容视图在单元格。为内容视图背景设置清晰的颜色,您可以调整基本视图的高度以创建单元格之间的空间。

使用UITableViewDelegate, heightForRowAtIndexPath并返回行高度。

 (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 100.0f ;
}

例子在swift 3..

enter image description here

  1. 折痕单个视图应用程序
  2. 在视图控制器中添加tableview
  3. 为tableview cell添加customcell
  4. 视图控制器代码如下

       class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
    
    
    @IBOutlet weak var tableView: UITableView!
    
    
    
    
    var arraytable = [[String:Any]]()
    override func viewDidLoad() {
    super.viewDidLoad()
    
    
    arraytable = [
    ["title":"About Us","detail":"RA-InfoTech Ltd -A Joint Venture IT Company formed by Bank Asia Ltd"],
    ["title":"Contact","detail":"Bengal Center (4th & 6th Floor), 28, Topkhana Road, Dhaka - 1000, Bangladesh"]
    ]
    
    
    
    
    
    
    
    
    
    
    
    
    tableView.delegate = self
    tableView.dataSource = self
    
    
    //For Auto Resize Table View Cell;
    tableView.estimatedRowHeight = 44
    tableView.rowHeight = UITableViewAutomaticDimension
    
    
    //Detault Background clear
    tableView.backgroundColor = UIColor.clear
    }
    

    func numberOfSections(in tableView: UITableView) -> Int { 返回arraytable.count } < / p >

       func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 1
    }
    
    
    // Set the spacing between sections
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 10
    }
    
    
    // Make the background color show through
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let headerView = UIView()
    headerView.backgroundColor = UIColor.clear
    
    
    return headerView
    }
    
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
    
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell")! as! CustomCell
    
    
    cell.tv_title.text = arraytable[indexPath.section]["title"] as! String?
    cell.tv_details.text = arraytable[indexPath.section]["detail"] as! String?
    
    
    //label height dynamically increase
    cell.tv_details.numberOfLines = 0
    
    
    
    
    
    
    
    
    //For bottom border to tv_title;
    let frame =  cell.tv_title.frame
    let bottomLayer = CALayer()
    bottomLayer.frame = CGRect(x: 0, y: frame.height - 1, width: frame.width, height: 1)
    bottomLayer.backgroundColor = UIColor.black.cgColor
    cell.tv_title.layer.addSublayer(bottomLayer)
    
    
    //borderColor,borderWidth, cornerRadius
    cell.backgroundColor = UIColor.lightGray
    cell.layer.borderColor = UIColor.red.cgColor
    cell.layer.borderWidth = 1
    cell.layer.cornerRadius = 8
    cell.clipsToBounds = true
    
    
    return cell
    }
    
    
    }
    
  5. Download full source to Github : link

    https://github.com/enamul95/CustomSectionTable

这篇文章很有帮助,它和其他答案差不多,但是总结和简洁

https://medium.com/@andersongusmao/left-and-right margins-on uitableviewcell-595f0ba5f5e6

在其中,他只将它们应用于左右两边,但UIEdgeInsetsMake init允许为所有四个点添加填充。

func UIEdgeInsetsMake(_上:CGFloat, _左:CGFloat, _下:CGFloat, _右:CGFloat) -> UIEdgeInsets

< br > < p >描述 为按钮或视图创建边缘插入。 嵌段是矩形周围的边距。正值表示距矩形中心更近的边距,而负值表示距矩形中心更远的边距 < br > < p >参数 top:位于对象顶部的插页 left:对象
左边的插入 bottom:对象底部的插入。

.右边:对象右边的插入 < br > < p >回报 按钮或视图的插入

注意,UIEdgeInsets也可以用来实现同样的效果。

Xcode 9.3/Swift 4

检查我的GitHub上的解决方案UITableView的子类化和使用Objective-C的运行时特性 它基本上使用苹果的私有数据结构UITableViewRowData,我搜索私有运行时头UITableView:

https://github.com/JaviSoto/iOS10-Runtime-Headers/blob/master/Frameworks/UIKit.framework/UITableView.h,

这里是你想要的私有类,它包含了你需要的所有东西来布局你的单元格的空间,而不需要在单元格的类中设置它:

https://github.com/JaviSoto/iOS10-Runtime-Headers/blob/master/Frameworks/UIKit.framework/UITableViewRowData.h

根据Husam的回答:使用单元格层而不是内容视图允许在整个单元格和附件周围添加边框。这种方法需要仔细调整单元格的底部约束以及那些嵌入,否则视图将不正确。

@implementation TableViewCell


- (void)awakeFromNib {
...
}


- (void) layoutSubviews {
[super layoutSubviews];


CGRect newFrame = UIEdgeInsetsInsetRect(self.layer.frame, UIEdgeInsetsMake(4, 0, 4, 0));
self.layer.frame = newFrame;
}


@end

我也有同感。起初,我试着换到分组课,但对我来说,最后比我最初想象的更头疼,所以我一直在寻找替代方案。为了坚持使用行(而不是混乱你如何访问你的模型数据),下面是我通过使用掩码工作的:

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
{
let verticalPadding: CGFloat = 8


let maskLayer = CALayer()
maskLayer.cornerRadius = 10    //if you want round edges
maskLayer.backgroundColor = UIColor.black.cgColor
maskLayer.frame = CGRect(x: cell.bounds.origin.x, y: cell.bounds.origin.y, width: cell.bounds.width, height: cell.bounds.height).insetBy(dx: 0, dy: verticalPadding/2)
cell.layer.mask = maskLayer
}

你剩下要做的就是使单元格的高度变大增加与你想要的verticalPadding相同的值,然后修改你的内部布局,以便任何与单元格边缘有间距的视图都有相同的间距增加verticalPadding/2。小缺点:你在tableView的顶部和底部都得到了verticalPadding/2填充,但你可以通过设置tableView.contentInset.bottom = -verticalPadding/2tableView.contentInset.top = -verticalPadding/2来快速修复这个问题。希望这能帮助到一些人!

我遇到了麻烦,让它与背景颜色和附属视图一起在单元格中工作。最后不得不:

1)使用带有背景颜色的UIView设置单元格的背景视图属性。

let view = UIView()
view.backgroundColor = UIColor.white
self.backgroundView = view

2)在layoutSubviews中重新定位这个视图,添加间距的想法

override func layoutSubviews() {
super.layoutSubviews()
backgroundView?.frame = backgroundView?.frame.inset(by: UIEdgeInsets(top: 2, left: 0, bottom: 0, right: 0)) ?? CGRect.zero
}

我在Swift 4中是这样解决的。

我创建了UITableViewCell的扩展,并包括以下代码:

override open var frame: CGRect {
get {
return super.frame
}
set (newFrame) {
var frame =  newFrame
frame.origin.y += 10
frame.origin.x += 10
frame.size.height -= 15
frame.size.width -= 2 * 10
super.frame = frame
}
}


override open func awakeFromNib() {
super.awakeFromNib()
layer.cornerRadius = 15
layer.masksToBounds = false
}

我希望这对你有所帮助。

如果你不想使用任何标题,使用标题作为间距也可以。否则,这可能不是最好的主意。我在想的是创建一个自定义单元格视图。

例子:

在自定义单元格中,创建一个带有约束的背景视图,这样它就不会填充整个单元格,给它一些填充。

然后,使tableview背景不可见,并删除分隔符:

// Make the background invisible
tableView.backgroundView = UIView()
tableView.backgroundColor = .clear


// Remove the separators
tableview.separatorStyle = .none

如果你不想改变你的表视图的section和行号(就像我做的那样),下面是你要做的:

1)在表格单元格视图的底部添加一个ImageView。

2)使它与表格视图的背景颜色相同。

我已经在我的应用程序中这样做了,它工作得很好。干杯!: D

不需要使用一堆不同的部分。其他的答案使用框架insets和CGRect和图层…等等等等。不太好;使用自动布局和自定义UITableViewCell。在那个UITableViewCell中,不是在contentView中查看你的内容,而是创建一个新的containerView(一个UIView),在contentView中查看容器视图,然后在容器视图中查看所有视图。

现在要创建空格,只需编辑容器视图的布局边距,如下所示:

class CustomTableViewCell: UITableViewCell {
let containerView = UIView()
let imageView = UIImageView()


required init?(coder aDecoder: NSCoder) {super.init(coder: aDecoder)}


override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)


containerView.translatesAutoResizingMaskIntoConstraints = false
imageView.translatesAutoResizingMaskIntoConstraints = false
contentView.addSubview(containerView)
containerView.addSubview(imageView)


contentView.layoutMargins = UIEdgeInsets(top: 15, left: 3, bottom: 15, right: 3)
containerView.layoutMargins = UIEdgeInsets(top: 15, left: 17, bottom: 15, right: 17) // It isn't really necessary unless you've got an extremely complex table view cell. Otherwise, you could just write e.g. containerView.topAnchor


let cg = contentView.layoutMarginsGuide
let lg = containerView.layoutMarginsGuide
NSLayoutConstraint.activate([
containerView.topAnchor.constraint(equalTo: cg.topAnchor),
containerView.leadingAnchor.constraint(equalTo: cg.leadingAnchor),
containerView.trailingAnchor.constraint(equalTo: cg.trailingAnchor),
containerView.bottomAnchor.constraint(equalTo: cg.bottomAnchor),
imageView.topAnchor.constraint(equalTo: lg.topAnchor),
imageView.leadingAnchor.constraint(equalTo: lg.leadingAnchor),
imageView.trailingAnchor.constraint(equalTo: lg.trailingAnchor),
imageView.bottomAnchor.constraint(equalTo: lg.bottomAnchor)
])
}
}
  1. 使用节而不是行
  2. 每个section应该返回一行
  3. 使用indexPath.section而不是row分配单元格数据
  4. 实现UITableView委托方法heightForHeader并返回所需的间距

table with show space between 3 rows .

你可以像这样简单地在代码中使用constraint:

class viewCell : UITableViewCell
{


@IBOutlet weak var container: UIView!






func setShape() {
self.container.backgroundColor = .blue
self.container.layer.cornerRadius = 20
container.translatesAutoresizingMaskIntoConstraints = false
self.container.widthAnchor.constraint(equalTo:contentView.widthAnchor , constant: -40).isActive = true
self.container.heightAnchor.constraint(equalTo: contentView.heightAnchor,constant: -20).isActive = true
self.container.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
self.container.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true


}
}

添加子视图(容器)并在其中放入其他元素是很重要的。

修改section的行数为1 你改变了section的数量而不是行数

 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
1
}

func numberOfSections(in tableView: UITableView) -> Int {
return 2
}

这里是行与行之间的行距

 func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}

我重写这个函数是UITableViewCell的子类,它对我来说工作正常

override func layoutSubviews() {
super.layoutSubviews()
//set the values for top,left,bottom,right margins
let margins = UIEdgeInsets(top: 5, left: 8, bottom: 5, right: 8)
contentView.frame = contentView.frame.inset(by: margins)
contentView.layer.cornerRadius = 8
}

这是实际的解决方案

使用节而不是行因为每一行都有一个节所以你可以给页眉留出空间节脚这是代码,把它粘贴到你的视图控制器类中,在这里你创建tableview outlet

如果你想要顶部间距使用heightForHeaderInSection 如果你想要底部间距,只需使用heightForFooterInSection如下所示

复制粘贴即可

func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 20
}


func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let v = UIView()
v.backgroundColor = UIColor.clear
return v
}


func numberOfSections(in tableView: UITableView) -> Int {
return 10
}


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}

在阅读其他人的答案后再读这篇文章

我想警告所有想要使用像添加标题这样的解决方案来达到间隔目的的人。如果你这样做,你将不能动画单元格的插入,删除等。例如,如果您使用该方法,您可能会得到这种错误

Invalid update: invalid number of sections. The number of sections contained in the table view after the update (6) must be equal to the number of sections contained in the table view before the update (5), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted).

如果你需要对行进行动画插入和删除,我会在单元格中添加这个空格。如果你关心高亮显示,那么你可以重写方法
func setHighlighted(_ highlighted: Bool, animated: Bool) 并设置高亮自己

为了增加行之间的间距,将使用第二个原型单元格。

在第二个原型单元格中添加一个不同的单元格标识符,然后添加一个空视图并将其边缘约束到单元格的边缘,然后将emptyView的颜色设置为“clear”。

然后在代码中:

import UIKit


class YourViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
        

@IBOutlet weak var yourTableView: UITableView!
        

let yourArray = ["data1", "data2", "data3" /* so on */ ]


let emptyTransparentRowHeight: CGFloat = 10
        

override func viewDidLoad() {
super.viewDidLoad()
    

yourTableView.dataSource = self
yourTableView.delegate = self
}
            



func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (yourArray.count * 2)
}
        

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            

guard indexPath.row % 2 == 0,
let usableCell = tableView.dequeueReusableCell(withIdentifier: "Your First Cell Prototype Identifier") as? YourTableViewCellSubClass
else {
                

return tableView.dequeueReusableCell(withIdentifier: "The Second and Empty Cell Prototype Identifier")!
}
      

usableCell.Label?.text = yourArray[indexPath.row/2]
            

return usableCell
    

}
        

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.row % 2 == 0 {
return tableView.rowHeight
}
            

return self.emptyTransparentRowHeight
}
        

}

只是把对我有用的答案添加到答案池中。

我已经在TableViewCell中添加了一个视图(紫色视图),我使用它作为单元格的内容视图。并约束紫色视图在顶部和底部有填充,或任何你想要的,但我认为这种方式创建了更多的灵活性

TableViewCell→

   override open var frame: CGRect {
get {
return super.frame
}
set {
var frame =  newValue
frame.size.height -= 2
super.frame = frame
}
}