【问题标题】:Putting gradient on tableview cells background在表格视图单元格背景上放置渐变
【发布时间】:2010-11-19 18:51:41
【问题描述】:

我一直在尝试通过多种方式为我的表格视图单元格背景添加渐变,但似乎都没有效果。我一直在尝试用石英核心图形的东西来绘制它,将背景插座放在 IB 上的不同视图中,将 imageview 放在后面,并带有代码。似乎没有人以某种方式出现在背面,我不明白出了什么问题。需要的我可以详细说明,谢谢!

【问题讨论】:

    标签: objective-c cocoa-touch ios uitableview core-graphics


    【解决方案1】:

    我在this question 中找到了一些代码,并对其进行了修改以适用于我的应用程序。它适用于普通表和分组表。

    //
    //  UAGradientCellBackgroundLayer.h
    //
    
    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
    
    #import <QuartzCore/QuartzCore.h>
    
    @class UAGradientCellBackgroundView;
    
    @interface UAGradientCellBackgroundLayer : CAGradientLayer {
        CGFloat     *colorComponents;
        BOOL        _override;
    }
    
    @property(nonatomic,assign) BOOL override;
    
    - (void)setColorComponents:(CGFloat *)components;
    
    @end
    
    //
    //  UAGradientCellBackgroundLayer.m
    //
    
    #import "UAGradientCellBackgroundLayer.h"
    #import "UAGradientCellBackgroundView.h"
    
    #define TABLE_CELL_BACKGROUND                                   {1, 1, 1, 1, 204/255.0, 204/255.0, 204/255.0, 1}        // #FFFFFF and #DDDDDD
    
    @implementation UAGradientCellBackgroundLayer
    
    @synthesize override = _override;
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    - (id)init { 
        if ((self = [super init])) {
            colorComponents = NSZoneMalloc(NSDefaultMallocZone(), 8*sizeof(CGFloat));
            CGFloat c[8] = TABLE_CELL_BACKGROUND;
            for (int i = 0; i < 8; i++) {
                colorComponents[i] = c[i];
            }
            // self.cornerRadius = 10;
            // self.backgroundColor = [UIColor clearColor].CGColor;
        }
        return self;
    }
    
    - (void) dealloc {
        NSZoneFree(NSDefaultMallocZone(), colorComponents);
        [super dealloc];
    }
    - (void)display {
        if (_override) {
            self.colors =
            [NSArray arrayWithObjects:
             (id)[UIColor colorWithRed:colorComponents[0] green:colorComponents[1] blue:colorComponents[2] alpha:colorComponents[3]].CGColor,
             (id)[UIColor colorWithRed:colorComponents[4] green:colorComponents[5] blue:colorComponents[6] alpha:colorComponents[7]].CGColor,
             nil];
        } else {
            self.colors =
            [NSArray arrayWithObjects:
             (id)[UIColor clearColor].CGColor,
             (id)[UIColor clearColor].CGColor,
             nil];
        }
        [super display];
    }
    
    - (void)setColorComponents:(CGFloat *)components {
        for (int i = 0; i < 8; i++) {
            colorComponents[i] = components[i];
        }
    }
    
    @end 
    
    //
    //  UAGradientCellBackgroundView.h
    //
    
    #import <Foundation/Foundation.h>
    
    #import <UIKit/UIKit.h>
    
    typedef enum  {
        UAGradientCellBackgroundViewPositionMiddle = 0,
        UAGradientCellBackgroundViewPositionTop,
        UAGradientCellBackgroundViewPositionBottom,
        UAGradientCellBackgroundViewPositionSingle,
        UAGradientCellBackgroundViewPositionPlain
    } UAGradientCellBackgroundViewPosition;
    
    @interface UAGradientCellBackgroundView : UIView {
        UAGradientCellBackgroundViewPosition position;
        CGFloat colors[8];
    }
    
    @property(nonatomic, assign) UAGradientCellBackgroundViewPosition position;
    
    - (void)setColors:(CGFloat[8])comps;
    
    @end
    
    //
    //  UAGradientCellBackgroundView.m
    //
    
    #import "UAGradientCellBackgroundView.h"
    #import "UAGradientCellBackgroundLayer.h"
    #import <QuartzCore/QuartzCore.h>
    
    #define kDefaultMargin                                          10
    #define TABLE_CELL_BACKGROUND                                   {1, 1, 1, 1, 204/255.0, 204/255.0, 204/255.0, 1}        // #FFFFFF and #DDDDDD
    
    static void addRoundedRectToPath(CGContextRef context, CGRect rect,
                                     float ovalWidth,float ovalHeight);
    
    @implementation UAGradientCellBackgroundView
    
    @synthesize position;
    
    //////////////////////////////////////////////////////////////////////
    // PLAIN CELL
    //
    // layerClass
    //
    // returns a CAGradientLayer class as the default layer class for this view
    //
    + (Class)layerClass {
        return [UAGradientCellBackgroundLayer class];
    }
    
    //////////////////////////////////////////////////////////////////////
    - (void)updateLayer {
        UAGradientCellBackgroundLayer* layer = (UAGradientCellBackgroundLayer*)self.layer;
            // This is dramatically faster than calling drawRect.
        [layer setColorComponents:colors];
        layer.override = (self.position == UAGradientCellBackgroundViewPositionPlain);
        [layer setNeedsDisplay];
    }
    
    ////////////////////////////////////////////////////////////////////
    // GROUPED CELL
    - (void)setColors:(CGFloat[8])comps {
        for (int i = 0; i < 8; i++) {
            colors[i] = comps[i];
        }
    }
    
    - (BOOL)isOpaque {
        return YES;
    }
    
    - (id)initWithFrame:(CGRect)frame {
        self = [super initWithFrame:frame];
        if (self != nil) {
            CGFloat comps[8] = TABLE_CELL_BACKGROUND;
            [self setColors:comps];
        }
        return self;
    }
    
    - (void)debugView:(UIView *)view {
        NSLog(@"%@ - %@", view.backgroundColor, [[view class] description]);
        for (UIView* child in view.subviews) {
            [self debugView:child];
        }
    }
    
    -(void)drawRect:(CGRect)aRect {
        [super drawRect:aRect];
        // Drawing code
        if (position == UAGradientCellBackgroundViewPositionPlain) {
            return;
        }
    
        CGContextRef c = UIGraphicsGetCurrentContext(); 
    
        // TODO - Dirty, Dirty hack to fix the background black corners on pop issue. doesnt handle rotation.
    //  CGContextSetFillColorWithColor(c, [UAColor offsetPinstripesColor].CGColor);
    //  CGContextFillRect(c, aRect);
    
        int lineWidth = 1;
    
        CGRect rect = [self bounds];
        rect.size.width -= lineWidth;
        rect.size.height -= lineWidth;
        rect.origin.x += lineWidth / 2.0;
        rect.origin.y += lineWidth / 2.0;
    
        CGFloat minx = CGRectGetMinX(rect), midx = CGRectGetMidX(rect), maxx = CGRectGetMaxX(rect);
        CGFloat miny = CGRectGetMinY(rect), midy = CGRectGetMidY(rect), maxy = CGRectGetMaxY(rect);
        miny -= 1;
    
        CGFloat locations[2] = { 0.0, 1.0 };    
        CGColorSpaceRef myColorspace = CGColorSpaceCreateDeviceRGB();
        CGGradientRef myGradient = nil;
    
        CGContextSetStrokeColorWithColor(c, [UIColor darkGrayColor].CGColor);
        CGContextSetLineWidth(c, lineWidth);
        CGContextSetAllowsAntialiasing(c, YES);
        CGContextSetShouldAntialias(c, YES);
    
        if (position == UAGradientCellBackgroundViewPositionTop) {
            miny += 1;
    
            CGMutablePathRef path = CGPathCreateMutable();
            CGPathMoveToPoint(path, NULL, minx, maxy);
            CGPathAddArcToPoint(path, NULL, minx, miny, midx, miny, kDefaultMargin);
            CGPathAddArcToPoint(path, NULL, maxx, miny, maxx, maxy, kDefaultMargin);
            CGPathAddLineToPoint(path, NULL, maxx, maxy);
            CGPathAddLineToPoint(path, NULL, minx, maxy);
            CGPathCloseSubpath(path);
    
            // Fill and stroke the path
            CGContextSaveGState(c);
            CGContextAddPath(c, path);
            CGContextClip(c);
    
            myGradient = CGGradientCreateWithColorComponents(myColorspace, colors, locations, 2);
            CGContextDrawLinearGradient(c, myGradient, CGPointMake(minx,miny), CGPointMake(minx,maxy), 0);
    
            CGContextAddPath(c, path);
            CGPathRelease(path);
            CGContextStrokePath(c);
            CGContextRestoreGState(c);
    
        } else if (position == UAGradientCellBackgroundViewPositionBottom) {
            //maxy -= 1; // -1 for the shadow 
    
            CGMutablePathRef path = CGPathCreateMutable();
            CGPathMoveToPoint(path, NULL, minx, miny);
            CGPathAddArcToPoint(path, NULL, minx, maxy, midx, maxy, kDefaultMargin);
            CGPathAddArcToPoint(path, NULL, maxx, maxy, maxx, miny, kDefaultMargin);
            CGPathAddLineToPoint(path, NULL, maxx, miny);
            CGPathAddLineToPoint(path, NULL, minx, miny);
            CGPathCloseSubpath(path);
    
            // Fill and stroke the path
            CGContextSaveGState(c);
            CGContextAddPath(c, path);
            CGContextClip(c);
    
            myGradient = CGGradientCreateWithColorComponents(myColorspace, colors, locations, 2);
            CGContextDrawLinearGradient(c, myGradient, CGPointMake(minx,miny), CGPointMake(minx,maxy), 0);
    
            CGContextAddPath(c, path);
            CGPathRelease(path);
            CGContextStrokePath(c);
            CGContextRestoreGState(c);
    
    
        } else if (position == UAGradientCellBackgroundViewPositionMiddle) {
    
            CGMutablePathRef path = CGPathCreateMutable();
            CGPathMoveToPoint(path, NULL, minx, miny);
            CGPathAddLineToPoint(path, NULL, maxx, miny);
            CGPathAddLineToPoint(path, NULL, maxx, maxy);
            CGPathAddLineToPoint(path, NULL, minx, maxy);
            CGPathAddLineToPoint(path, NULL, minx, miny);
            CGPathCloseSubpath(path);
    
            // Fill and stroke the path
            CGContextSaveGState(c);
            CGContextAddPath(c, path);
            CGContextClip(c);
    
            myGradient = CGGradientCreateWithColorComponents(myColorspace, colors, locations, 2);
            CGContextDrawLinearGradient(c, myGradient, CGPointMake(minx,miny), CGPointMake(minx,maxy), 0);
    
            CGContextAddPath(c, path);
            CGPathRelease(path);
            CGContextStrokePath(c);
            CGContextRestoreGState(c);
    
        } else if (position == UAGradientCellBackgroundViewPositionSingle) {
            miny += 1;
            //maxy -= 1; // -1 for the shadow 
    
            CGMutablePathRef path = CGPathCreateMutable();
            CGPathMoveToPoint(path, NULL, minx, midy);
            CGPathAddArcToPoint(path, NULL, minx, miny, midx, miny, kDefaultMargin);
            CGPathAddArcToPoint(path, NULL, maxx, miny, maxx, midy, kDefaultMargin);
            CGPathAddArcToPoint(path, NULL, maxx, maxy, midx, maxy, kDefaultMargin);
            CGPathAddArcToPoint(path, NULL, minx, maxy, minx, midy, kDefaultMargin);
            CGPathCloseSubpath(path);
    
            // Shadow
    //      CGContextAddPath(c, path);
    //      CGContextSaveGState(c);
    //      CGContextSetShadow(c, CGSizeMake(0, -1), 1);
    //      CGContextFillPath(c);
    
            // Fill and stroke the path
            CGContextSaveGState(c);
            CGContextAddPath(c, path);
            CGContextClip(c);
    
    
            myGradient = CGGradientCreateWithColorComponents(myColorspace, colors, locations, 2);
            CGContextDrawLinearGradient(c, myGradient, CGPointMake(minx,miny), CGPointMake(minx,maxy), 0);
    
            CGContextAddPath(c, path);
            CGPathRelease(path);
            CGContextStrokePath(c);
            CGContextRestoreGState(c);
    
        }
        CGColorSpaceRelease(myColorspace);
        CGGradientRelease(myGradient);
        return;
    }
    
    - (void)setPosition:(UAGradientCellBackgroundViewPosition)newPosition {
        if (position != newPosition) {
            position = newPosition;
            [self updateLayer];
        }
    }
    
    @end
    
    static void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth,float ovalHeight) {
        float fw, fh;
    
        if (ovalWidth == 0 || ovalHeight == 0) {// 1
            CGContextAddRect(context, rect);
            return;
        }
    
        CGContextSaveGState(context);// 2
    
        CGContextTranslateCTM (context, CGRectGetMinX(rect),// 3
                               CGRectGetMinY(rect));
        CGContextScaleCTM (context, ovalWidth, ovalHeight);// 4
        fw = CGRectGetWidth (rect) / ovalWidth;// 5
        fh = CGRectGetHeight (rect) / ovalHeight;// 6
    
        CGContextMoveToPoint(context, fw, fh/2); // 7
        CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1);// 8
        CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1);// 9
        CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1);// 10
        CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1); // 11
        CGContextClosePath(context);// 12
    
        CGContextRestoreGState(context);// 13
    } 
    

    使用示例(普通表):

    #import "UAGradientCellBackgroundView.h" 
    CGFloat COLORS[8] = { 0.0/255, 0.0/255, 255.0/255, 1.0, 0.0/255, 0.0/255, 0.0/255, 1.0 }
    ...
    
    - (UITableViewCell *)tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
        NSString *cellID = @"CellID";
    
        // create cell
        UITableViewCell *cell = (UITableViewCell *)[table dequeueReusableCellWithIdentifier:cellID];
        if (cell == nil) {
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID] autorelease];
    
            UAGradientCellBackgroundView *bgView = [[[UAGradientCellBackgroundView alloc] initWithFrame:CGRectZero] autorelease];
            [bgView setBackgroundColor:[UIColor clearColor]];
            [bgView setColors:COLORS];
            [bgView setPosition:UAGradientCellBackgroundViewPositionPlain];
            cell.selectedBackgroundView = bgView;
            cell.textLabel.backgroundColor = [UIColor clearColor];
    
            cell.imageView.image = [UIImage imageNamed:@"cellimg.png"];
        }
    
        cell.textLabel.text = @"Text";
        return cell; 
    }
    

    【讨论】:

    • 如果我尝试将其设置为背景视图,它只会使单元格分隔符变暗,我不明白为什么它不能用作背景视图,但它可以用作选定视图?
    • 嗯...将selectedBackgroundView 更改为backgroundView 对我来说效果很好,您的代码中可能存在其他问题,或者您对粘贴的代码进行了其他更改。也许您正在为单元格设置背景颜色和背景视图?或者您有几种类型的具有不同梯度的单元格并且您没有使用不同的单元格 ID? -- 这只是我在某个时候遇到的两个问题。
    猜你喜欢
    • 2022-09-29
    • 1970-01-01
    • 2014-10-22
    • 1970-01-01
    • 2010-10-28
    • 1970-01-01
    • 2017-05-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多