ios 如何向 UITableViewCell 添加自定义分隔符?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14767847/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 22:13:33  来源:igfitidea点击:

How to add a custom separator to UITableViewCell?

iosobjective-c

提问by user1899840

Please spare sometime as this is a long explanation

请留出一些时间,因为这是一个很长的解释

I have a UIViewControllerwhich consists of a UIButtonand a UITableViewwhich loads different types of UITableViewCells with Identifier Cell1and Cell2, on event touchUpInsideof the button. I m using storyboard.

我有一个UIViewController由 aUIButton和 a组成的 a ,UITableView它在按钮的事件中加载不同类型的UITableViewCells 和 IdentifierCell1和。我正在使用故事板。Cell2touchUpInside

The separator for both cells are customized.

两个电池的隔板都是定制的。

Cell1has a separator that occupies the entire width of cell and 1 pixel height at the bottom of the cell.

Cell1有一个分隔符,占据单元格的整个宽度和单元格底部的 1 个像素高度。

Whereas Cell2has a separator which has offset of 5 pixels from the cell, both left and right.

Cell2有一个分隔符,它与单元格的左右偏移量为 5 个像素。

Each time the button outside the tableViewis clicked the tableViewCells are swapped, based on the cell identifier.

每次单击 外面的tableView按钮时,tableViewCells 都会根据单元格标识符进行交换。

Initially the tableViewoccupies the complete width of viewControllerand consists of Cell1, but the the button is tapped , tableViewCells are changed to Cell2 and the frame of the tableViewis Changed, The width is reduced by 10 and x-origin is increased by 5.

最初tableView占据Cell1的完整宽度viewController并由tableViewCellCell1组成,但是点击按钮,s 更改为 Cell2 并且更改了边框tableView,宽度减少了 10,x-origin 增加了 5。

But when this happens, the separator of Cell2is 5 pixels away from the cell on right but on the left it is away by 5 pixel. This happens for all Cell2which is loaded with data, and the cells which has no data the frame is changed appropriately.

但是当发生这种情况时, 的分隔符与Cell2右侧的单元格相距 5 个像素,而在左侧则相距 5 个像素。对于所有Cell2加载了数据的单元格都会发生这种情况,而没有数据的单元格会适当地更改框架。

But the cell after that has the width of Cell1(larger width)

但是之后的单元格的宽度为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;
}

回答by iPatel

You can add tableView's standard separator line, and add your custom line at the top of each cell.

您可以添加tableView的标准分隔线,并在每个单元格的顶部添加您的自定义线。

In following code Change hight/width/color/imageof UIViewfor set your separatorLine.

在下面的代码更改HIGHT /宽/彩色/图像UIView用于设置您的separatorLine。

The easiest way to add custom separator is to add simple UIViewof 1px height:

添加自定义分隔符的最简单方法是添加简单UIView的 1px 高度:

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];

This code might solve your problem :)

此代码可能会解决您的问题:)

回答by SAPLogix

Right way to do this would be to have the separator with in the cell class, subclass UITableViewCell if you haven't add a separator image variable there and on each cell creation you can just change the image and the frame rather than adding that on each redraw. If you require a code for this i can supply that as well. Currently when the cell is redrawn it already has the image u added last time and you just adding that again, either you remove that in -prepareForReuse method or just do as i explained above.

正确的方法是在单元格类中使用分隔符,子类 UITableViewCell 如果您没有在那里添加分隔符图像变量,并且在每个单元格创建时,您可以更改图像和框架,而不是在每个单元格上添加重绘。如果您需要此代码,我也可以提供。目前,当单元格被重绘时,它已经有你上次添加的图像,你只需再次添加,要么在 -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

Using the above cell in the view controller.

在视图控制器中使用上述单元格。

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

回答by roberto.buratti

I do it this way... hope this might help.

我这样做...希望这可能会有所帮助。

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

Now you can do things like

现在你可以做这样的事情

UITableViewCell *cell = ...
cell.cellSeparatorStyle = UITableViewCellSeparatorStyleSingleLine;
cell.cellSeparatorColor = [UIColor orangeColor];

回答by kgaidis

As others said, usually there's two ways to do this, either create a CALayeror a UIViewseparator of 1px and add it to contentView.

正如其他人所说,通常有两种方法可以做到这一点,要么创建1pxCALayerUIView分隔符或分隔符,然后将其添加到contentView.

Over time I've seen multiple projects do this differently, and sometimes, even multiple different ways in the sameproject. It's also easy to introduce bugs because of cell reuse and also, for proper rendering of pixel lines, one must incorporate the screen scale: (1.0 / [UIScreen mainScreen].scale).

随着时间的推移,我看到多个项目以不同的方式执行此操作,有时甚至在同一项目中以多种不同的方式执行此操作。由于单元格重用也很容易引入错误,而且为了正确渲染像素线,必须合并屏幕比例:(1.0 / [UIScreen mainScreen].scale).

I've created a librarythat simplifies this to just a single method class, with no subclassing required. https://github.com/kgaidis/KGViewSeparators

我创建了一个,将其简化为一个方法类,不需要子类化。 https://github.com/kgaidis/KGViewSeparators

Objective-C:

目标-C

[view kg_show:YES separator:KGViewSeparatorTop color:[UIColor blackColor] lineWidth:KGViewSeparatorLineWidth(1.0) insets:UIEdgeInsetsMake(0, 15.0, 0, 15.0)];

[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)

view.kg_show(true, separator: .Bottom, color: UIColor.blackColor(), lineWidth: KGViewSeparatorLineWidth(1.0), insets: UIEdgeInsetsZero)