2011-07-19 87 views
139

我正在實現一個顏色選擇器表格視圖,用戶可以在其中選擇10種顏色(取決於產品)。用戶也可以選擇其他選項(如硬盤容量,...)。當選擇單元格時,UITableViewCell子視圖消失

所有顏色選項都在它們自己的tableview部分中。

我想在textLabel的左側顯示一個小正方形,顯示實際的顏色。

現在我加入了簡單的方形的UIView,給它正確的背景顏色,就像這樣:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:RMProductAttributesCellID]; 
    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:RMProductAttributesCellID] autorelease]; 
     cell.indentationWidth = 44 - 8; 

     UIView *colorThumb = [[[UIView alloc] initWithFrame:CGRectMake(8, 8, 28, 28)] autorelease]; 
     colorThumb.tag = RMProductAttributesCellColorThumbTag; 
     colorThumb.hidden = YES; 
     [cell.contentView addSubview:colorThumb]; 
    } 

    RMProductAttribute *attr = (RMProductAttribute *)[_product.attributes objectAtIndex:indexPath.section]; 
    RMProductAttributeValue *value = (RMProductAttributeValue *)[attr.values objectAtIndex:indexPath.row]; 
    cell.textLabel.text = value.name; 
    cell.textLabel.backgroundColor = [UIColor clearColor]; 

    UIView *colorThumb = [cell viewWithTag:RMProductAttributesCellColorThumbTag]; 
    colorThumb.hidden = !attr.isColor; 
    cell.indentationLevel = (attr.isColor ? 1 : 0); 

    if (attr.isColor) { 
     colorThumb.layer.cornerRadius = 6.0; 
     colorThumb.backgroundColor = value.color; 
    } 

    [self updateCell:cell atIndexPath:indexPath]; 

    return cell; 
} 

這顯示沒有問題的罰款。

我唯一的問題是,當我選擇一個「顏色」行,在漸變到藍色選擇動畫期間,我的自定義UIView(colorThumb)被隱藏。它在選擇/取消選擇動畫結束後再次可見,但是這會產生一個醜陋的工件。

我該怎麼做才能糾正這個問題?不要在正確的地方插入子視圖?

(沒有什麼特別的didSelectRowAtIndexPath,我只是將單元格的附件更改爲複選框或沒有任何內容,並取消選擇當前的indexPath)。

+0

什麼upadteCell一回事呢? – Idan

+0

updateCell會進行一些微小的調整,如設置選中標記或不選中,根據可用性選擇文本顏色,但不會涉及單元格本身或colorThumb。 – Cyrille

+0

接受的答案不提供解決方案,請參閱我的答案以下解答 –

回答

162

UITableViewCell當單元格被選中或突出顯示時更改所有子視圖的背景顏色,您可以通過覆蓋Tableview單元格的setSelected:animatedsetHighlighted:animated並重置視圖背景顏色來解決此問題。

在Objective C:

- (void)setSelected:(BOOL)selected animated:(BOOL)animated { 
    UIColor *color = self.yourView.backgroundColor;   
    [super setSelected:selected animated:animated]; 

    if (selected){ 
     self.yourView.backgroundColor = color; 
    } 
} 

