Как добавить интервал между UITableViewCell

Можно ли добавить интервал между UITableViewCell?

Я создал таблицу, и каждая ячейка содержит только изображение. Изображение назначается ячейке следующим образом:

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

но это увеличит изображение и поместится во всю ячейку, и между изображениями не будет промежутка.

Или скажем так, высота изображения, например. 50, и я хочу добавить 20 интервалов между изображениями. Есть ли способ сделать это?

Ответ 1

Быстрая версия

Обновлен для Swift 3

Этот ответ несколько более общий, чем оригинальный вопрос во имя будущих зрителей. Это дополнительный пример базового примера UITableView для Swift.

введите описание изображения здесь

Обзор

Основная идея - создать новый раздел (а не новую строку) для каждого элемента массива. Секции затем могут быть разнесены с использованием высоты заголовка раздела.

Как это сделать

  • Настройте свой проект, как описано в примере UITableView для Swift. (То есть, добавьте UITableView и подключите выход tableView к контроллеру просмотра).

  • В построителе интерфейса измените цвет фона основного вида на синий и цвет фона 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, чтобы получить правильные значения для элементов массива и позиции нажатия.

Как вы получили дополнительное дополнение/пространство справа и слева?

Я получил это так же, как вы добавляете интервал к любому виду. Я использовал ограничения автоматической компоновки. Просто используйте инструмент привязки в построителе интерфейса, чтобы добавить интервал для ведущих и конечных ограничений.

Ответ 2

То, как я достигаю добавление промежутка между ячейками, состоит в том, чтобы сделать 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;
}

Ответ 3

Мое простое решение с использованием Swift:

// 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

Ответ 4

Мне нужно было сделать ту же концепцию, что UITableCells имеет "пространство" между ними. Поскольку вы не можете буквально добавить пространство между ячейками, вы можете подделать его, манипулируя высотой ячейки UITableView, а затем добавив UIView в contentView вашей ячейки. Вот скриншот прототипа, который я сделал в другом тестовом проекте, когда я имитировал это:

Spacing between 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, но мой контентView 70.0, который придает ей внешний вид.

Могут быть другие способы сделать это еще лучше, но это только то, как я нашел, как это сделать. Надеюсь, это поможет кому-то другому.

Ответ 5

Вам нужно будет установить рамку для вашего изображения. Неподтвержденный код

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

Ответ 6

Решение 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))
}

Ответ 7

Если вы больше не используете заголовки разделов (или нижние колонтитулы), вы можете использовать их для добавления произвольного интервала к ячейкам таблицы. Вместо того, чтобы иметь один раздел с n строками, создайте таблицу с n разделами по одной строке.

Внедрите метод tableView:heightForHeaderInSection: для управления интервалом.

Вы также можете реализовать tableView:viewForHeaderInSection:, чтобы контролировать, как выглядит интервал.

Ответ 8

Я думаю, что наиболее прямолинейное решение, если вы просто ищете небольшое пространство и, вероятно, наименее дорого, будет просто установить цвет рамки ячейки на цвет фона для ваших таблиц, а затем установить ширину границы, чтобы получить желаемый результат!

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

Ответ 9

Я решил это так в 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
}

Я надеюсь, что это поможет вам.

Ответ 10

Пример в swift 3..

введите описание изображения здесь

  • Создание одного приложения вида
  • добавить представление таблицы в контроллер
  • добавить пользовательскую ячейку для ячейки tablview
  • просмотр кода контроллера ниже, например

       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 (в таблицеView: 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
      }
    
       }
    
  • Загрузите полный источник в Github: link

    https://github.com/enamul95/CustomSectionTable

Ответ 11

Три подхода, о которых я могу думать:

  • Создайте собственную ячейку таблицы, которая отображает представление всей ячейки так, как вы пожелаете.

  • Вместо добавления изображения в изображения, очистите изображение, создать пользовательский который добавляет UIImageView для изображения и другой вид, возможно простой UIView, который обеспечивает требуемый интервал, и добавляет его как подпункт изображения.

  • Я хочу предложить вам манипулировать UIImageView напрямую, чтобы установить фиксированный размер/дополнение, но я нигде не близок к Xcode, поэтому я не могу подтвердить, будет ли/как это работать.

