सेल चयनित होने पर UITableViewCell सबव्यू गायब हो जाता है


178

मैं एक रंग-चयनकर्ता तालिका दृश्य लागू कर रहा हूं जहां उपयोगकर्ता 10 रंगों (उत्पाद पर निर्भर करता है) के बीच चयन कर सकता है। उपयोगकर्ता अन्य विकल्पों (जैसे हार्ड ड्राइव की क्षमता, ...) का भी चयन कर सकता है।

सभी रंग विकल्प अपने स्वयं के टेबलव्यू अनुभाग के अंदर हैं।

मैं टेक्स्टलेब के बाईं ओर एक छोटा वर्ग प्रदर्शित करना चाहता हूं जो वास्तविक रंग दिखा रहा है।

अभी मैं एक साधारण वर्ग 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 में कुछ खास नहीं है, मैं सिर्फ सेल के एक्सेसरी को चेकबॉक्स या कुछ भी नहीं बदलता हूं, और वर्तमान इंडेक्सपैथ को अचयनित करता हूं)।


क्या सभी के बारे में upadteCell है?
इदन

updateCell कुछ मामूली बदलाव करता है जैसे कि चेकमार्क सेट करना या न करना, उपलब्धता के आधार पर टेक्स्ट का रंग चुनना, ... लेकिन सेल से संबंधित कोई वास्तविक परिवर्तन या colorThumb नहीं।
साइरिल

स्वीकृत उत्तर समाधान प्रदान नहीं करता है, समाधान के लिए मेरा जवाब नीचे देखें
पावेल गुआरोव

जवाबों:


227

UITableViewCellसेल चयनित या हाइलाइट होने पर सभी उप-दृश्यों के पृष्ठभूमि का रंग बदल जाता है, आप टेबलव्यू सेल setSelected:animatedऔर setHighlighted:animatedऔर दृश्य पृष्ठभूमि के रंग को रीसेट करके इस समस्या को हल कर सकते हैं ।

उद्देश्य सी में:

- (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
    }
}

क्या हमें if (highlighted)और if (selected)शर्तों की आवश्यकता है ? मुझे लगता है कि अगर हमारे पास वे स्थितियां नहीं हैं तो यह काम करेगा।
ऋषभ तायल

@ ऋषभतयाल मूल रूप से एक ही मान के साथ चर को ओवरराइड करने से बचने के लिए है
कैमलोपर

1
ध्यान रखें कि जब आप आइटम का चयन करते समय पृष्ठभूमि का रंग बदलते हैं, तो आइटम के अचयनित होने पर पुराने (गलत) रंग को पुनर्स्थापित किया जा सकता है। यदि ऐसा हो सकता है, तो (यदि हाइलाइट किया गया है) और यदि (चयनित) शर्तों को हटा दें।
मार्सेल डब्ल्यू

यह दृष्टिकोण एनीमेशन को रद्द कर देता है, इसलिए इसका कोई अर्थ नहीं है। सेल चयन शैली को .none पर सेट करने के लिए बेहतर है।
अलेक्जेंडर डानिलोव

122

ऐसा इसलिए है क्योंकि टेबल व्यू सेल स्वचालित रूप से हाइलाइट किए गए राज्य के लिए सामग्री दृश्य के अंदर सभी दृश्यों की पृष्ठभूमि का रंग बदलता है। आप UIViewअपने रंग को आकर्षित करने के लिए या UIImageViewकस्टम 1x1 px स्ट्रेच्ड छवि के साथ उपयोग करने के लिए उपवर्ग पर विचार कर सकते हैं ।


1
गूंगा मुझे। बेशक यह था, साक्षात्कार पारदर्शी होना चाहिए ताकि चयन एनीमेशन ठीक से हो सके। धन्यवाद!
साइरिल

52
या आप बैकग्राउंड कलर को ओवरराइड कर सकते हैं setHighlighted:animated:औरsetSelected:animated:
pt2ph8

1
किसी तरह बैकग्राउंड कलर को रीसेट करना मेरे लिए काम नहीं करता था (iOS 8.1 पर चलना)। इसके बजाय मेरे विचार को रेखांकित करके और setBackgroundColor को अधिलेखित करके [सुपर setBackgroundColor: [UIColor whiteColor]] के रूप में हल किया।
बिजोय 14

44

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

