【问题标题】:How to add a custom separator to UITableViewCell?如何向 UITableViewCell 添加自定义分隔符?
【发布时间】:2013-02-08 07:41:40
【问题描述】:

请稍等,因为这是一个很长的解释

我有一个UIViewController,它由一个UIButton 和一个UITableView 组成,它在按钮的事件touchUpInside 上加载带有标识符Cell1Cell2 的不同类型的UITableViewCells。我正在使用故事板。

两个单元格的分隔符都是自定义的。

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

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

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

最初tableView占据viewController的完整宽度,由Cell1组成,但点击按钮后,tableViewCells变为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;
}

【问题讨论】:

    标签: ios objective-c


    【解决方案1】:

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

    在以下代码中更改 UIViewhight/width/color/image 以设置您的 separatorLine。

    添加自定义分隔符最简单的方法是添加简单的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];
    

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

    【讨论】:

    • 一般来说,这是可行的。 However, it breaks when the cell is selected/highlighted because then the backgroundColor in all the subviews is reset to transparent.而不是backgroundColor,最好创建一个简单的UIView 子类,它会用drawRect: 中的给定颜色填充自己。此外,分隔符不能进入contentView(因为删除按钮、附件视图等)。它必须直接进入单元格。
    • @Sulthan - 你也可以用图片代替颜色,我在回答的评论中也提到了:)谢谢 :)
    • 最后一个单元格没有添加一行
    • @Mittchel - 如果要覆盖最后一个单元格分隔线,则需要将 separatorLineView 0 的 Y 轴更改为 cell.heigh-1
    【解决方案2】:

    这样做的正确方法是在单元格类中使用分隔符,如果您没有在其中添加分隔符图像变量,则子类 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
    

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

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

      【讨论】:

      • 值得注意的是,如果使用名称separatorStyle 代替cellSeparatorStyle 来表示属性,则无论如何,单元格都会绘制自己奇怪的分隔符。千万不要在您的 UITableViewCell 后代上创建这样的属性。
      【解决方案4】:

      正如其他人所说,通常有两种方法可以做到这一点,要么创建一个CALayer,要么创建一个 1px 的 UIView 分隔符并将其添加到 contentView

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

      我创建了一个library,将其简化为一个方法类,不需要子类化。 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)];

      斯威夫特:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-08-26
        • 2012-09-02
        • 1970-01-01
        • 2021-11-07
        • 1970-01-01
        • 2023-02-01
        • 1970-01-01
        相关资源
        最近更新 更多