Как добавить пользовательский разделитель в UITableViewCell?
Пожалуйста, подождите некоторое время, поскольку это длинное объяснение.
У меня есть UIViewController
, который состоит из UIButton
и a UITableView
, который загружает различные типы UITableViewCell
с идентификатором Cell1
и Cell2
, на событие touchUpInside
кнопки. Я использую раскадровку.
Сепаратор для обеих ячеек настраивается.
Cell1
имеет разделитель, который занимает всю ширину ячейки и 1 пиксельную высоту в нижней части ячейки.
В то время как Cell2
имеет разделитель, который имеет смещение 5 пикселей от ячейки, как влево, так и вправо.
При нажатии кнопки tableView
кнопка tableViewCell
заменяется на основе идентификатора ячейки.
Изначально tableView
занимает полную ширину viewController
и состоит из Cell1, но кнопка нажата, tableViewCell
меняются на Cell2, а кадр tableView
изменяется, ширина уменьшается на 10, а x-origin увеличивается на 5.
Но когда это произойдет, разделитель Cell2
находится на расстоянии 5 пикселей от ячейки справа, а слева - на 5 пикселей.
Это происходит для всех Cell2
, которые загружаются данными, а ячейки, у которых нет данных, кадр изменяется соответствующим образом.
Но ячейка после этого имеет ширину Cell1
(большая ширина)
-(void)setSeperatorStyleForTableView :(UITableViewCell *)cell //this is called in cellForRowAtIndex
{
//cell- type of cell(Cell1 or Cell2)
CGRect seperatorFrame;
UIImageView *seperatorImage;
seperatorFrame = [self setSeperatorFrame:cell];
if(firstCellToBeLoaded)//BOOL used to change the button text and load appropriate cells
{
seperatorImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"table_row
2.png"]];
}
else
{
seperatorImage = [[UIImageView alloc] initWithImage:[UIImage
imageNamed:@"table_row.png"]];
}
seperatorImage.frame = seperatorFrame;
seperatorImage.autoresizingMask = YES;
[cell.contentView addSubview:seperatorImage];
}
//set the customized separator frame
-(CGRect)setSeperatorFrame :(UITableViewCell *)cell
{
CGRect seperatorFrame;
seperatorFrame.size.height = 1.0;
seperatorFrame.origin.y = cell.frame.origin.y + (cell.frame.size.height - 1.0);
if(firstCellToBeLoaded)
{
seperatorFrame.origin.x = cell.frame.origin.x ;
seperatorFrame.size.width = cell.frame.size.width;
}
else
{
seperatorFrame.origin.x = cell.frame.origin.x + 5.0;
seperatorFrame.size.width = cell.frame.size.width -10.0;
}
return seperatorFrame;
}
Ответы
Ответ 1
Вы можете добавить стандартную разделительную линию tableView
и добавить свою пользовательскую строку вверху каждой ячейки.
В следующем коде измените высоту/ширину/цвет/изображение UIView
для установки разделителя.
Самый простой способ добавить пользовательский разделитель - добавить простой UIView
из 1px height:
UIView* separatorLineView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 1)];/// change size as you need.
separatorLineView.backgroundColor = [UIColor grayColor];// you can also put image here
[cell.contentView addSubview:separatorLineView];
Этот код может решить вашу проблему:)
Ответ 2
Правильный способ сделать это будет иметь разделитель в классе ячеек, подкласс UITableViewCell, если вы не добавляете здесь переменную изображения разделителя и при каждом создании ячейки вы можете просто изменить изображение и кадр, а не добавлять что на каждом перерисовке. Если вам нужен код для этого, я также могу это предоставить. В настоящее время, когда ячейка перерисована, у нее уже есть изображение u, добавленное в прошлый раз, и вы просто добавляете это снова, либо вы удаляете его в методе -prepareForReuse, либо просто делаете, как я объяснил выше.
***** Custom Cell *****
//
// CustomCell.m
// Custom
//
// Created by Syed Arsalan Pervez on 2/8/13.
// Copyright (c) 2013 SAPLogix. All rights reserved.
//
#import "CustomCell.h"
@implementation CustomCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
_separatorImage = [[UIImageView alloc] initWithFrame:CGRectZero];
[[self contentView] addSubview:_separatorImage];
}
return self;
}
- (void)prepareForReuse
{
_separatorImage.image = nil;
}
- (void)dealloc
{
[_separatorImage release];
[super dealloc];
}
@end
Использование указанной ячейки в контроллере представления.
***** Test View Controller *****
//
// TestViewController.m
// Custom
//
// Created by Syed Arsalan Pervez on 2/8/13.
// Copyright (c) 2013 SAPLogix. All rights reserved.
//
#import "TestViewController.h"
#import "CustomCell.h"
@interface TestViewController ()
@end
@implementation TestViewController
- (void)viewDidLoad
{
[self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
#warning TODO: set the image name here
_separatorImage1 = [[UIImage imageNamed:@""] retain];
_separatorImage2 = [[UIImage imageNamed:@""] retain];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 2;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *_identifier = @"CustomCell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:_identifier];
if (!cell)
{
cell = [[[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:_identifier] autorelease];
}
//Set Separator Image Here
//Preload the image so it doesn't effect the scrolling performance
CGRect frame = cell.contentView.frame;
switch (indexPath.row)
{
case 0:
cell.separatorImage.image = _separatorImage1;
cell.separatorImage.frame = CGRectMake(0, CGRectGetMaxY(frame)-1, frame.size.width, 1);
break;
case 1:
cell.separatorImage.image = _separatorImage2;
cell.separatorImage.frame = CGRectMake(frame.origin.x+5, CGRectGetMaxY(frame)-1, frame.size.width-10, 1);
break;
}
return cell;
}
- (void)dealloc
{
[_separatorImage1 release];
[_separatorImage2 release];
[super dealloc];
}
@end
Ответ 3
Я делаю это так... надеюсь, что это может помочь.
//
// UITableViewCell+MyAdditions.h
//
// Created by Roberto O. Buratti on 19/02/14.
//
#import <UIKit/UIKit.h>
@interface UITableViewCell (MyAdditions)
@property (nonatomic,assign) UITableViewCellSeparatorStyle cellSeparatorStyle;
@property (nonatomic,strong) UIColor *cellSeparatorColor;
@end
//
// UITableViewCell+MyAdditions.m
//
// Created by Roberto O. Buratti on 19/02/14.
//
#import "UITableViewCell+MyAdditions.h"
NSString *const kUITablewViewCellSeparatorLayerName = @"kUITablewViewCellSeparatorLayerName";
@implementation UITableViewCell (MyAdditions)
-(CALayer *)separatorLayer
{
for (CALayer *sublayer in self.layer.sublayers)
{
if ([sublayer.name isEqualToString:kUITablewViewCellSeparatorLayerName])
return sublayer;
}
return nil;
}
-(CALayer *)newSeparatorLayer
{
CALayer *separatorLayer = [CALayer layer];
separatorLayer.name = kUITablewViewCellSeparatorLayerName;
separatorLayer.frame = CGRectMake(0, self.bounds.size.height - 1, self.bounds.size.width, 1);
separatorLayer.backgroundColor = [UIColor whiteColor].CGColor;
[self.layer addSublayer:separatorLayer];
return separatorLayer;
}
-(UITableViewCellSeparatorStyle)cellSeparatorStyle
{
CALayer *separatorLayer = [self separatorLayer];
if (separatorLayer == nil)
return UITableViewCellSeparatorStyleNone;
else
return UITableViewCellSeparatorStyleSingleLine;
}
-(void)setCellSeparatorStyle:(UITableViewCellSeparatorStyle)separatorStyle
{
CALayer *separatorLayer = [self separatorLayer];
switch (separatorStyle)
{
case UITableViewCellSeparatorStyleNone:
[separatorLayer removeFromSuperlayer];
break;
case UITableViewCellSeparatorStyleSingleLine:
if (separatorLayer == nil)
separatorLayer = [self newSeparatorLayer];
break;
default:
@throw [NSException exceptionWithName:NSStringFromClass([self class]) reason:@"Unsupported separatorStyle" userInfo:nil];
break;
}
}
-(UIColor *)cellSeparatorColor
{
CALayer *separatorLayer = [self separatorLayer];
return [UIColor colorWithCGColor:separatorLayer.backgroundColor];
}
-(void)setCellSeparatorColor:(UIColor *)separatorColor
{
CALayer *separatorLayer = [self separatorLayer];
if (separatorLayer == nil)
separatorLayer = [self newSeparatorLayer];
separatorLayer.backgroundColor = separatorColor.CGColor;
}
@end
Теперь вы можете делать что-то вроде
UITableViewCell *cell = ...
cell.cellSeparatorStyle = UITableViewCellSeparatorStyleSingleLine;
cell.cellSeparatorColor = [UIColor orangeColor];
Ответ 4
Как говорили другие, обычно есть два способа сделать это: либо создайте разделитель CALayer
, либо UIView
1px и добавьте его в contentView
.
Со временем я видел, как несколько проектов делают это по-разному, а иногда и несколько разных способов в одном проекте. Также легко вводить ошибки из-за повторного использования ячеек, а также для правильной визуализации пиксельных линий необходимо включить масштаб экрана: (1.0 / [UIScreen mainScreen].scale)
.
Я создал библиотеку которая упрощает это только к одному классу методов, без необходимости подкласса.
https://github.com/kgaidis/KGViewSeparators
Objective-C
[view kg_show:YES separator:KGViewSeparatorTop color:[UIColor blackColor] lineWidth:KGViewSeparatorLineWidth(1.0) insets:UIEdgeInsetsMake(0, 15.0, 0, 15.0)];
Swift:
view.kg_show(true, separator: .Bottom, color: UIColor.blackColor(), lineWidth: KGViewSeparatorLineWidth(1.0), insets: UIEdgeInsetsZero)