Скрыть разделительную линию на одном UITableViewCell
Я настраиваю UITableView
. Я хочу скрыть строку, разделяющую последнюю ячейку... могу ли я сделать это?
Я знаю, что могу сделать tableView.separatorStyle = UITableViewCellStyle.None
, но это повлияет на все ячейки tableView. Я хочу, чтобы это повлияло только на мою последнюю ячейку.
Ответы
Ответ 1
в 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);
}
Ответ 2
Для iOS 7 вы можете использовать следующий код:
Swift 3:
if indexPath.row == {your row number} {
cell.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: .greatestFiniteMagnitude)
}
Objective-C:
if (indexPath.row == {your row number}) {
cell.separatorInset = UIEdgeInsetsMake(0.0f, 0.0f, 0.0f, CGFLOAT_MAX)
}
Ответ 3
Следить за ответом Хирена.
в ViewDidLoad и в следующей строке:
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
Или, если вы используете XIB или Storyboards, измените " разделитель" на " none":
![Interface builder]()
И в 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];
Вот пример результата, где я показываю табличное представление с динамическими ячейками (но только один с содержимым). Результат состоит в том, что только тот, у которого есть разделитель, и не все "dummy" те табличные представления автоматически добавляются, чтобы заполнить экран.
![enter image description here]()
Надеюсь, что это поможет.
EDIT: Для тех, кто не всегда читает комментарии, на самом деле есть лучший способ сделать это с помощью нескольких строк кода:
override func viewDidLoad() {
super.viewDidLoad()
tableView.tableFooterView = UIView()
}
Ответ 4
Если вы не хотите рисовать разделитель самостоятельно, используйте это:
// Hide the cell separator by moving it to the far right
cell.separatorInset = UIEdgeInsetsMake(0, 10000, 0, 0);
Этот API доступен только начиная с iOS 7.
Ответ 5
моя среда разработки
- Xcode 7.0
- 7A220 Swift 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 content to show normally
cell.indentationLevel = 1 // must add this, otherwise default is 0, now actual indentation = indentationWidth * indentationLevel = 10000 * 1 = -10000
и эффект:
![введите описание изображения здесь]()
Ответ 6
Лучшее решение для 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.0f для левой вставки постоянной или выведите его на лету.
Если вы попытаетесь установить правую вставку, у вас есть видимая часть разделителя в левой части ячейки на iOS 8.
Ответ 7
В iOS 7 разделяемый элемент ячейки типа UITableView выглядит несколько иначе. Это выглядит примерно так:
![enter image description here]()
Я попробовал Kemenaran ответить:
cell.separatorInset = UIEdgeInsetsMake(0, 10000, 0, 0);
Однако это не работает для меня. Я не знаю, почему. Поэтому я решил использовать Hiren answer, но используя 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. Надеюсь, что это кому-то полезно.
Ответ 8
В Swift с помощью 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)
}
}
Ответ 9
Я не верю, что этот подход будет работать при любых обстоятельствах с динамическими ячейками...
if (indexPath.row == self.newCarArray.count-1) {
cell.separatorInset = UIEdgeInsetsMake(0.f, cell.bounds.size.width, 0.f, 0.f);
}
Неважно, какой метод tableview вы делаете для динамических ячеек, ячейка, в которую вы изменили свойство вставки, всегда будет иметь свойство вставки, установленное сейчас каждый раз, когда оно отменяется, что приводит к разрыву недостающих разделителей строк... Это пока вы не измените его самостоятельно.
Что-то вроде этого сработало для меня:
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 при каждой загрузке
Ответ 10
Используйте этот подкласс, установка 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
https://gist.github.com/liruqi/9a5add4669e8d9cd3ee9
Ответ 11
В Swift 3.0 вы можете написать расширение для 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 в ландшафтном режиме вы не можете гарантировать, что ваши разделители всегда будут невидимыми.
Ответ 12
if([_data count] == 0 ){
[self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];// [self tableView].=YES;
} else {
[self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];//// [self tableView].hidden=NO;
}
Ответ 13
если принятый ответ не работает, вы можете попробовать следующее:
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 0.01f; }
Это здорово;)
Ответ 14
Для Swift 2:
добавьте следующую строку в viewDidLoad()
:
tableView.separatorColor = UIColor.clearColor()
Ответ 15
В willdisplaycell
:
cell.separatorInset = UIEdgeInsetsMake(0, cell.bounds.size.width, 0, 0)
Ответ 16
В подклассе UITableViewCell переопределите layoutSubviews и скройте _UITableViewCellSeparatorView. Работает под iOS 10.
override func layoutSubviews() {
super.layoutSubviews()
subviews.forEach { (view) in
if view.dynamicType.description() == "_UITableViewCellSeparatorView" {
view.hidden = true
}
}
}
Ответ 17
Используя 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
}
}
Ответ 18
Попробуйте приведенный ниже код, который поможет вам решить вашу проблему.
- (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;
}
Ответ 19
- (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);
}
}
Ответ 20
Вам нужно взять пользовательскую ячейку и добавить ярлык и установить ограничение, например, метка должна охватывать всю область ячеек.
и напишите следующую строку в конструкторе.
- (void)awakeFromNib {
// Initialization code
self.separatorInset = UIEdgeInsetsMake(0, 10000, 0, 0);
//self.layoutMargins = UIEdgeInsetsZero;
[self setBackgroundColor:[UIColor clearColor]];
[self setSelectionStyle:UITableViewCellSelectionStyleNone];
}
Также задайте поле UITableView Layout следующим образом
tblSignup.layoutMargins = UIEdgeInsetsZero;
Ответ 21
Лучший способ добиться этого - отключить разделители строк по умолчанию, подкласс 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!
}
Ответ 22
Я не мог скрыть разделитель в конкретной ячейке, за исключением использования следующего обходного пути
- (void)layoutSubviews {
[super layoutSubviews];
[self hideCellSeparator];
}
// workaround
- (void)hideCellSeparator {
for (UIView *view in self.subviews) {
if (![view isKindOfClass:[UIControl class]]) {
[view removeFromSuperview];
}
}
}
Ответ 23
Для iOS7 и выше более чистым способом является использование INFINITY вместо жестко заданного значения. Вам не нужно беспокоиться об обновлении ячейки при повороте экрана.
if (indexPath.row == <row number>) {
cell.separatorInset = UIEdgeInsetsMake(0, INFINITY, 0, 0);
}
Ответ 24
Мое требование состояло в том, чтобы скрыть разделитель между 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);
}
}
Ответ 25
cell.separatorInset = UIEdgeInsetsMake(0.0, cell.bounds.size.width, 0.0, -cell.bounds.size.width)
хорошо работает в iOS 10.2
![введите описание изображения здесь]()
Ответ 26
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
}
Objective-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;
}
Ответ 27
Ширина iphone - 320. Так что положите левое и правое значение в атрибуте Cell для separatorInset более половины из 320.
Ответ 28
Как указывали другие (многие), вы можете скрыть все разделители UITableViewCell, просто отключив их для всего UITableView; например, в вашем UITableViewController
- (void)viewDidLoad {
...
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
...
}
К сожалению, его реальная PITA делает на основе каждой ячейки, что вы действительно задаете.
Лично я пробовал множество перестановок изменения cell.separatorInset.left
, опять же, как (многие) другие предложили, но проблема состоит в том, чтобы процитировать Apple (выделено мной):
"... Вы можете использовать это свойство, чтобы добавить пробел между текущими ячейками содержимое и левым и правым краями таблицы. Положительные значения вставки перемещают содержимое ячейки и разделитель ячеек внутри и от края таблицы..."
Итак, если вы попытаетесь "спрятать" разделитель, сдвинув его с экрана вправо, вы можете в конечном итоге также отступать от своего содержимого cellView. Как было предложено крифаном, вы можете попытаться компенсировать этот неприятный побочный эффект, установив 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
Предостережение: нет надежного способа восстановить исходную правую вставку, поэтому вы не можете "спрятать" разделитель, поэтому я использую необратимый метод hideSeparator
(vs exposing separatorIsHidden). Обратите внимание, что separatorInset сохраняется в повторно используемых ячейках, поэтому, поскольку вы не можете "скрывать", вам нужно сохранить эти ячейки скрытого разделителя в своем собственном повторном идентификаторе.
Ответ 29
В iOS9 у меня возникла проблема, заключающаяся в том, что изменение вставки разделителя также влияет на позиционирование текстовой и детальной метки.
Я решил это с помощью
override func layoutSubviews() {
super.layoutSubviews()
separatorInset = UIEdgeInsets(top: 0, left: layoutMargins.left, bottom: 0, right: width - layoutMargins.left)
}
Ответ 30
Это ответ, который я дал аналогичному вопросу. Он работает для меня красиво, и вы можете контролировать его, для которого всегда нужна ячейка, которую вы хотите показать или нет.
cell.separatorInset = UIEdgeInsetsMake(0, 160, 0, 160);