Это имеет смысл?

Ответ 12

Да, вы можете увеличить или уменьшить расстояние между двумя ячейками, создав одно базовое представление в представлении содержимого в ячейке. Установите прозрачный цвет для фона представления контента, и вы можете настроить высоту базового представления для создания пространства между ячейками.

Ответ 13

Я думаю, что это самое чистое решение:

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

Ответ 14

Эта статья помогла, это в значительной степени то, что сказали другие ответы, но суммировать и кратко

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

В нем он применяет их только к левой и правой сторонам, но инициализация UIEdgeInsetsMake позволяет добавлять отступы ко всем четырем точкам.

func UIEdgeInsetsMake (_ вверху: CGFloat, _ слева: CGFloat, _ внизу: CGFloat, _ справа: CGFloat) → UIEdgeInsets

Описание
Создает вставку края для кнопки или вида. Вставка - это поле вокруг прямоугольника. Положительные значения представляют поля ближе к центру прямоугольника, а отрицательные значения представляют поля дальше от центра.

параметры
top: вставка в верхней части объекта.
слева: вставка слева от объекта
внизу: вставка в нижней части объекта.
справа: вставка справа от объекта.

Возвращает
Вставка для кнопки или вида

Обратите внимание, что UIEdgeInsets также может быть использован для достижения того же.

Xcode 9.3/Swift 4

Ответ 15

Основано на ответе 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

Ответ 16

Я был в одной лодке. Сначала я попытался переключиться на разделы, но в моем случае это оказалось головной болью, чем я думал, поэтому я искал альтернативу. Чтобы продолжать использовать строки (и не связываться с тем, как вы получаете доступ к данным модели), вот что сработало для меня, просто используя маску:

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. Небольшой недостаток: у вас есть verticalPadding/2 отступ verticalPadding/2 в верхней и нижней части tableView, но вы можете быстро это исправить, установив tableView.contentInset.bottom = -verticalPadding/2 и tableView.contentInset.top = -verticalPadding/2, Надеюсь, это кому-нибудь поможет!

Ответ 17

Попробуйте изучить   - (UIEdgeInsets) layoutMargins; на ячейке

Ответ 18

В моей ситуации я использовал пользовательский UIView для viewForHeader в разделе также heightForHeader в разделе return constant height say 40, проблема была в том, что нет данных, все заголовки заголовков были затронуты друг другом. поэтому я хотел простоять между секцией без данных, поэтому я исправил, просто изменив плоскость "tableview style" на "Group". И это сработало для меня.

Ответ 19

Ознакомьтесь с моим решением на GitHub с использованием подклассов UITableView и использованием функций времени выполнения Objective-C.
Он в основном использует закрытую структуру данных Apple 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

Ответ 20

У меня были проблемы с тем, чтобы заставить это работать вместе с фоновыми цветами и дополнительными видами в камере. Закончилось тем, что:

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
}

Ответ 21

Использование заголовков в качестве интервала будет работать нормально, я думаю, если вы не хотите использовать какие-либо заголовки. В противном случае, вероятно, не самая лучшая идея. Что я думаю, это создать собственный вид ячейки.

Примеры:

В пользовательской ячейке создайте фоновое представление с ограничениями, чтобы оно не заполняло всю ячейку, добавьте ему отступы.

Затем сделайте фон таблицы невидимым и удалите разделители:

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

// Remove the separators
tableview.separatorStyle = .none

Ответ 22

Если вы не хотите изменять номер раздела и строки вашего табличного представления (как я это сделал), вот что вы делаете:

1) Добавьте ImageView в нижней части представления ячейки таблицы.

2) Сделайте тот же цвет, что и цвет фона представления таблицы.

Я сделал это в моем приложении, и это работает отлично. Ура!: D

Ответ 23

Используйте UITableViewDelegate, heightForRowAtIndexPath и верните высоту строки.

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

Ответ 24

добавьте внутренний вид в ячейку, затем добавьте к нему свои собственные представления.