How to add a custom separator to UITableViewCell?

后端 未结 4 1107
北海茫月
北海茫月 2020-12-16 17:22

Please spare sometime as this is a long explanation

I have a UIViewController which consists of a UIButton and a UITableView w

相关标签:
4条回答
  • 2020-12-16 17:29

    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];
    
    0 讨论(0)
  • 2020-12-16 17:35

    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.

    ***** 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
    
    0 讨论(0)
  • 2020-12-16 17:37

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

    In following code Change hight/width/color/image of UIView for set your separatorLine.

    The easiest way to add custom separator is to add simple UIView of 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];
    

    This code might solve your problem :)

    0 讨论(0)
  • 2020-12-16 17:41

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

    Over time I've seen multiple projects do this differently, and sometimes, even multiple different ways in the same project. 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).

    I've created a library that simplifies this to just a single method class, with no subclassing required. 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)

    0 讨论(0)
提交回复
热议问题