有没有办法在UITableViewCell
之间添加间距?
我创建了一个表,每个单元格只包含一个图像。图像被分配给单元格,如下所示:
cell.imageView.image = [myImages objectAtIndex:indexPath.row];
但这会使图像放大并适合整个单元格,图像之间没有间距。
或者以这种方式说,图像的高度是例如50,我想在图像之间添加20个间距。有没有办法实现这个目标?
答案 0 :(得分:129)
更新了Swift 3
为了未来的观众,这个答案比原来的问题更为笼统。这是基本UITableView example for Swift的补充例子。
<强>概述强>
基本思想是为每个数组项创建一个新部分(而不是新行)。然后可以使用节标题高度来隔开这些部分。
怎么做
按照UITableView example for Swift中的说明设置项目。 (也就是说,添加UITableView
并将tableView
出口连接到View Controller。
在界面生成器中,将主视图背景颜色更改为浅蓝色,并将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).")
}
}
请注意,使用indexPath.section
而不是indexPath.row
才能获得数组元素和点按位置的正确值。
你是如何在左右两侧获得额外的填充/空格的?
我的方法与为任何视图添加间距的方式相同。我使用了自动布局约束。只需使用Interface Builder中的pin tool为前导约束和尾随约束添加间距。
答案 1 :(得分:127)
我在单元格之间添加间距的方法是使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;
}
答案 2 :(得分:80)
使用 Swift :
轻松解决方案// Inside UITableViewCell subclass
override func layoutSubviews() {
super.layoutSubviews()
contentView.frame = contentView.frame.inset(by: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10))
}
答案 3 :(得分:40)
我需要做同样的概念,让UITableCells之间有一个“空间”。由于您无法在单元格之间添加空格,因此可以通过操纵UITableView的单元格高度然后将UIView添加到单元格的contentView来伪造它。这是我在模拟这个模型时在另一个测试项目中做的原型的屏幕截图:
这是一些代码(注意:有许多硬编码值用于演示目的)
首先,我需要设置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,这使它具有外观。
可能有其他方法可以更好地实现这一目标,但这就是我如何找到它的方法。我希望它可以帮助别人。
答案 4 :(得分:20)
您必须为图像设置框架。未经测试的代码是
cell.imageView.frame = CGRectOffset(cell.frame, 10, 10);
答案 5 :(得分:7)
如果您尚未使用节标题(或页脚),则可以使用它们向表格单元格添加任意间距。不是让一个部分有n行,而是创建一个包含n个部分的表,每个部分都有一行。
实施tableView:heightForHeaderInSection:
方法来控制间距。
您可能还希望实现tableView:viewForHeaderInSection:
来控制间距的大小。
答案 6 :(得分:6)
将部分中的行数更改为1 您已更改了部分数而不是行数
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
}
答案 7 :(得分:6)
我认为最直接的解决方案,如果你只想寻找一个小空间而且可能最便宜的只是将单元边框颜色设置为表背景颜色,然后设置边框宽度以获得所需的结果!
cell.layer.borderColor = blueColor.CGColor
cell.layer.borderWidth = 3
答案 8 :(得分:4)
我在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
}
希望对您有帮助。
答案 9 :(得分:3)
是的,您可以通过在单元格中的内容视图上创建一个基本视图来增加或减少两个单元格之间的间距(填充)。为内容视图背景设置清晰颜色,您可以调整基本视图的高度以在单元格之间创建空间
答案 10 :(得分:3)
Example in swift 3..
的价值查看控制器代码如下所示
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(在tableView:UITableView中) - &gt; 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
}
}
将完整源码下载到Github:链接
答案 11 :(得分:3)
我能想到的三种方法:
创建一个自定义表格单元格,以您希望的方式布置整个单元格的视图
而不是将图像添加到 图像视图,清除子视图 在图像视图中,创建一个自定义 为图像和另一个视图添加UIImageView的视图,也许是提供所需间距的简单UIView,并将其添加为子视图 图像视图。
这有意义吗?
答案 12 :(得分:2)
我重写了此函数,它是 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
}
答案 13 :(得分:2)
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))
}
答案 14 :(得分:2)
不需要使用许多不同的部分。其他答案使用框架插图和CGRect以及图层和... BLAH。不好;使用自动布局和自定义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)
])
}
}
答案 15 :(得分:2)
1. use sections instead of rows
2. each section should return one row
3. assign your cell data like this e.g [indexPath.section], instead of row
4. use UITableView Method "heightForHeader" and return your desired spacing
5. Do rest things as you were doing it
Thanks!
答案 16 :(得分:1)
我认为这是最干净的解决方案:
class MyTableViewCell: UITableViewCell {
override func awakeFromNib() {
super.awakeFromNib()
layoutMargins = UIEdgeInsetsMake(8, 0, 8, 0)
}
}
答案 17 :(得分:1)
基于Husam的回答:使用单元格层而不是内容视图允许在需要时在整个单元格和附件周围添加边框。这种方法需要仔细调整单元格的底部约束以及那些插入,否则视图将不合适。
column_1 = ["some text", "some more text", "yet some more text"]
column_2 = ["another some text", "another some more text", "yet another some more text"]
for i in range(0, len(column_1 )):
print("{}\t{}".format(column_1[i], column_2[i]))
答案 18 :(得分:1)
这篇文章有所帮助,它几乎是其他答案所说的,但总结和简洁
https://medium.com/@andersongusmao/left-and-right-margins-on-uitableviewcell-595f0ba5f5e6
在其中,他只将它们应用于左侧和右侧,但UIEdgeInsetsMake
init允许向所有四个点添加填充。
func UIEdgeInsetsMake(_ top:CGFloat,_ left:CGFloat,_ bottom:CGFloat,_ right:CGFloat) - &gt; UIEdgeInsets
描述
为按钮或视图创建边缘插入。 插图是矩形周围的边距。正值表示靠近矩形中心的边距,而负值表示距离中心更远的边距。参数
top:对象顶部的插图。
left:对象左侧的插图
bottom:对象底部的插图。
右:对象右侧的插图。返回
按钮或视图的插图
请注意,UIEdgeInsets也可用于实现相同目的。
Xcode 9.3 / Swift 4
答案 19 :(得分:0)
您可以在这样的代码中简单地使用约束:
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
}
}
添加子视图(容器)并在其中放置其他元素很重要。
答案 20 :(得分:0)
使用UITableView
的子类并使用Objective-C的运行时功能查看我的solution on GitHub。
它主要使用Apple的私有数据结构UITableViewRowData
,我搜索了UITableView
的私有运行时头:
以及此处所需的私人课程,其中包含您布置细胞所需的一切信息。然而你想要的间距没有设置在单元格中。课程:
答案 21 :(得分:0)
阅读其他人的答案后阅读此书
我想警告所有想使用该解决方案的人,例如添加用于分隔目的的标头。如果这样做,则将无法为单元格的插入,删除等设置动画。例如,如果使用该方法,则可能会出现这种错误
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)
并自行设置突出显示
答案 22 :(得分:0)
如果您不想更改表格视图的节和行号(像我一样),请执行以下操作:
1)将ImageView添加到表格单元格视图的底部。
2)使其颜色与表格视图的背景色相同。
我已经在我的应用程序中做到了这一点,并且效果很好。干杯! :D
答案 23 :(得分:0)
使用标题作为间距会很好用,我想如果您不想使用任何标题。否则,可能不是最好的主意。我在想的是创建自定义单元格视图。
示例:
在自定义单元格中,创建具有约束的背景视图,以使其不会填充整个单元格,并为其添加一些填充。
然后,使tableview背景不可见并删除分隔符:
// Make the background invisible
tableView.backgroundView = UIView()
tableView.backgroundColor = .clear
// Remove the separators
tableview.separatorStyle = .none
答案 24 :(得分:0)
我很难让它与单元格中的背景色和附件视图一起使用。最终不得不:
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
}
答案 25 :(得分:0)
我在同一条船上。最初,我尝试切换到各个部分,但就我而言,这最终比我原先的想法更令人头疼,因此我一直在寻找替代方法。要继续使用行(而不用弄乱您访问模型数据的方式),这是对我有用的,只需使用蒙版:
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/2
和tableView.contentInset.top = -verticalPadding/2
来快速解决此问题。希望这对某人有帮助!
答案 26 :(得分:0)
我的情况是我使用自定义UIView来查看viewHeader部分还有heightForHeader部分返回常量高度说40,问题是当没有数据时所有标题视图都互相触及。所以我想在没有数据的部分之间留出空间,所以我通过将“tableview style”平面更改为“Group”来修复。它对我有用。
答案 27 :(得分:0)
试着深入研究 - (UIEdgeInsets)layoutMargins; 在细胞上
答案 28 :(得分:-1)
要在行之间添加间距,将使用第二个原型单元格。
向第二个原型单元格添加不同的单元格标识符,然后添加一个空视图并将其边缘约束到单元格的边缘,然后将空视图的颜色设置为“清除”。
然后在您的代码中:
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
}
}
答案 29 :(得分:-2)
使用UITableViewDelegate,heightForRowAtIndexPath
并返回行的高度。
(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 100.0f ;
}
答案 30 :(得分:-3)
这是实际的解决方法
使用节代替行,因为每一行都有一个节,因此您可以在节的页眉和页脚中留出空间,这里的代码只是将其粘贴到创建tableview出口的viewcontroller类中
如果要顶部间距,请使用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
}
答案 31 :(得分:-3)
向单元格添加内部视图,然后将自己的视图添加到其中。