如何在UITableViewCell之间添加间距

sai*_*ili 163 objective-c uitableview ios

有没有办法增加间距UITableViewCell

我创建了一个表,每个单元格只包含一个图像.图像被分配给单元格,如下所示:

cell.imageView.image = [myImages objectAtIndex:indexPath.row];
Run Code Online (Sandbox Code Playgroud)

但这会使图像放大并适合整个单元格,图像之间没有间距.

或者以这种方式说,图像的高度例如是50,并且我想在图像之间添加20个间隔.有没有办法实现这个目标?

Sur*_*gch 141

Swift版本

针对Swift 3进行了更新

为了未来的观众,这个答案比原来的问题更为笼统.它是Swift的基本UITableView示例的补充示例.

在此输入图像描述

概观

基本思想是为每个数组项创建一个新的部分(而不是一个新行).然后可以使用截面标题高度来隔开这些截面.

怎么做

  • 按照Swift的UITableView示例中的描述设置项目.(也就是说,添加一个UITableView并将tableView插座连接到View Controller).

  • 在Interface Builder中,将主视图背景颜色更改为浅蓝色,将UITableView背景颜色更改为清除.

  • 用以下内容替换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).")
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,indexPath.section使用而不是indexPath.row为了获得数组元素和分接位置的正确值.

你是如何在左右两侧获得额外的填充/空间的?

我得到它的方式与为任何视图添加间距的方式相同.我使用了自动布局约束.只需使用Interface Builder中的pin工具为前导和尾随约束添加间距.

  • 此解决方案有效,但如果您使用的是 iOS 15.0+,则需要设置“tableView.sectionHeaderTopPadding = 0”。该属性在其默认值的基础上创建了额外的静态间距。 (4认同)
  • @ user2901306,我最初也犹豫是否使用这种方法,因为我觉得我应该能够只使用行并增加边距或其他东西.但是,我没有找到办法,这种方法运作良好.您不必更改单元格上的自定义项.你基本上只需要为行数添加`numberOfSectionsInTableView`和`return 1`.然后使用`indexPath.section`获取当前单元格索引.尝试一次.我想你会发现你不需要对当前的设置进行很多改动.这绝对比子类化更容易. (2认同)

小智 131

我在单元格之间添加间距的方法是使numberOfSections ="你的数组计数"并使每个部分只包含一行.然后定义headerView及其高度.

- (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;
}
Run Code Online (Sandbox Code Playgroud)

  • 这非常有效.我不得不改变cellForRowAtIndexPath,而不是普通数组[indexPath.row]而是数组[indexPath.section].否则,它将在所有部分中显示数组的第一项. (20认同)
  • @TKutal - 就像cellForRowAtIndexPath中的普通代码一样,但是将indexPath.row更改为indexPath.section (5认同)
  • 那么苹果不应该抱怨,而应该创建一种方便的方法来改变行之间的间距。 (3认同)
  • 虽然这实现了提问者的愿望,但我不相信苹果会推荐这种方法。如果我错了,请纠正我,但我相信“部分”意味着在逻辑上分隔您在表中表示的数据“部分”。您不应该使用“部分”来设置每个数据单元之间的空格样式,否则这些数据应该全部显示在单个部分中。我认为更好的方法(尽管更困难)是子类化 UITableViewCell,并通过在单元格底部添加视图来模拟表视图分隔符。 (2认同)

Hus*_*sam 112

我使用Swift的简单解决方案:

// Inside UITableViewCell subclass

override func layoutSubviews() {
    super.layoutSubviews()

    contentView.frame = contentView.frame.inset(by: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10))
}
Run Code Online (Sandbox Code Playgroud)

