Draw custom separator line between UITableViewCell on iOS 7

纵饮孤独 提交于 2020-02-06 08:40:36

问题


Because I had some troubles using the default separator line between the UITableViewCell I want to use my own. Therefore I'm using auto layout. C# is the language I used. You can of course provide solutions in Objective-C.

In the constructor of my custom cell I add my view UIView:

separator = new DividerView ();
ContentView.Superview.AddSubview (separator);

One has to add it to the superview otherwise it doesn't cover the accessory area. In updateConstraints I set up my constraints:

separator.TranslatesAutoresizingMaskIntoConstraints = false;

this.ContentView.Superview.AddConstraints (NSLayoutConstraint.FromVisualFormat ("H:|[separator]|", (NSLayoutFormatOptions)0, null, viewsDictionary));
this.ContentView.Superview.AddConstraints (NSLayoutConstraint.FromVisualFormat ("V:|-(82@999)-[separator(1)]|", (NSLayoutFormatOptions)0, null, viewsDictionary));

This for example, does work on iOS 8 but not on iOS 7. Also this constraint V:[separator(1)]| would work on iOS 8 but not on iOS 7.


回答1:


With my knowledge two possibilites come to my mind to solve this:

  1. Instead of using the default accessory views, use no accessory view at all. Instead fake the accessory views by creating the images needed for the acessory views (screenshot of retina display or using a custom image or drawing itself). If you have your fake accessory view one can add it to the contentView and position it with constraints accordingly. Now you can add a line to the content view while disabling the default separator with TableView.SeparatorStyle = UITableViewCellSeparatorStyle.None;. But you have to add events to the created UIButton which holds the image because AccessoryButtonTapped will not be called anymore. That are many steps only for adding a separator line.

  2. Add the separator line on the background view. This is the approach I took.

First the GradientView class which creates my gradient background view with my separator lines:

public class GradientView : UIView
{
    // accessors
    private CAShapeLayer line;
    private bool shouldShowSeparatorLine = false;

    private CAGradientLayer gradientLayer {
        // read-only
        get { return (CAGradientLayer)this.Layer; }
    }

    public CGColor[] Colors {
        // set the colors of the gradient layer
        get { return this.gradientLayer.Colors; }
        set { this.gradientLayer.Colors = value; }
    }

    public GradientView(bool shouldShowSeparatorLine = false)
    {
        this.shouldShowSeparatorLine = shouldShowSeparatorLine;

        this.BackgroundColor = UIColor.Clear;
    }

    [Export ("layerClass")]
    public static Class LayerClass ()
    {
        // use a different Core Animation layer for its backing store
        // normally a CALayer is used for a UIView
        return new Class (typeof(CAGradientLayer));
    }


    public override void Draw (RectangleF rect)
    {
        base.Draw (rect);

        if (shouldShowSeparatorLines) {

            // get graphics context
            CGContext context = UIGraphics.GetCurrentContext ();

            context.SetStrokeColor(UIColor.FromRGB (21,66,139).CGColor);
            context.SetLineWidth (1.0f);
            context.SetShouldAntialias (false);

            float top = 0;
            if (Util.UserInterfaceIdiomIsPhone) {
                top = 0;
            } else {
                top = 1;
            }

            // top
            // start point
            context.MoveTo (0, top);
            // end point
            context.AddLineToPoint (rect.Width, top);
            // draw the path
            context.DrawPath (CGPathDrawingMode.Stroke);

            // bottom
            // start point
            context.MoveTo (0, rect.Height);
            // end point
            context.AddLineToPoint (rect.Width, rect.Height);
            // draw the path
            context.DrawPath (CGPathDrawingMode.Stroke);
        }
    }

You don't need two separator lines, but for my selection problem I needed both.

In your custom UITableViewCell you set the background in the initializer accordingly:

GradientView background = new GradientView (true);
background.Colors = new CGColor[] {
    UIColor.White.CGColor,
    UIColor.White.CGColor,
    UIColor.Blue.CGColor
};

this.BackgroundView = background;

Of course you don't need the gradient thing so you can leave it out. Than your GradientView will only contain the Draw methow with a few fields.




回答2:


This code works for me (subclass of UITableViewCell):

- (void)awakeFromNib {
    // Initialization code
    [super awakeFromNib];
    PCTableViewCellSeparatorView *sV = [[PCTableViewCellSeparatorView alloc] initWithFrame:CGRectMake(0, 0, 0, 1.0)]; // my custom subclass of UIView for drawing 1px line
    sV.backgroundColor = [UIColor clearColor];
    self.accessoryView.backgroundColor = [UIColor clearColor];
    [sV setTranslatesAutoresizingMaskIntoConstraints:NO];
    [self.contentView addSubview:sV];
    // horizontal
    NSNumber *space     = [NSNumber numberWithFloat:0.0f];
    NSNumber *space2    = [NSNumber numberWithFloat:-64.0f]; // MAGIC HERE
    NSDictionary *views = NSDictionaryOfVariableBindings(sV, self.contentView);
    NSDictionary *metrics = NSDictionaryOfVariableBindings(space, space2);
    NSString *horizontalFormat =@"|-space-[sV]-space2-|";
    NSArray* horizontal = [NSLayoutConstraint constraintsWithVisualFormat:horizontalFormat                                                              options:NSLayoutFormatDirectionLeadingToTrailing
                                                              metrics:metrics
                                                                views:views];
    // height
    NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:sV attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1.0f constant:1.0f];
    // bottom
    NSLayoutConstraint *vertical1 = [NSLayoutConstraint constraintWithItem: sV
                                                             attribute: NSLayoutAttributeBottom
                                                             relatedBy: NSLayoutRelationEqual
                                                                toItem: self.contentView
                                                             attribute: NSLayoutAttributeBottom
                                                            multiplier: 1.0f
                                                              constant: 0.0f
                                 ];
    [self.contentView addConstraints:horizontal];
    [self.contentView addConstraints:@[vertical1,height]];
    self.separatorView = sV; // my own cell's property
}

Code of PCTableViewCellSeparatorView:

#import <UIKit/UIKit.h>
@interface PCTableViewCellSeparatorView : UIView

@end

#import "PCTableViewCellSeparatorView.h"
#import "UIColor+Utilities.h"

@implementation PCTableViewCellSeparatorView

// -----------------------------------------------------------------------
#pragma mark - Drawing
// -----------------------------------------------------------------------
- (void)drawRect:(CGRect)rect
{
    [super drawRect:rect];

    CGFloat inset;
    switch ([UIScreen screenScale]) {
        case ScreenScale2x:
            inset = 0.5f/2.0f;
            break;
        case ScreenScale3x:
            inset = 0.5f/3.0f;
            break;
        default:
            inset = 0.5f;
            break;
    }

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    // draw
    CGContextSetLineWidth(context, inset);
    CGContextSetStrokeColorWithColor(context, [UIColor colorWithRGB:PCColorGrey].CGColor);
    CGContextMoveToPoint(context, 0, CGRectGetHeight(rect)-inset);
    CGContextAddLineToPoint(context, CGRectGetWidth(rect), CGRectGetHeight(rect)-inset);
    CGContextStrokePath(context);
    CGContextRestoreGState(context);
}

@end



来源:https://stackoverflow.com/questions/26884479/draw-custom-separator-line-between-uitableviewcell-on-ios-7

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!