-(void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated{ 
    UIColor *color = self.yourView.backgroundColor;   
    [super setHighlighted:highlighted animated:animated]; 

    if (highlighted){ 
     self.yourView.backgroundColor = color; 
    } 
} 

在夫特3。1:

override func setSelected(_ selected: Bool, animated: Bool) { 
    let color = yourView.backgroundColor   
    super.setSelected(selected, animated: animated) 

    if selected { 
     yourView.backgroundColor = color 
    } 
} 

override func setHighlighted(_ highlighted: Bool, animated: Bool) { 
    let color = yourView.backgroundColor 
    super.setHighlighted(highlighted, animated: animated) 

    if highlighted { 
     yourView.backgroundColor = color 
    } 
} 
+1

這應該是答案。 –

+0

我們是否需要'if(突出顯示)'和'if(selected)'條件?如果我們沒有這些條件,我認爲它會起作用。 –

+0

@Cyrille這個行爲應該被接受爲最佳解決方案。 – arts777

120

這是因爲表格視圖單元格會自動更改內容視圖中所有視圖的背景色以突出顯示狀態。您可以考慮繼承UIView以繪製顏色或使用UIImageView自定義1x1像素拉伸圖像。

+1

啞我。當然就是這樣,子視圖必須是透明的,以便選擇動畫可以正確地發生。謝謝! – Cyrille

+49

或者你可以重新設置背景顏色覆蓋'setHighlighted:animated:'和'setSelected:animated:' – pt2ph8

+0

謝謝你們,我遇到了同樣的問題,真的有所幫助。 – ratsimihah

9

另一種方式來管理問題,以填補核心圖形漸變的觀點,如:

CAGradientLayer* gr = [CAGradientLayer layer]; 
gr.frame = mySubview.frame; 
gr.colors = [NSArray arrayWithObjects: 
        (id)[[UIColor colorWithRed:0 green:0 blue:0 alpha:.5] CGColor] 
        ,(id)[[UIColor colorWithRed:0 green:0 blue:0 alpha:.5] CGColor] 
        , nil]; 

gr.locations = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0],[NSNumber numberWithFloat:1],nil]; 

[mySubview.layer insertSublayer:gr atIndex:0]; 
+0

+1,因爲這是我最近一直在做的事情。 – Cyrille

+0

嗯,我正在嘗試這個確切的代碼,它對我沒有任何影響。我的子視圖是一個UILabel作爲cell.contentView的子視圖添加,並在iOS 6.0.1下進行測試,以防萬一。 –

+0

你對上面的代碼應用了什麼?你有沒有嘗試將標籤添加到單元格視圖? – Agat

3

的UITableViewCell上選擇改變的backgroundColor所有子視圖出於某種原因。

這可能幫助:

DVColorLockView

使用類似的東西,從選取過程中更改您的視圖顏色停止的UITableView。

0

這裏是我的解決方案,使用內容查看顯示selectionColor設置,它的工作完美

#import "BaseCell.h" 

@interface BaseCell() 
@property (nonatomic, strong) UIColor *color_normal; 
@property (nonatomic, assign) BOOL needShowSelection; 
@end 


@implementation BaseCell 
@synthesize color_customSelection; 
@synthesize color_normal; 
@synthesize needShowSelection; 

- (void)awakeFromNib 
{ 
    [super awakeFromNib]; 
    [self setup]; 
} 

- (void)setup 
{ 
    //save normal contentView.backgroundColor 
    self.color_normal = self.backgroundColor; 
    if (self.color_normal == nil) { 
     self.color_normal = [UIColor colorWithRGBHex:0xfafafa]; 
    } 
    self.color_customSelection = [UIColor colorWithRGBHex:0xF1F1F1]; 
    self.accessoryView.backgroundColor = [UIColor clearColor]; 
    if (self.selectionStyle == UITableViewCellSelectionStyleNone) { 
     needShowSelection = NO; 
    } 
    else { 
     //cancel the default selection 
     needShowSelection = YES; 
     self.selectionStyle = UITableViewCellSelectionStyleNone; 
    } 
} 

/* 
solution is here 
*/ 
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    [super touchesBegan:touches withEvent:event]; 
    if (needShowSelection) { 
     self.contentView.backgroundColor = self.backgroundColor = color_customSelection; 
    } 
} 

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    [super touchesCancelled:touches withEvent:event]; 
    if (needShowSelection) { 
     self.contentView.backgroundColor = self.backgroundColor = color_normal; 
    } 
} 

- (void)setSelected:(BOOL)selected animated:(BOOL)animated 
{ 
    [super setSelected:selected animated:animated]; 
    if (needShowSelection) { 
     UIColor *color = selected ? color_customSelection:color_normal; 
     self.contentView.backgroundColor = self.backgroundColor = color; 
    } 
} 
3

通過 Yatheesha B Lanswer 我創建一個UITableViewCell類/擴展,可以讓你的啓發打開和關閉此透明度「功能」。

夫特

let cell = <Initialize Cell> 
cell.keepSubviewBackground = true // Turn transparency "feature" off 
cell.keepSubviewBackground = false // Leave transparency "feature" on 

目標C