ये बहुत प्यारी है। आसानी से सबसे अच्छा समाधान यदि आपके पास "बैज" या "टैग" जैसा कुछ पुनः प्रयोग करने योग्य दृश्य है, जिसमें कभी भी स्पष्ट पृष्ठभूमि नहीं होनी चाहिए। :: शेख़ी :: क्या एक उलझन समाधान @UIKit, जब आप एक सेल चयन करते हैं तो सभी बच्चे के विचार पारदर्शी होते हैं। बच्चे के विचारों की कम से कम सीमा जो सेल की पूरी ऊंचाई या चौड़ाई, या एन गहराई पर हैं।
सिंपलजी

@SimplGy हाइलाइटिंग की गहराई वास्तव में एक मीठा विकल्प होगा, लेकिन हे - यह उकीत है, मैंने चीजों को देखा है तो इससे भी बदतर =)
पावेल गुआरोव

3
मेरे लिए काम करने के बाद अगर मैंने CGColorGetAlpha (बैकग्राउंडरोलर .CGColor) == 0 को बदल दिया तो यह क्लियररोल के बराबर नहीं था
piltdownman7

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];

हम्म, मैं इस सटीक कोड की कोशिश कर रहा हूं और यह मेरे लिए बिल्कुल भी प्रभाव नहीं डाल रहा है। मेरा सबव्यू उस मामले के मामले में सेल 6.0.VententView, और iOS 6.0.1 के तहत परीक्षण के रूप में जोड़ा गया एक UILabel है।
जो स्ट्रैट

आप ऊपर दिए गए कोड को क्या लागू करते हैं? और क्या आपने सेल को केवल सेल दृश्य में जोड़ने की कोशिश की है?
अगत

यह मेरी राय में सही समाधान है। परत पर आरेखण पूरी तरह से लचीलेपन रखते हुए, समस्या को पूरी तरह से संबोधित करता है। मुझे UIImageView का उपयोग करना पसंद नहीं है, क्योंकि तब ग्रेडिएंट या रंग को समायोजित करना कठिन होता है (आपको हर बार एक नई छवि बनानी होगी), और इसके लिए UIView को उप-वर्गित करना ओवरकिल लगता है।
एरिक वैन डेर न्यूट जूल

@ लिडा, मैं वास्तव में स्विफ्ट-डेवलपर नहीं हूं। (मैं और भी # C -one)। लेकिन मैंने जो देखा है, वह भाषा-विशिष्ट चीज नहीं है, हालांकि, ज्यादातर कोको / आईओएस फ्रेमवर्क लॉजिक है। इसलिए, विचार केवल अनुरोध को प्राप्त परिणाम प्राप्त करने के लिए लगभग पारदर्शी CAGradientLayer को अपने दृष्टिकोण में रखने के लिए है।
Agat

9

के लिए स्विफ्ट 2.2 यह काम करता है

cell.selectionStyle = UITableViewCellSelectionStyle.None

और कारण @ एंड्री द्वारा समझाया गया है

ऐसा इसलिए है क्योंकि टेबल व्यू सेल स्वचालित रूप से हाइलाइट किए गए राज्य के लिए सामग्री दृश्य के अंदर सभी दृश्यों की पृष्ठभूमि का रंग बदलता है।


8

यतिशा बीएल के जवाब से प्रेरित होकर मैंने एक यूआईटेबल व्यूसेल श्रेणी / विस्तार बनाया जो आपको इस पारदर्शिता "सुविधा" को चालू और बंद करने की अनुमति देता है।

तीव्र

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

उद्देश्य सी

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

KeepBackgroundCell कोकोपोड संगत है। आप इसे GitHub पर पा सकते हैं


7

आप कर सकते हैं cell.selectionStyle = UITableViewCellSelectionStyleNone;, तो पृष्ठभूमि पर सेट करें- (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath


4

यतिशा बीएल के जवाब से प्रेरित ।

यदि आप 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
    }
}

1
समाधान के लिए धन्यवाद। +1 ishiglighted वैरिएबल और sethighlighted विधि को ओवरराइड करना अलग चीजें हैं। सही उत्तर विधि को ओवरराइड करना है।
नुमान कारासलान

4

