114

グループ化されたスタイルの UITableView の背景と境界線の色の両方をカスタマイズしたいと思います。

以下を使用して背景色をカスタマイズできました。

tableView.contentView.backgroundColor = [UIColor greenColor];

しかし、境界線の色はまだ変更方法がわからないものです。

グループ化されたスタイルのテーブル ビューのこれら 2 つの側面をカスタマイズするにはどうすればよいですか?

4

11 に答える 11

100

更新: iPhone OS 3.0以降では、これを非常に簡単UITableViewCellにするbackgroundColorプロパティが追加されました(特に[UIColor colorWithPatternImage:]イニシャライザーとの組み合わせで)。しかし、答えを必要とする人のために、2.0バージョンの答えをここに残しておきます…</ p>


本来あるべきより難しいです。これが私がそれをしなければならなかったときに私がこれをした方法です:

UITableViewCellのbackgroundViewプロパティを、境界線と背景自体を適切な色で描画するカスタムUIViewに設定する必要があります。このビューは、セクションの最初のセルの上部を丸め、セクションの最後のセルの下部を丸め、セクションの中央のセルの角を丸めない、4つの異なるモードで境界線を描画できる必要があります。 、および1つのセルを含むセクションの4つの角すべてが丸められます。

残念ながら、このモードを自動的に設定する方法がわからなかったため、UITableViewDataSourceの-cellForRowAtIndexPathメソッドで設定する必要がありました。

これは本物のPITAですが、Appleのエンジニアに、これが現在唯一の方法であることを確認しました。

更新これがそのカスタムbgビューのコードです。丸みを帯びた角が少しおかしくなる描画バグがありますが、修正する前に別のデザインに移動してカスタム背景を削除しました。それでも、これはおそらくあなたにとって非常に役立つでしょう:

//
//  CustomCellBackgroundView.h
//
//  Created by Mike Akers on 11/21/08.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import <UIKit/UIKit.h>

typedef enum  {
    CustomCellBackgroundViewPositionTop, 
    CustomCellBackgroundViewPositionMiddle, 
    CustomCellBackgroundViewPositionBottom,
    CustomCellBackgroundViewPositionSingle
} CustomCellBackgroundViewPosition;

@interface CustomCellBackgroundView : UIView {
    UIColor *borderColor;
    UIColor *fillColor;
    CustomCellBackgroundViewPosition position;
}

    @property(nonatomic, retain) UIColor *borderColor, *fillColor;
    @property(nonatomic) CustomCellBackgroundViewPosition position;
@end

//
//  CustomCellBackgroundView.m
//
//  Created by Mike Akers on 11/21/08.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import "CustomCellBackgroundView.h"

static void addRoundedRectToPath(CGContextRef context, CGRect rect,
                                 float ovalWidth,float ovalHeight);

@implementation CustomCellBackgroundView
@synthesize borderColor, fillColor, position;

- (BOOL) isOpaque {
    return NO;
}

- (id)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        // Initialization code
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    // Drawing code
    CGContextRef c = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(c, [fillColor CGColor]);
    CGContextSetStrokeColorWithColor(c, [borderColor CGColor]);

    if (position == CustomCellBackgroundViewPositionTop) {
        CGContextFillRect(c, CGRectMake(0.0f, rect.size.height - 10.0f, rect.size.width, 10.0f));
        CGContextBeginPath(c);
        CGContextMoveToPoint(c, 0.0f, rect.size.height - 10.0f);
        CGContextAddLineToPoint(c, 0.0f, rect.size.height);
        CGContextAddLineToPoint(c, rect.size.width, rect.size.height);
        CGContextAddLineToPoint(c, rect.size.width, rect.size.height - 10.0f);
        CGContextStrokePath(c);
        CGContextClipToRect(c, CGRectMake(0.0f, 0.0f, rect.size.width, rect.size.height - 10.0f));
    } else if (position == CustomCellBackgroundViewPositionBottom) {
        CGContextFillRect(c, CGRectMake(0.0f, 0.0f, rect.size.width, 10.0f));
        CGContextBeginPath(c);
        CGContextMoveToPoint(c, 0.0f, 10.0f);
        CGContextAddLineToPoint(c, 0.0f, 0.0f);
        CGContextStrokePath(c);
        CGContextBeginPath(c);
        CGContextMoveToPoint(c, rect.size.width, 0.0f);
        CGContextAddLineToPoint(c, rect.size.width, 10.0f);
        CGContextStrokePath(c);
        CGContextClipToRect(c, CGRectMake(0.0f, 10.0f, rect.size.width, rect.size.height));
    } else if (position == CustomCellBackgroundViewPositionMiddle) {
        CGContextFillRect(c, rect);
        CGContextBeginPath(c);
        CGContextMoveToPoint(c, 0.0f, 0.0f);
        CGContextAddLineToPoint(c, 0.0f, rect.size.height);
        CGContextAddLineToPoint(c, rect.size.width, rect.size.height);
        CGContextAddLineToPoint(c, rect.size.width, 0.0f);
        CGContextStrokePath(c);
        return; // no need to bother drawing rounded corners, so we return
    }

    // At this point the clip rect is set to only draw the appropriate
    // corners, so we fill and stroke a rounded rect taking the entire rect

    CGContextBeginPath(c);
    addRoundedRectToPath(c, rect, 10.0f, 10.0f);
    CGContextFillPath(c);  

    CGContextSetLineWidth(c, 1);  
    CGContextBeginPath(c);
    addRoundedRectToPath(c, rect, 10.0f, 10.0f);  
    CGContextStrokePath(c); 
}


