问题
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:
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 withTableView.SeparatorStyle = UITableViewCellSeparatorStyle.None;
. But you have to add events to the createdUIButton
which holds the image becauseAccessoryButtonTapped
will not be called anymore. That are many steps only for adding a separator line.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