在iOS 7上的UITableViewCell之间绘制自定义分隔线

时间:2014-11-12 10:19:03

标签: ios uitableview autolayout nslayoutconstraint

因为我在使用UITableViewCell之间的默认分隔线时遇到了一些麻烦。因此,我使用自动布局。 C#是我使用的语言。您当然可以在Objective-C中提供解决方案。

在我的自定义单元格的构造函数中,我添加了我的视图UIView

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

必须将其添加到超级视图中,否则它不会覆盖附件区域。在updateConstraints我设置了约束:

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

例如,这适用于iOS 8,但不适用于iOS 7.此约束V:[separator(1)]|也适用于iOS 8,但不适用于iOS 7.

2 个答案:

答案 0 :(得分:0)

据我所知,有两种可能性来解决这个问题:

  1. 不使用默认附件视图,而是根本不使用附件视图。而是通过创建附件视图所需的图像(视网膜显示的屏幕截图或使用自定义图像或drawing本身)伪造附件视图。如果您有假配件视图,可以将其添加到contentView并相应地设置约束。 现在,您可以在使用TableView.SeparatorStyle = UITableViewCellSeparatorStyle.None;禁用默认分隔符的同时向内容视图添加一行。但是您必须将事件添加到保存图像的已创建UIButton,因为将不再调用AccessoryButtonTapped。这只是添加分隔线的许多步骤。

  2. 在背景视图中添加分隔线。这是我采取的方法。

  3. 首先使用我的分隔线创建渐变背景视图的GradientView类:

    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);
            }
        }
    

    您不需要两个分隔线,但对于我的选择问题,我需要两个。

    在自定义UITableViewCell中,您可以相应地在初始值设定项中设置背景:

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

    当然你不需要渐变的东西,所以你可以把它留下来。比GradientView仅包含带有少量字段的Draw方法。

答案 1 :(得分:0)

此代码适用于我(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
}

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