- (void)dealloc {
    [borderColor release];
    [fillColor release];
    [super dealloc];
}


@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
}
于 2008-12-30T19:46:36.033 に答える
34

答えはグループ化されたテーブルセルの変更に関連していることは知っていますが、誰かがテーブルビューの背景色も変更したい場合は、次のようにします。

設定する必要があるだけではありません:

tableview.backgroundColor = color;

また、背景ビューを変更または削除する必要があります。

tableview.backgroundView = nil;  
于 2011-06-30T17:30:08.740 に答える
24

まず、このコードに感謝します。描画のコーナーの問題を取り除くために、この関数にいくつかの描画変更を加えました。

-(void)drawRect:(CGRect)rect 
{
    // Drawing code

    CGContextRef c = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(c, [fillColor CGColor]);
    CGContextSetStrokeColorWithColor(c, [borderColor CGColor]);
    CGContextSetLineWidth(c, 2);

    if (position == CustomCellBackgroundViewPositionTop) {

        CGFloat minx = CGRectGetMinX(rect) , midx = CGRectGetMidX(rect), maxx = CGRectGetMaxX(rect) ;
        CGFloat miny = CGRectGetMinY(rect) , maxy = CGRectGetMaxY(rect) ;
        minx = minx + 1;
        miny = miny + 1;

        maxx = maxx - 1;
        maxy = maxy ;

        CGContextMoveToPoint(c, minx, maxy);
        CGContextAddArcToPoint(c, minx, miny, midx, miny, ROUND_SIZE);
        CGContextAddArcToPoint(c, maxx, miny, maxx, maxy, ROUND_SIZE);
        CGContextAddLineToPoint(c, maxx, maxy);

        // Close the path
        CGContextClosePath(c);
        // Fill & stroke the path
        CGContextDrawPath(c, kCGPathFillStroke);        
        return;
    } else if (position == CustomCellBackgroundViewPositionBottom) {

        CGFloat minx = CGRectGetMinX(rect) , midx = CGRectGetMidX(rect), maxx = CGRectGetMaxX(rect) ;
        CGFloat miny = CGRectGetMinY(rect) , maxy = CGRectGetMaxY(rect) ;
        minx = minx + 1;
        miny = miny ;

        maxx = maxx - 1;
        maxy = maxy - 1;

        CGContextMoveToPoint(c, minx, miny);
        CGContextAddArcToPoint(c, minx, maxy, midx, maxy, ROUND_SIZE);
        CGContextAddArcToPoint(c, maxx, maxy, maxx, miny, ROUND_SIZE);
        CGContextAddLineToPoint(c, maxx, miny);
        // Close the path
        CGContextClosePath(c);
        // Fill & stroke the path
        CGContextDrawPath(c, kCGPathFillStroke);    
        return;
    } else if (position == CustomCellBackgroundViewPositionMiddle) {
        CGFloat minx = CGRectGetMinX(rect) , maxx = CGRectGetMaxX(rect) ;
        CGFloat miny = CGRectGetMinY(rect) , maxy = CGRectGetMaxY(rect) ;
        minx = minx + 1;
        miny = miny ;

        maxx = maxx - 1;
        maxy = maxy ;

        CGContextMoveToPoint(c, minx, miny);
        CGContextAddLineToPoint(c, maxx, miny);
        CGContextAddLineToPoint(c, maxx, maxy);
        CGContextAddLineToPoint(c, minx, maxy);

        CGContextClosePath(c);
        // Fill & stroke the path
        CGContextDrawPath(c, kCGPathFillStroke);    
        return;
    }
}
于 2009-06-23T09:47:08.627 に答える
16

コードをありがとう、それはまさに私が探していたものです。CustomCellBackgroundViewPositionSingle セルのケースを実装するために、Vimal のコードに次のコードも追加しました。(四隅はすべて丸みを帯びています。)


