【问题标题】:How do I draw a line and a gradient in my table header section viewForHeaderInSection?如何在表格标题部分 viewForHeaderInSection 中绘制线条和渐变?
【发布时间】:2010-11-22 11:57:43
【问题描述】:

我在 UITableView 标题部分添加了一些标题,我想在底部画一条白线,从上到下画一个灰色渐变。

目前在viewForHeaderInSection 我已经为我的标题创建了一个带有标签的视图。我现在正在尝试绘制一条白线,我使用 1 像素高的标签对其进行了管理。

【问题讨论】:

    标签: iphone objective-c xcode uitableview


    【解决方案1】:

    您展示了创建一个 UIVIew 子类,例如 HeaderView,您将在其中画线:

    @implementation HeaderView
    - (void)drawRect:(CGRect)rect 
    {
        [super drawRect:rect];
    
        //add a gradient:
        CAGradientLayer *layer = [[[CAGradientLayer alloc] init] autorelease]
        [gradientLayer setBounds:[self bounds]]
        [gradientLayer setColors:[NSArray arrayWithObjects:(id)[[UIColor blackColor] CGColor], (id)[[UIColor whiteColor] CGColor], nil]];
        [[self layer] insertSublayer:gradientLayer atIndex:0];
    
        //draw line
        CGContextRef ctx = UIGraphicsGetCurrentContext(); 
        CGContextSetRGBStrokeColor(ctx, 1.0, 0, 0, 1); 
        CGContextMoveToPoint(ctx, 0, rect.size.height-1);
        CGContextAddLineToPoint( ctx, rect.size.width, rect.size.height-1);
        CGContextStrokePath(ctx);
    
    
    }
    @end
    

    然后在您的表委托中:

    - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
    {
        // create the parent view that will hold header Label
        HeaderView* customView = [[[HeaderView alloc] initWithFrame:CGRectMake(0.0, 0.0, 360.0, 20.0)] autorelease];
    
        UILabel * headerLabel = [[UILabel alloc] initWithFrame:CGRectZero];
        headerLabel.backgroundColor = [UIColor clearColor];
        headerLabel.frame = CGRectMake(10.0, 0.0, 100.0, 20.0); 
        headerLabel.text = [sectionTitles objectAtIndex:section];
        [customView addSubview:headerLabel];
        [headerLabel release];
    
        return customView;
    

    }

    【讨论】:

    • Romain,请参阅上面的编辑,我对您的代码进行了一些小的颜色更改。但是,渐变是否超出了标题部分区域?而且我无法让这条线变成白色。我添加了一个高度为 1 的标签,这是最后一张图片,所以我知道灰线不是高度 1。
    • CoreGraphics 将始终跨越像素边界绘制,这意味着如果您有一条单像素线,它将在两个像素之间绘制,使其看起来像一条粗大的、粗略的 2 像素线,已褪色。对于您的水平线,您需要将 Y 坐标偏移 0.5,对于垂直线,反之亦然。
    • 我需要进行更正[gradientLayer setFrame:rect]; 并在使用 CrystalSkulls 修复我的底线后,我的线被隐藏在渐变后面。所以我坚持使用我的一个像素标签。一切看起来都不错:)
    • 我必须通过 *gradientLayer 更改第一个 *layer,以及 Jules 所做的更改。
    【解决方案2】:

    我知道这个问题已经得到解答,但我在绘制渐变线时遇到了问题。我想可能还有其他人有同样的问题,所以这就是我解决它的方法。这适用于 iOS 4x

    CustomTableViewSectionHeaderWithLine.h

    #import <UIKit/UIKit.h>
    #import <QuartzCore/QuartzCore.h>
    
    @interface CustomTableViewSectionHeaderWithLine : UIView {
        UIColor *topColor;
        UIColor *bottomColor;
        UIColor *lineColor;
    }
    @property(nonatomic, retain) UIColor *topColor, *bottomColor, *lineColor;
    @end
    

    CustomTableViewSectionHeaderWithLine.m

    #import "CustomTableViewSectionHeaderWithLine.h"
    
    
    @implementation CustomTableViewSectionHeaderWithLine
    @synthesize topColor;
    @synthesize bottomColor;
    @synthesize lineColor;
    
    - (id)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            // Set the colors to something heinous so if you forget you can know immediately
            if ([self topColor] == nil) topColor = [UIColor greenColor];
            if ([self bottomColor] == nil) bottomColor = [UIColor yellowColor];
            if ([self lineColor] == nil) lineColor = [UIColor redColor];        
        }
        return self;
    }
    
    - (void)drawRect:(CGRect)rect 
    {
        //[super drawRect:rect];
    
        //add a gradient:
        CAGradientLayer *gradientLayer = [[[CAGradientLayer alloc] init] autorelease];
        [gradientLayer setBounds:[self bounds]];
        CGRect newRect = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height -1);
        [gradientLayer setFrame:newRect];
        [gradientLayer setColors:[NSArray arrayWithObjects:(id)[topColor CGColor], (id)[bottomColor CGColor], nil]];
        [[self layer] insertSublayer:gradientLayer atIndex:0];
    
        //draw line
        CGContextRef ctx = UIGraphicsGetCurrentContext(); 
        CGContextBeginPath(ctx);
        // This gets the RGB Float values from the color initialized for lineColor
        const float* colors = CGColorGetComponents( lineColor.CGColor );
        CGContextSetRGBStrokeColor(ctx, colors[0], colors[1], colors[2], 1);    
        //CGContextSetGrayStrokeColor(ctx, 0, 1);
        CGContextMoveToPoint(ctx, 0, rect.size.height);
        CGContextAddLineToPoint( ctx, rect.size.width, rect.size.height);
        CGContextStrokePath(ctx);
    }
    
    - (void)dealloc
    {
        [super dealloc];
    }
    
    @end
    

    用法(在你的 TableViewDelegate 中实现这两个方法

    - (UIView *) tableView:(UITableView *) tableView viewForHeaderInSection:(NSInteger)section {
        CustomTableViewSectionHeaderWithLine *customView = [[[CustomTableViewSectionHeaderWithLine alloc] initWithFrame:CGRectMake(0.0, 0.0, 360.0, 25.0)] autorelease];
        [customView setTopColor:[UIColor whiteColor]];
        [customView setBottomColor:[UIColor blackColor]];
        [customView setLineColor:[UIColor whiteColor]];
    
        UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(10, 3, tableView.bounds.size.width - 10, 18)] autorelease];
        label.text = [tableView.dataSource tableView:tableView titleForHeaderInSection:section];
        label.textColor = [UIColor blackColor];
        label.backgroundColor = [UIColor clearColor];
        [customView addSubview:label];
    
        return customView;
    }
    
    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
        return 25;
    }
    

    【讨论】:

      【解决方案3】:

      不想子类化视图(UILabel/UIButton)等的人...

      -(void) drawUnderlinedLabel {
          NSString *string = [forgetButton titleForState: UIControlStateNormal];
          CGSize stringSize = [string sizeWithFont: forgetButton.titleLabel.font];
          CGRect buttonFrame = forgetButton.frame;
          CGRect labelFrame = CGRectMake(buttonFrame.origin.x + buttonFrame.size.width - stringSize.width, buttonFrame.origin.y + stringSize.height + 1 , stringSize.width, 2);
          UILabel *lineLabel = [[UILabel alloc] initWithFrame: labelFrame];
          lineLabel.backgroundColor = [UIColor blackColor];
          //[forgetButton addSubview:lineLabel];
          [self.view addSubview: lineLabel];
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-07
        • 1970-01-01
        相关资源
        最近更新 更多