मामले के लिए, यह सेल में सभी वस्तुओं के लिए ग्रे रंग प्राप्त करने से बचने के लिए सिपाही है (यदि आप कस्टम टेबल सेल का उपयोग कर रहे हैं तो:

  1. चयन करने के लिए सेट करें selectionStyle = .none

  2. इस विधि को ओवरराइड करें।

    func setHighlighted (_ हाइलाइट किया गया: बूल, एनिमेटेड: बूल)

  3. सुपर को कॉल करें, सुपर सेटअप का लाभ पाने के लिए।

    super.setHighlighted (हाइलाइट, एनिमेटेड: एनिमेटेड)

  4. आप जो चाहते हैं, उस पर प्रकाश डालिए।

    override func setHighlighted(_ highlighted: Bool, animated: Bool) {
          super.setHighlighted(highlighted, animated: animated)
          // Your Highlighting Logic goes here...
    }

3

UITableViewCell किसी कारण से चयन पर सभी साक्षात्कारों की पृष्ठभूमि बदल देता है।

यह मदद कर सकता है:

DVColorLockView

UITableView को चयन के दौरान अपना दृश्य रंग बदलने से रोकने के लिए कुछ ऐसा उपयोग करें।


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);

        }
    }


}

1

एनीमेशन के साथ बग के बिना SIMPLEST समाधान (शीर्ष रेटेड उत्तर के रूप में) और उपवर्ग और ड्राइंग के बिना - पृष्ठभूमि की जगह परत की सीमा का रंग सेट करें और बहुत बड़ी सीमा चौड़ाई सेट करें।

colorThumb.layer.cornerRadius = 6
colorThumb.layer.borderWidth = colorThumb.frame.width
colorThumb.layer.borderColor = value.color

0

निम्नलिखित कोड का प्रयास करें:

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

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

यह पावेल गुरोव के उत्तर के समान है, लेकिन इसमें अधिक लचीला यह किसी भी रंग को स्थायी होने की अनुमति देता है।

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

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

0

मैं एक सेल सबवे को छोड़कर डिफ़ॉल्ट चयन व्यवहार रखना चाहता था जिसे मैं स्वचालित पृष्ठभूमि रंग परिवर्तन को अनदेखा करना चाहता था। लेकिन मुझे अन्य समय में पृष्ठभूमि का रंग बदलने में सक्षम होने की भी आवश्यकता थी।

मैं जिस समाधान के साथ आया था वह उपवर्ग के लिए था UIViewइसलिए यह पृष्ठभूमि के रंग को सामान्य रूप से सेट करने की उपेक्षा करता है और सुरक्षा को बायपास करने के लिए एक अलग फ़ंक्शन जोड़ता है।

स्विफ्ट 4

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

    override var backgroundColor: UIColor? {
        set {
            return
        }
        get {
            return super.backgroundColor
        }
    }
}

-1

यहाँ मेरा समाधान है, SelectionColor दिखाने के लिए contentView का उपयोग करें, यह पूरी तरह से काम करता है

#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;
    }
}

-1

इस कोड को अपने उपवर्ग में रखें 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)
    }
}

-1

यदि आप स्टोरीबोर्ड का उपयोग कर रहे हैं तो एक और समाधान जोड़ना। इसका एक उपवर्ग बनाएँ जो शुरू में सेट होने के बाद सेट होने की UIViewअनुमति नहीं देता backgroundColorहै।

@interface ConstBackgroundColorView : UIView

@end

@implementation ConstBackgroundColorView

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

@end

-1

यदि उपर्युक्त पृष्ठभूमि समाधान आपकी समस्या को ठीक नहीं कर रहा है, तो आपका मुद्दा आप में झूठ हो सकता है datasource आपके तालिका दृश्य लिए ।

मेरे लिए, मैं BoxDataSourceप्रतिनिधि और डेटा स्रोत तालिका दृश्य विधियों को संभालने के लिए एक डेटा स्रोत ऑब्जेक्ट (कॉल ) का एक उदाहरण बना रहा था :

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

जब भी सेल का दोहन किया गया था, तब डेटा स्रोत को डीलॉस्क किया जा रहा था, और इस तरह सभी सामग्री गायब हो गई। इसका कारण, एआरसी डीलकोलेटिंग / कचरा संग्रहण प्रकृति है।

इसे ठीक करने के लिए, मुझे कस्टम सेल में जाना था, एक डेटा स्रोत चर जोड़ना होगा:

//CustomCell.swift
var dataSource: BoxDataSource?

फिर, आपको सेल के डेटास्रोत को सेट करने की ज़रूरत है जो varआपने अभी सेलफ़ोररॉव में बनाया है, इसलिए इस एआरसी के साथ डील नहीं की गई है।

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

उम्मीद है की वो मदद करदे।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.