结果 在此输入图像描述

  • 如果使用自动布局渲染单元格内容,则在布局子视图时添加插图会剪切单元格内容。 (9认同)
  • 好的解决方案 如果有人遇到问题,我必须首先调用`super.layoutSubviews()`以确保在设置框架之前正确布局整个视图. (6认同)
  • 嘿,胡萨姆。感谢您提供出色的解决方案。不要告诉我如何改变单元格之间添加的内容的颜色? (2认同)
  • 无法为只有一个标签的单元工作。 (2认同)

Fle*_*lea 41

我需要做同样的概念,让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;
}
Run Code Online (Sandbox Code Playgroud)

接下来,我想操纵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];

    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,我使whiteRoundedCornerView高度为70.0,这就是导致模拟空间的原因,因为单元格的高度实际上是80.0但我的contentView是70.0,这使它具有外观.

可能有其他方法可以更好地实现这一点,但这就是我如何找到它的方法.我希望它可以帮助别人.


Cha*_*nok 21

您必须为图像设置框架.未经测试的代码是

cell.imageView.frame = CGRectOffset(cell.frame, 10, 10);
Run Code Online (Sandbox Code Playgroud)

  • @NicoHämäläinen嗯,我在过去三年里开发了20多个应用程序,我总是将子类化为UITableViewCell`以获得我需要的结果:) ...子类化`UITableViewCell`非常常见. (29认同)
  • 刚刚通过backgroundView测试,这是最简单的工作解决方案 (2认同)
  • 如果你是`UITableViewCell`的子类,请确保在`layoutSubviews`中调用此代码 (2认同)

Rai*_*idi 20

我在同一条船上。起初我尝试切换到部分,但就我而言,结果比我原先想象的更令人头疼,所以我一直在寻找替代方案。为了继续使用行(而不是弄乱您访问模型数据的方式),以下是仅使用掩码对我有用的方法

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
}
Run Code Online (Sandbox Code Playgroud)

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

  • 也适用于 Swift 5。 (3认同)

meh*_*oca 9

Swift 4.2解决方案

// Inside UITableViewCell subclass
override func layoutSubviews() {    
    super.layoutSubviews()

    contentView.frame = contentView.frame.inset(by: UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8))
}
Run Code Online (Sandbox Code Playgroud)


小智 9

我覆盖了这个函数是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
}
Run Code Online (Sandbox Code Playgroud)


Fer*_*cio 7

如果您尚未使用节标题(或页脚),则可以使用它们向表格单元格添加任意间距.而不是让一个部分有n行,创建一个包含n个部分的表,每个部分各有一行.

实现tableView:heightForHeaderInSection:控制间距的方法.

您可能还想实现tableView:viewForHeaderInSection:控制间距的样子.


Cra*_*aig 7

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

    cell.layer.borderColor = blueColor.CGColor
    cell.layer.borderWidth = 3
Run Code Online (Sandbox Code Playgroud)


Jul*_*Kro 7

我在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
}
Run Code Online (Sandbox Code Playgroud)

希望对您有帮助。


Ena*_*que 6

swift 3 中的示例..

在此处输入图片说明

  1. 创建单视图应用程序
  2. 在视图控制器中添加 tableview
  3. 为 tablview 单元格添加自定义单元格
  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
    }
    
    Run Code Online (Sandbox Code Playgroud)

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

       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
      }
    
       }
    
    Run Code Online (Sandbox Code Playgroud)
  5. 将完整源代码下载到 Github:链接

    https://github.com/enamul95/CustomSectionTable


小智 6

将节中的行数更改为 1 您已更改节数而不是行数

 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        1
    }
Run Code Online (Sandbox Code Playgroud)

    func numberOfSections(in tableView: UITableView) -> Int {
        return 2
    }
Run Code Online (Sandbox Code Playgroud)

在这里你把行间距

 func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 50
    }
Run Code Online (Sandbox Code Playgroud)


MAL*_*MAN 5

  1. 使用节而不是行
  2. 每个部分应返回一行
  3. 使用indexPath.section, 而不是row
  4. 实现 UITableView 委托方法heightForHeader并返回您想要的间距

显示 3 行之间的空间的表格