else if (position == CustomCellBackgroundViewPositionSingle)
{
        CGFloat minx = CGRectGetMinX(rect) , midx = CGRectGetMidX(rect), maxx = CGRectGetMaxX(rect) ;
        CGFloat miny = CGRectGetMinY(rect) , midy = CGRectGetMidY(rect) , maxy = CGRectGetMaxY(rect) ;
        minx = minx + 1;
        miny = miny + 1;

        maxx = maxx - 1;
        maxy = maxy - 1;

        CGContextMoveToPoint(c, minx, midy);
        CGContextAddArcToPoint(c, minx, miny, midx, miny, ROUND_SIZE);
        CGContextAddArcToPoint(c, maxx, miny, maxx, midy, ROUND_SIZE);
        CGContextAddArcToPoint(c, maxx, maxy, midx, maxy, ROUND_SIZE);
        CGContextAddArcToPoint(c, minx, maxy, minx, midy, ROUND_SIZE);

        // Close the path
        CGContextClosePath(c);
        // Fill & stroke the path
        CGContextDrawPath(c, kCGPathFillStroke);                
        return;     
}
于 2009-07-18T01:53:37.607 に答える
13

他の人に役立つかもしれないMikeAkersからの上記のCustomCellBackgroundViewコードで私が遭遇した1つのこと:

cell.backgroundViewセルが再利用されたときに自動的に再描画されることはなく、backgroundViewの位置変数を変更しても再利用されたセルには影響しません。つまり、長いテーブルはcell.backgroundViews、その位置を指定すると誤って描画されます。

行が表示されるたびに新しいbackgroundViewを作成せずにこれを修正するには[cell.backgroundView setNeedsDisplay]、の最後でを呼び出します-[UITableViewController tableView:cellForRowAtIndexPath:]。または、より再利用可能なソリューションの場合は、CustomCellBackgroundViewの位置セッターをオーバーライドして。を含めます[self setNeedsDisplay]

于 2009-08-26T18:18:19.607 に答える
12

この非常に役立つ投稿をありがとう。IB の画像/テキスト/その他のコンテンツを介してカスタマイズする代わりに、セルの背景を完全に空の状態にしたい人がいる場合に備えて (私のように!)、ダムの境界線/パディング/を取り除く方法がわかりません。 IBでクリアするように設定してもバックグラウンド...これが私が使用したコードです。


- (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath {

    static NSString *cellId = @"cellId";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: cellId];
    if (cell == nil) {
        [[NSBundle mainBundle] loadNibNamed:@"EditTableViewCell" owner:self options:nil];
        cell = cellIBOutlet;
        self.cellIBOutlet = nil;
    }

    cell.backgroundView = [[[UIView alloc] initWithFrame: CGRectZero] autorelease];
    [cell.backgroundView setNeedsDisplay];

    ... any other cell customizations ...

    return cell;
}

うまくいけば、それは他の誰かを助けるでしょう! 魔法のように機能するようです。

于 2010-08-06T20:18:29.290 に答える
4

設定により、境界線の色をカスタマイズできます

tableView.separatorColor
于 2011-04-11T20:34:43.853 に答える
2

テーブル ビューの境界線の色を変更するには:

時間:

#import <QuartzCore/QuartzCore.h>

.m:

tableView.layer.masksToBounds=YES;
tableView.layer.borderWidth = 1.0f;
tableView.layer.borderColor = [UIColor whiteColor].CGColor;
于 2013-04-11T16:26:41.807 に答える
0

このタスクは、 PrettyKitを使用して約 5 行のコードを追加するだけで簡単に実行できます。nibファイルまたはを使用する場合は、この小さなハックstoryboardを適用することも忘れないでください。このアプローチを使用する場合は、以下からセルをサブクラス化する必要があります。PrettyTableViewCell

#import <PrettyKit/PrettyKit.h>

@class RRSearchHistoryItem;

@interface RRSearchHistoryCell : PrettyTableViewCell

これは私の例ですcellForRowAtIndexPath

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  static NSString *cellIdentifier = @"RRSearchHistoryCell";

  RRSearchHistoryCell *cell = (RRSearchHistoryCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];

  if ( cell == nil ) {

    NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"RRSearchHistoryCell" owner:self options:nil];
    cell = topLevelObjects[0];
    cell.gradientStartColor = RGB(0xffffff);
    cell.gradientEndColor = RGB(0xf3f3f3);

  }

  RRSearchHistoryItem *item = _historyTableData[indexPath.row];
  [cell setHistoryItem:item];


  [cell prepareForTableView:tableView indexPath:indexPath];

  return cell;
}
于 2013-08-20T07:57:34.187 に答える
-5

私はこれに問題を抱えていて、いくつかのセルではうまく機能するが他のセルでは機能しないことに気付いたので、さまざまな組み合わせを試しました。

不思議なことに、cell.backgroundColorをlightGrayColorに設定することが可能であり、すべてが完全に機能することがわかりました。しかし、blueColorにより、外側のエッジが更新されないという問題が発生しました。

緑を使用することが本当に重要でない限り、おそらくこれを試してみることをお勧めします。これは、セルが選択されていることを示すときに、人々が灰色だけを使用できるようにする機能である可能性があります。

于 2009-06-19T07:28:42.190 に答える