UITableViewCell* cell = <Initialize Cell> 
cell.keepSubviewBackground = YES; // Turn transparency "feature" off 
cell.keepSubviewBackground = NO; // Leave transparency "feature" on 

KeepBackgroundCell是的CocoaPods兼容。你可以找到它on GitHub

+0

流利地爲我工作! –

6

您可以cell.selectionStyle = UITableViewCellSelectionStyleNone;, 然後設置的backgroundColor在- (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath

22

找到一個漂亮優雅的解決方案,而不是與tableViewCell選擇搞亂/高亮方法。您可以創建UIView的子類,忽略設置其背景顏色以清除顏色。

夫特3/4:

class NeverClearView: UIView { 
    override var backgroundColor: UIColor? { 
     didSet { 
      if backgroundColor != nil && backgroundColor!.cgColor.alpha == 0 { 
       backgroundColor = oldValue 
      } 
     } 
    } 
} 

夫特2:

class NeverClearView: UIView { 
    override var backgroundColor: UIColor? { 
     didSet { 
      if CGColorGetAlpha(backgroundColor!.CGColor) != 0 { 
       backgroundColor = oldValue 
      } 
     } 
    } 
} 

的OBJ-C版本:

@interface NeverClearView : UIView 

@end 

@implementation NeverClearView 

- (void)setBackgroundColor:(UIColor *)backgroundColor { 
    if (CGColorGetAlpha(backgroundColor.CGColor) != 0) { 
     [super setBackgroundColor:backgroundColor]; 
    } 
} 

@end 
+0

這很可愛。如果您有一些可重複使用的視圖,如「徽章」或「標籤」,應該永遠不會有清晰的背景,那麼最容易找到最佳解決方案。 :: rant ::多麼混亂的解決方案@UIKit,當你做一個單元格選擇時,將所有子視圖設置爲透明。至少限制爲單元格的全高或寬度的子視圖或N個深度的子視圖。 – SimplGy

+0

@SimplGy突出顯示的深度確實是一個很好的選擇,但嘿 - 這是UIKit,我看到的事情比這更糟糕=) –

+3

在我更改if後改爲CGColorGetAlpha(backgroundColor!.CGColor)= = 0,因爲它不等於clearColor – piltdownman7

1

繪製,而不是設置背景顏色的視圖

import UIKit 

class CustomView: UIView { 

    var fillColor:UIColor! 

    convenience init(fillColor:UIColor!) { 
     self.init() 
     self.fillColor = fillColor 
    } 

    override func drawRect(rect: CGRect) { 
     if let fillColor = fillColor { 
      let context = UIGraphicsGetCurrentContext() 
      CGContextSetFillColorWithColor(context, fillColor.CGColor); 
      CGContextFillRect (context, self.bounds); 

     } 
    } 


} 
6

對於雨燕2.2這個作品

cell.selectionStyle = UITableViewCellSelectionStyle.None 

和理性是由@Andriy

解釋說這是因爲表視圖單元格自動改變的 高亮顯示狀態的內容視圖中的所有視圖的背景顏色。

+1

短而簡單,工作就像一個魅力。謝謝:) –

+1

簡單而完美的工作 –

0

嘗試下面的代碼:

-(void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated 
{  
[super setHighlighted:highlighted animated:animated]; 
//Set your View's Color here. 
} 
0

基於保羅·古羅夫的答案我實現了在Xamarin.iOS以下。 C#版本:

NeverClearView.cs

public partial class NeverClearView : UIView 
{ 
    public NeverClearView(IntPtr handle) : base(handle) 
    { 
    } 

    public override UIColor BackgroundColor 
    { 
     get 
     { 
      return base.BackgroundColor; 
     } 
     set 
     { 
      if (value.CGColor.Alpha == 0) return; 

      base.BackgroundColor = value; 
     } 
    } 
} 

NeverClearView.designer。CS

[Register("NeverClearView")] 
partial class NeverClearView 
{ 
    void ReleaseDesignerOutlets() 
    { 
    } 
} 
0

不要忘了覆蓋setSelected以及setHighlighted

override func setHighlighted(highlighted: Bool, animated: Bool) { 

    super.setHighlighted(highlighted, animated: animated) 
    someView.backgroundColor = .myColour() 
} 

override func setSelected(selected: Bool, animated: Bool) { 

    super.setSelected(selected, animated: animated) 
    someView.backgroundColor = .myColour() 
} 
0

將此代碼放在您的UITableViewCell

子斯威夫特3語法

override func setSelected(_ selected: Bool, animated: Bool) { 
    super.setSelected(selected, animated: animated) 

    if(selected) { 
     lockerSmall.backgroundColor = UIColor.init(red: 233/255, green: 106/255, blue: 49/255, alpha: 1.0) 
    } 
} 


override func setHighlighted(_ highlighted: Bool, animated: Bool) { 
    super.setHighlighted(highlighted, animated: animated) 

    if(highlighted) { 
     lockerSmall.backgroundColor = UIColor.init(red: 233/255, green: 106/255, blue: 49/255, alpha: 1.0) 
    } 
} 
0

T他與Pavel Gurov的答案類似,但更靈活,因爲它允許任何顏色永久。

class PermanentBackgroundColorView: UIView { 
    var permanentBackgroundColor: UIColor? { 
     didSet { 
      backgroundColor = permanentBackgroundColor 
     } 
    } 

    override var backgroundColor: UIColor? { 
     didSet { 
      if backgroundColor != permanentBackgroundColor { 
       backgroundColor = permanentBackgroundColor 
      } 
     } 
    } 
} 
0

如果您使用的是故事板,請添加其他解決方案。創建一個UIView的子類,它不允許backgroundColor在初始設置之後進行設置。

@interface ConstBackgroundColorView : UIView 

@end 

@implementation ConstBackgroundColorView 

- (void)setBackgroundColor:(UIColor *)backgroundColor { 
    if (nil == self.backgroundColor) { 
     [super setBackgroundColor:backgroundColor]; 
    } 
} 

@end 
0

如果上述背景溶液不修理你的問題,您的問題可能在於你的datasource您的tableView。

對於我來說,我創建一個數據源對象(稱爲BoxDataSource)的一個實例來處理的委託和數據源的tableView方法,像這樣:

//In cellForRowAtIndexPath, when setting up cell 
let dataSource = BoxDataSource(delegate: self) 
cell.tableView.dataSource = dataSource 
return cell 

這是導致數據源被釋放每當細胞被竊聽,因此所有的內容都消失了。原因是,ARC釋放/垃圾收集的性質。

爲了解決這個問題,我不得不去到自定義單元格,添加一個數據源變量:

//CustomCell.swift 
var dataSource: BoxDataSource? 

然後,你需要設置的數據源var你只是在cellForRow創建的單元格的數據源,所以這未與ARC重新分配。

cell.statusDataSource = BoxAssigneeStatusDataSource(delegate: self) 
cell.detailsTableView.dataSource = cell.statusDataSource 
return cell 

希望有所幫助。

2

Yatheesha B L的回答啓發。

如果您調用super.setSelected(選定,動畫:動畫),它將清除您設置的所有背景色。所以,我們不會調用超級方法。

在斯威夫特:

override func setSelected(selected: Bool, animated: Bool) {  
    if(selected) { 
     contentView.backgroundColor = UIColor.red 
    } else { 
     contentView.backgroundColor = UIColor.white 
    } 
} 

override func setHighlighted(highlighted: Bool, animated: Bool) { 
    if(highlighted) { 
     contentView.backgroundColor = UIColor.red 
    } else { 
     contentView.backgroundColor = UIColor.white 
    } 
} 
+0

感謝您的解決方案。 +1 重寫ishiglighted變量和sethighlighted方法是不同的事情。正確的答案是重寫該方法。 –

0

我想保持不同的是,我想忽略自動背景色改變一個單元子視圖的默認選擇行爲。但我還需要能夠在其他時間更改背景顏色。

我想出的解決方案是子類UIView,所以它忽略了正常設置背景顏色並添加一個單獨的函數來繞過保護。

斯威夫特4

class MyLockableColorView: UIView { 
    func backgroundColorOverride(_ color: UIColor?) { 
      super.backgroundColor = color 
    } 

    override var backgroundColor: UIColor? { 
     set { 
      return 
     } 
     get { 
      return super.backgroundColor 
     } 
    } 
} 
相關問題