Скрыть разделительную линию на одном UITableViewCell
я настраиваю a UITableView
. Я хочу скрыть линию, разделяющую на последние ячейки ... я могу это сделать?
Я знаю, что могу сделать tableView.separatorStyle = UITableViewCellStyle.None
но это повлияет все ячейки tableView. Я хочу, чтобы это повлияло только на мою последнюю клетку.
30 ответов:
на
viewDidLoad
добавьте следующую строку:self.tableView.separatorColor = [UIColor clearColor];
и
cellForRowAtIndexPath
:для iOS более низких версий
if(indexPath.row != self.newCarArray.count-1){ UIImageView *line = [[UIImageView alloc] initWithFrame:CGRectMake(0, 44, 320, 2)]; line.backgroundColor = [UIColor redColor]; [cell addSubview:line]; }
для iOS 7 верхних версий (включая iOS 8)
if (indexPath.row == self.newCarArray.count-1) { cell.separatorInset = UIEdgeInsetsMake(0.f, cell.bounds.size.width, 0.f, 0.f); }
вы можете использовать следующий код:
Swift:
if indexPath.row == {your row number} { cell.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: .greatestFiniteMagnitude) }
или :
cell.separatorInset = UIEdgeInsetsMake(0, 0, 0, UIScreen.main.bounds.width)
для поля по умолчанию:
cell.separatorInset = UIEdgeInsetsMake(0, tCell.layoutMargins.left, 0, 0)
чтобы показать разделитель конец в конец
cell.separatorInset = .zero
Цель-C:
if (indexPath.row == {your row number}) { cell.separatorInset = UIEdgeInsetsMake(0.0f, 0.0f, 0.0f, CGFLOAT_MAX); }
выполнить Hiren'ы ответ.
на ViewDidLoad и следующая строка :
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
или, если вы используете XIB или раскадровки меняем "разделитель" на "нет":
и CellForRowAtIndexPath добавить это :
CGFloat separatorInset; // Separator x position CGFloat separatorHeight; CGFloat separatorWidth; CGFloat separatorY; UIImageView *separator; UIColor *separatorBGColor; separatorY = cell.frame.size.height; separatorHeight = (1.0 / [UIScreen mainScreen].scale); // This assures you to have a 1px line height whatever the screen resolution separatorWidth = cell.frame.size.width; separatorInset = 15.0f; separatorBGColor = [UIColor colorWithRed: 204.0/255.0 green: 204.0/255.0 blue: 204.0/255.0 alpha:1.0]; separator = [[UIImageView alloc] initWithFrame:CGRectMake(separatorInset, separatorY, separatorWidth,separatorHeight)]; separator.backgroundColor = separatorBGColor; [cell addSubView: separator];
вот пример результата, где я показываю tableview с динамическими ячейками (но только один с содержимым.) В результате получается, что только у этого есть разделитель, а не все "фиктивные", которые tableview автоматически добавляет Для заполнения экрана.
надеюсь, что это помогает.
EDIT: для тех, кто не всегда читает комментарии, на самом деле есть лучший способ сделать это с помощью нескольких строк кода :
override func viewDidLoad() { super.viewDidLoad() tableView.tableFooterView = UIView() }
Если вы не хотите рисовать разделитель себя, используйте это:
// Hide the cell separator by moving it to the far right cell.separatorInset = UIEdgeInsetsMake(0, 10000, 0, 0);
этот API доступен только начиная с iOS 7.
моя среда разработки
- Xcode 7.0
- 7A220 Свифт 2.0
- iOS 9.0
выше ответы не полностью работает для меня
после попытки, мое, наконец, рабочее решение:
let indent_large_enought_to_hidden:CGFloat = 10000 cell.separatorInset = UIEdgeInsetsMake(0, indent_large_enought_to_hidden, 0, 0) // indent large engough for separator(including cell' content) to hidden separator cell.indentationWidth = indent_large_enought_to_hidden * -1 // adjust the cell's content to show normally cell.indentationLevel = 1 // must add this, otherwise default is 0, now actual indentation = indentationWidth * indentationLevel = 10000 * 1 = -10000
лучшее решение для iOS 7 & 8
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { DLog(@""); if (cell && indexPath.row == 0 && indexPath.section == 0) { DLog(@"cell.bounds.size.width %f", cell.bounds.size.width); cell.separatorInset = UIEdgeInsetsMake(0.f, cell.bounds.size.width, 0.f, 0.0f); } }
Если ваше приложение вращается-используйте 3000.0 f для левой вставки константы или calc его на лету. Если вы попытаетесь установить правую вставку, у вас есть видимая часть разделителя на левой стороне ячейки на iOS 8.
в iOS 7 разделитель ячеек сгруппированного стиля UITableView выглядит немного иначе. Это выглядит немного так:
я попробовал Кеменаран ответ для этого:
cell.separatorInset = UIEdgeInsetsMake(0, 10000, 0, 0);
однако это, кажется, не работает для меня. Я не знаю почему. Поэтому я решил использовать Hiren's ответ, но через
UIView
вместоUIImageView
, и рисует линию в стиле iOS 7:UIColor iOS7LineColor = [UIColor colorWithRed:0.82f green:0.82f blue:0.82f alpha:1.0f]; //First cell in a section if (indexPath.row == 0) { UIView *line = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 1)]; line.backgroundColor = iOS7LineColor; [cell addSubview:line]; [cell bringSubviewToFront:line]; } else if (indexPath.row == [self.tableViewCellSubtitles count] - 1) { UIView *line = [[UIView alloc] initWithFrame:CGRectMake(21, 0, self.view.frame.size.width, 1)]; line.backgroundColor = iOS7LineColor; [cell addSubview:line]; [cell bringSubviewToFront:line]; UIView *lineBottom = [[UIView alloc] initWithFrame:CGRectMake(0, 43, self.view.frame.size.width, 1)]; lineBottom.backgroundColor = iOS7LineColor; [cell addSubview:lineBottom]; [cell bringSubviewToFront:lineBottom]; } else { //Last cell in the table view UIView *line = [[UIView alloc] initWithFrame:CGRectMake(21, 0, self.view.frame.size.width, 1)]; line.backgroundColor = iOS7LineColor; [cell addSubview:line]; [cell bringSubviewToFront:line]; }
если вы используете это, убедитесь, что вы подключите правильную высоту представления таблицы во втором операторе if. Я надеюсь, что это полезно для кого-то.
на Swift 3 и Swift 4, вы можете написать расширение для UITableViewCell следующим образом:
extension UITableViewCell { func hideSeparator() { self.separatorInset = UIEdgeInsets(top: 0, left: self.bounds.size.width, bottom: 0, right: 0) } func showSeparator() { self.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) } }
затем вы можете использовать это, как показано ниже (когда ячейка является вашим экземпляром ячейки):
cell.hideSeparator() cell.showSeparator()
действительно лучше назначить ширину ячейки табличного представления как левую вставку вместо присвоения ей некоторого случайного числа. Потому что в некоторых размерах экрана, возможно, не сейчас, но в будущем ваши разделители все еще могут быть видны, потому что этого случайного числа может быть недостаточно. Кроме того, в iPad в ландшафтном режиме вы не можете гарантировать, что ваши разделители всегда будут невидимыми.
на Свифт используя iOS 8.4:
/* Tells the delegate that the table view is about to draw a cell for a particular row. (optional) */ override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { if indexPath.row == 3 { // Hiding separator line for only one specific UITableViewCell cell.separatorInset = UIEdgeInsetsMake(0, cell.bounds.size.width, 0, 0) } }
Примечание: этот фрагмент выше будет работать на UITableView с помощью динамических ячеек. Единственная проблема, с которой вы можете столкнуться, - это использование статических ячеек с категориями, типом разделителя, отличным от none, и сгруппированным стилем для табличного представления. На самом деле, в этом конкретном случае он не будет скрывать последнюю ячейку каждой категории. Для преодоления этого, решение, которое я нашел, состояло в том, чтобы установить разделитель ячеек (через IB) в none, а затем создание и добавление вручную (через код) вашего вида строки в каждую ячейку. Для примера, пожалуйста, проверьте фрагмент ниже:
/* Tells the delegate that the table view is about to draw a cell for a particular row. (optional) */ override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { // Row 2 at Section 2 if indexPath.row == 1 && indexPath.section == 1 { // Hiding separator line for one specific UITableViewCell cell.separatorInset = UIEdgeInsetsMake(0, cell.bounds.size.width, 0, 0) // Here we add a line at the bottom of the cell (e.g. here at the second row of the second section). let additionalSeparatorThickness = CGFloat(1) let additionalSeparator = UIView(frame: CGRectMake(0, cell.frame.size.height - additionalSeparatorThickness, cell.frame.size.width, additionalSeparatorThickness)) additionalSeparator.backgroundColor = UIColor.redColor() cell.addSubview(additionalSeparator) } }
используйте этот подкласс, set
separatorInset
не работает для iOS 9.2.1, содержимое будет сжато.@interface NSPZeroMarginCell : UITableViewCell @property (nonatomic, assign) BOOL separatorHidden; @end @implementation NSPZeroMarginCell - (void) layoutSubviews { [super layoutSubviews]; for (UIView *view in self.subviews) { if (![view isKindOfClass:[UIControl class]]) { if (CGRectGetHeight(view.frame) < 3) { view.hidden = self.separatorHidden; } } } } @end
Я не верю, что этот подход будет работать при любых обстоятельствах с динамическими ячейками...
if (indexPath.row == self.newCarArray.count-1) { cell.separatorInset = UIEdgeInsetsMake(0.f, cell.bounds.size.width, 0.f, 0.f); }
не имеет значения, какой метод tableview вы делаете это для динамических ячеек ячейка, в которой вы изменили свойство inset, всегда будет иметь свойство inset, установленное теперь каждый раз, когда он удаляется из очереди, вызывая волнение отсутствующих разделителей строк... То есть до тех пор, пока вы не измените его сами.
что-то вроде этого сработало для меня:
if indexPath.row == franchises.count - 1 { cell.separatorInset = UIEdgeInsetsMake(0, cell.contentView.bounds.width, 0, 0) } else { cell.separatorInset = UIEdgeInsetsMake(0, 0, cell.contentView.bounds.width, 0) }
таким образом, вы обновляете ur состояние структуры данных при каждой загрузке
в инструменту UITableViewCell подкласс, переопределить layoutSubviews и скрыть _UITableViewCellSeparatorView. Работает под iOS 10.
override func layoutSubviews() { super.layoutSubviews() subviews.forEach { (view) in if view.dynamicType.description() == "_UITableViewCellSeparatorView" { view.hidden = true } } }
используя Swift 3 и приняв самый быстрый метод взлома, вы можете улучшить код с помощью расширения:
extension UITableViewCell { var isSeparatorHidden: Bool { get { return self.separatorInset.right != 0 } set { if newValue { self.separatorInset = UIEdgeInsetsMake(0, self.bounds.size.width, 0, 0) } else { self.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0) } } } }
затем, когда вы настроить мобильный:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "identifier", for: indexPath) switch indexPath.row { case 3: cell.isSeparatorHidden = true default: cell.isSeparatorHidden = false } return cell } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let cell = tableView.cellForRow(at: indexPath) if cell.isSeparatorHidden { // do stuff } }
if([_data count] == 0 ){ [self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];// [self tableView].=YES; } else { [self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];//// [self tableView].hidden=NO; }
если принятый ответ не работает, вы можете попробовать это:
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { return 0.01f; }
Это здорово ;)
Swift:
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { ... // remove separator for last cell cell.separatorInset = indexPath.row < numberOfRowsInSection-1 ? tableView.separatorInset : UIEdgeInsets(top: 0, left: tableView.bounds.size.width, bottom: 0, right: 0) return cell }
Цель-C:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { ... // remove separator for last cell cell.separatorInset = (indexPath.row < numberOfRowsInSection-1) ? tableView.separatorInset : UIEdgeInsetsMake(0.f, tableView.bounds.size.width, 0.f, 0.f); return cell; }
попробуйте ниже код может помочь вам решить вашу проблему.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSString* reuseIdentifier = @"Contact Cell"; UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier]; if (nil == cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier]; if (indexPath.row != 10) {//Specify the cell number cell.backgroundView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"bgWithLine.png"]]; } else { cell.backgroundView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"bgWithOutLine.png"]]; } } return cell; }
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *cellId = @"cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId]; NSInteger lastRowIndexInSection = [tableView numberOfRowsInSection:indexPath.section] - 1; if (row == lastRowIndexInSection) { CGFloat halfWidthOfCell = cell.frame.size.width / 2; cell.separatorInset = UIEdgeInsetsMake(0, halfWidthOfCell, 0, halfWidthOfCell); } }
вы должны взять пользовательскую ячейку и добавить метку и установить ограничение, такое как метка должна охватывать всю область ячейки. и напишите нижеприведенную строку в конструкторе.
- (void)awakeFromNib { // Initialization code self.separatorInset = UIEdgeInsetsMake(0, 10000, 0, 0); //self.layoutMargins = UIEdgeInsetsZero; [self setBackgroundColor:[UIColor clearColor]]; [self setSelectionStyle:UITableViewCellSelectionStyleNone]; }
также установите поле макета UITableView следующим образом
tblSignup.layoutMargins = UIEdgeInsetsZero;
лучший способ добиться этого - отключить разделители строк по умолчанию, подкласс
UITableViewCell
и добавить пользовательский разделитель строк в качестве подвидаcontentView
- см. ниже пользовательскую ячейку, которая используется для представления объекта типаSNStock
, который имеет два строковых свойства,ticker
иname
:import UIKit private let kSNStockCellCellHeight: CGFloat = 65.0 private let kSNStockCellCellLineSeparatorHorizontalPaddingRatio: CGFloat = 0.03 private let kSNStockCellCellLineSeparatorBackgroundColorAlpha: CGFloat = 0.3 private let kSNStockCellCellLineSeparatorHeight: CGFloat = 1 class SNStockCell: UITableViewCell { private let primaryTextColor: UIColor private let secondaryTextColor: UIColor private let customLineSeparatorView: UIView var showsCustomLineSeparator: Bool { get { return !customLineSeparatorView.hidden } set(showsCustomLineSeparator) { customLineSeparatorView.hidden = !showsCustomLineSeparator } } var customLineSeparatorColor: UIColor? { get { return customLineSeparatorView.backgroundColor } set(customLineSeparatorColor) { customLineSeparatorView.backgroundColor = customLineSeparatorColor?.colorWithAlphaComponent(kSNStockCellCellLineSeparatorBackgroundColorAlpha) } } required init(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } init(reuseIdentifier: String, primaryTextColor: UIColor, secondaryTextColor: UIColor) { self.primaryTextColor = primaryTextColor self.secondaryTextColor = secondaryTextColor self.customLineSeparatorView = UIView(frame:CGRectZero) super.init(style: UITableViewCellStyle.Subtitle, reuseIdentifier:reuseIdentifier) selectionStyle = UITableViewCellSelectionStyle.None backgroundColor = UIColor.clearColor() contentView.addSubview(customLineSeparatorView) customLineSeparatorView.hidden = true } override func prepareForReuse() { super.prepareForReuse() self.showsCustomLineSeparator = false } // MARK: Layout override func layoutSubviews() { super.layoutSubviews() layoutCustomLineSeparator() } private func layoutCustomLineSeparator() { let horizontalPadding: CGFloat = bounds.width * kSNStockCellCellLineSeparatorHorizontalPaddingRatio let lineSeparatorWidth: CGFloat = bounds.width - horizontalPadding * 2; customLineSeparatorView.frame = CGRectMake(horizontalPadding, kSNStockCellCellHeight - kSNStockCellCellLineSeparatorHeight, lineSeparatorWidth, kSNStockCellCellLineSeparatorHeight) } // MARK: Public Class API class func cellHeight() -> CGFloat { return kSNStockCellCellHeight } // MARK: Public API func configureWithStock(stock: SNStock) { textLabel!.text = stock.ticker as String textLabel!.textColor = primaryTextColor detailTextLabel!.text = stock.name as String detailTextLabel!.textColor = secondaryTextColor setNeedsLayout() } }
чтобы отключить использование разделителя строк по умолчанию,
tableView.separatorStyle = UITableViewCellSeparatorStyle.None;
. Потребительская сторона относительно проста, см. пример ниже:private func stockCell(tableView: UITableView, indexPath:NSIndexPath) -> UITableViewCell { var cell : SNStockCell? = tableView.dequeueReusableCellWithIdentifier(stockCellReuseIdentifier) as? SNStockCell if (cell == nil) { cell = SNStockCell(reuseIdentifier:stockCellReuseIdentifier, primaryTextColor:primaryTextColor, secondaryTextColor:secondaryTextColor) } cell!.configureWithStock(stockAtIndexPath(indexPath)) cell!.showsCustomLineSeparator = true cell!.customLineSeparatorColor = tintColor return cell! }
Я не мог скрыть разделитель в определенной ячейке, за исключением использования следующего обходного пути
- (void)layoutSubviews { [super layoutSubviews]; [self hideCellSeparator]; } // workaround - (void)hideCellSeparator { for (UIView *view in self.subviews) { if (![view isKindOfClass:[UIControl class]]) { [view removeFromSuperview]; } } }
Для Swift 2:
добавить следующую строку
viewDidLoad()
:tableView.separatorColor = UIColor.clearColor()
для iOS7 и выше, более чистый способ-использовать бесконечность вместо жестко закодированного значения. Вам не нужно беспокоиться об обновлении ячейки, когда экран вращается.
if (indexPath.row == <row number>) { cell.separatorInset = UIEdgeInsetsMake(0, INFINITY, 0, 0); }
моим требованием было скрыть разделитель между 4-й и 5-й ячейкой. Я достиг этого с помощью
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { if(indexPath.row == 3) { cell.separatorInset = UIEdgeInsetsMake(0, cell.bounds.size.width, 0, 0); } }
гораздо проще и логичнее сделать это:
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section { return [[UIView alloc] initWithFrame:CGRectZero]; }
в большинстве случаев вы не хотите видеть только последний разделитель tableCiewCell. И этот подход удаляет только последний разделитель tableViewCell, и вам не нужно думать о проблемах автозапуска (т. е. вращающемся устройстве) или значениях жесткого кода для настройки вставок разделителя.
как (многие) другие указали, вы можете легко скрыть все разделители UITableViewCell, просто отключив их для всего самого UITableView; например, в вашем UITableViewController
- (void)viewDidLoad { ... self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; ... }
к сожалению, это настоящий Пита, чтобы сделать на в ячейке основа, которая является то, что вы действительно спрашиваете.
лично я пробовал множество комбинаций, меняя
cell.separatorInset.left
, вновь, как и (многие) другие предложили, но проблема в том, чтобы цитата Apple (курсив добавлен):"...Это свойство можно использовать для добавления пространства между текущей ячейкой содержание и левый и правый края стола. Положительные значения вставки move содержимое ячейки и сепаратор клетки внутрь и далеко от краев таблицы..."
поэтому, если вы попытаетесь "скрыть" разделитель, сдвинув его за экран вправо,вы можете также отступить от contentView вашей ячейки. Как было предложено crifan, вы можете попытаться компенсировать этот неприятный побочный эффект, установив
cell.indentationWidth
иcell.indentationLevel
соответственно, чтобы переместить все назад, но я обнаружил, что это также ненадежно (контент все еще получает отступ...).самый надежный способ я нашел, чтобы
layoutSubviews
в простой инструменту UITableViewCell подкласс и установить право вставка так, чтобы она попадала в левую вставку, делая разделитель шириной 0 и поэтому невидимым [это нужно сделать в layoutSubviews, чтобы автоматически обрабатывать вращения]. Я также добавляю удобный метод в свой подкласс, чтобы включить его.@interface MyTableViewCellSubclass() @property BOOL separatorIsHidden; @end @implementation MyTableViewCellSubclass - (void)hideSeparator { _separatorIsHidden = YES; } - (void)layoutSubviews { [super layoutSubviews]; if (_separatorIsHidden) { UIEdgeInsets inset = self.separatorInset; inset.right = self.bounds.size.width - inset.left; self.separatorInset = inset; } } @end
предостережение: нет надежного способа восстановить оригинал правая вставка, так что вы не можете 'un-скрыть' разделитель, поэтому я использую необратимый
hideSeparator
метод (против разоблачения separatorIsHidden). Обратите внимание, что separatorInset сохраняется в повторно используемых ячейках, поэтому, поскольку вы не можете "скрыть", вам нужно изолировать эти ячейки скрытого разделителя reuseIdentifier.
на iOS9 у меня была проблема, что изменение разделительных вставок также влияет на позиционирование текста - и detailLabel.
Я решил это с помощью этого
override func layoutSubviews() { super.layoutSubviews() separatorInset = UIEdgeInsets(top: 0, left: layoutMargins.left, bottom: 0, right: width - layoutMargins.left) }
Он работает для меня, когда я использую расширение и вызов в layoutSubviews() для обновления макетов сразу.
extension UITableViewCell { func removeSeparator() { separatorInset = UIEdgeInsetsMake(0, bounds.size.width, 0, 0) } } override func layoutSubviews() { super.layoutSubviews() removeSeparator() }