2013-09-23 6 views
29

का उपयोग कर एक कस्टम UITableViewCell प्रोग्रामेटिक रूप से कैसे बनाएं I एक UITableView को लागू करने का प्रयास कर रहा हूं जो एक ट्विटर क्लाइंट की समयरेखा के समान व्यवहार करेगा। अभी मैं बस UITableViewCell के अंदर दो लेबल प्राप्त करने का प्रयास कर रहा हूं। जैसा कि this Stack Overflow answer द्वारा अनुशंसित किया गया है, मैं प्रत्येक लेआउट के लिए एक अलग पुन: उपयोगकर्ता का उपयोग कर रहा हूं। मेरे लेआउट सरल हैं, जिनमें से एक या तो लेबल या दो लेबल शामिल हैं। आखिर में मैं UITableViewCells की ऊंचाई समायोजित करूँगा लेकिन पहले मुझे सामग्री के साथ आबादी वाले कोशिकाओं को प्राप्त करने की आवश्यकता है।ऑटोलायआउट

यदि मैं initWithFrame: के साथ अपना फ्रेम सेट करता हूं तो मैं लेबल दिखा सकता हूं, हालांकि बाधाओं को लागू नहीं किया जा रहा है।

  • प्रश्न: लेबल और बाधाओं को प्रदर्शित होने से क्या रोक रहा है? मैं UITableViewCell के कार्यान्वयन में कुछ याद कर रहा हूं लेकिन मुझे नहीं पता कि यह क्या है।

  • माध्यमिक प्रश्न: क्या मैं viewDidLoad में प्रत्येक पुन: उपयोगकर्ता के लिए सही ढंग से UITableViewCell क्लास को पंजीकृत कर रहा हूं?

यह मुश्किल होने के रूप में देखने को मिल सकते हैं, लेकिन इंटरफ़ेस बिल्डर मुझे confuses, मैं सभी कोड में यह पूरा करना चाहते हैं।

static NSString * const kCellIDTitle = @"CellWithTitle"; 
static NSString * const kCellIDTitleMain = @"CellWithTitleMain"; 

@interface TVTCell : UITableViewCell 
{ 
    NSString *reuseID; 
} 

@property (nonatomic, strong) UILabel *nameLabel; 
@property (nonatomic, strong) UILabel *mainLabel; 

@end 

और TVTCell.m:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 
{ 
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 
    if (self) { 
     reuseID = reuseIdentifier; 

     nameLabel = [[UILabel alloc] init]; 
     [nameLabel setTextColor:[UIColor blackColor]]; 
     [nameLabel setBackgroundColor:[UIColor colorWithHue:32 saturation:100 brightness:63 alpha:1]]; 
     [nameLabel setFont:[UIFont fontWithName:@"HelveticaNeue" size:18.0f]]; 
     [nameLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; 
     [self.contentView addSubview:nameLabel]; 

     mainLabel = [[UILabel alloc] init]; 
     [mainLabel setTextColor:[UIColor blackColor]]; 
     [mainLabel setBackgroundColor:[UIColor colorWithHue:66 saturation:100 brightness:63 alpha:1]]; 
     [mainLabel setFont:[UIFont fontWithName:@"HelveticaNeue" size:18.0f]]; 
     [mainLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; 
     [self.contentView addSubview:mainLabel]; 

     [self.contentView setTranslatesAutoresizingMaskIntoConstraints:NO]; 

    } 
    return self; 
} 


- (void)updateConstraints 
{ 
    [super updateConstraints]; 

    NSDictionary *views = NSDictionaryOfVariableBindings(nameLabel, mainLabel); 
    if (reuseID == kCellIDTitle) { 
     NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[nameLabel]|" 
               options: NSLayoutFormatAlignAllCenterX 
               metrics:nil 
                views:views]; 
     [self.contentView addConstraints:constraints]; 
     constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[nameLabel]|" 
                   options: NSLayoutFormatAlignAllCenterX 
                   metrics:nil 
                   views:views]; 
     [self.contentView addConstraints:constraints]; 
    } 
    if (reuseID == kCellIDTitleMain) { 
     NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[nameLabel]|" 
                     options: NSLayoutFormatAlignAllCenterX 
                     metrics:nil 
                     views:views]; 
     [self.contentView addConstraints:constraints]; 

     constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[mainLabel]|" 
                     options: NSLayoutFormatAlignAllCenterX 
                     metrics:nil 
                     views:views]; 
     [self.contentView addConstraints:constraints]; 

     constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[nameLabel][mainLabel]|" 
                   options: NSLayoutFormatAlignAllLeft 
                   metrics:nil 
                   views:views]; 
     [self.contentView addConstraints:constraints]; 

     [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:nameLabel 
            attribute:NSLayoutAttributeHeight 
            relatedBy:NSLayoutRelationEqual 
             toItem:nil 
            attribute:NSLayoutAttributeNotAnAttribute 
            multiplier:0.0 
             constant:44.0]]; 
     [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:nameLabel 
                    attribute:NSLayoutAttributeWidth 
                    relatedBy:NSLayoutRelationEqual 
                     toItem:self.contentView 
                    attribute:NSLayoutAttributeNotAnAttribute 
                    multiplier:0.0 
                     constant:1]]; 
    } 
} 

क्षमा करें, कोड की टन

यहां कस्टम UITableViewCell TVTCell.h नामित के लिए कोड है। यहाँ मेरी UITableView के tableView:cellForRowAtIndexPath:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    if (indexPath.row == 0 || indexPath.row == 2 || indexPath.row == 3) { 
     TVTCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIDTitle forIndexPath:indexPath]; 

     [[cell nameLabel] setText:[nameArray objectAtIndex:indexPath.row]]; 

     return cell; 
    } else if (indexPath.row == 1 || indexPath.row == 4 || indexPath.row == 5) { 
     TVTCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIDTitleMain forIndexPath:indexPath]; 

     [[cell nameLabel] setText:[nameArray objectAtIndex:indexPath.row]]; 
     [[cell mainLabel] setText:[dataArray objectAtIndex:indexPath.row]]; 

     return cell; 
    } else 
    { 
     UITableViewCell *badCell = [[UITableViewCell alloc] init]; 
     NSLog(@"Warning! returning a cell that shouldnt be here"); 
     badCell.textLabel.text = @"Warning!"; 
     return badCell; 
    } 
} 

और अंत में, UITableView के viewDidLoad विधि:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    [[self tableView] registerClass:[TVTCell class] forCellReuseIdentifier:kCellIDTitle]; 
    [[self tableView] registerClass:[TVTCell class] forCellReuseIdentifier:kCellIDTitleMain]; 
} 
+0

मुझे एक ही भ्रम मिला। आपके प्रश्न के लिए धन्यवाद। – stackFish

उत्तर

31

कई चीज़ें हैं जिन्हें अपने कोड के साथ गलत कर रहे हैं। सबसे पहले, मुझे लगता है कि आप पाएंगे, अगर आप कुछ लॉगिंग करते हैं, तो अपडेट कॉन्स्ट्रेन को कभी नहीं कहा जाता है। मैं सभी कोड init विधि में डाल देंगे। इसके अलावा, आपकी बाधाओं में कई चीजें गलत हैं। जिस बाधा को आप 44 तक ऊंचाई निर्धारित करते हैं, उसकी आवश्यकता नहीं है क्योंकि आपके पास पहले से ही सेल के नीचे और नीचे लेबल किए गए लेबल हैं। मुझे नहीं पता कि आप उस आखिरी के साथ क्या करने की कोशिश कर रहे हैं, ऐसा लगता है कि नाम लेबल 1 बिंदु चौड़ा होगा। साथ ही, आपको सामग्री दृश्य के लिए अनुवादों को AutoresizingMaskIntoConstraints को सेट नहीं करना चाहिए, जो अजीब प्रभाव का कारण बनता है।

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 
    if (self) { 
     reuseID = reuseIdentifier; 

     nameLabel = [[UILabel alloc] init]; 
     [nameLabel setTextColor:[UIColor blackColor]]; 
     [nameLabel setBackgroundColor:[UIColor colorWithHue:32 saturation:100 brightness:63 alpha:1]]; 
     [nameLabel setFont:[UIFont fontWithName:@"HelveticaNeue" size:18.0f]]; 
     [nameLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; 
     [self.contentView addSubview:nameLabel]; 

     mainLabel = [[UILabel alloc] init]; 
     [mainLabel setTextColor:[UIColor blackColor]]; 
     [mainLabel setBackgroundColor:[UIColor colorWithHue:66 saturation:100 brightness:63 alpha:1]]; 
     [mainLabel setFont:[UIFont fontWithName:@"HelveticaNeue" size:18.0f]]; 
     [mainLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; 
     [self.contentView addSubview:mainLabel]; 

     NSDictionary *views = NSDictionaryOfVariableBindings(nameLabel, mainLabel); 
     if (reuseID == kCellIDTitle) { 
      NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[nameLabel]|" 
                      options: 0 
                      metrics:nil 
                      views:views]; 
      [self.contentView addConstraints:constraints]; 
      constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[nameLabel]|" 
                    options: 0 
                    metrics:nil 
                    views:views]; 
      [self.contentView addConstraints:constraints]; 
     } 
     if (reuseID == kCellIDTitleMain) { 
      NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[nameLabel]|" 
                      options:0 
                      metrics:nil 
                      views:views]; 
      [self.contentView addConstraints:constraints]; 

      constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[mainLabel]|" 
                    options: 0 
                    metrics:nil 
                    views:views]; 
      [self.contentView addConstraints:constraints]; 

      constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[nameLabel][mainLabel(==nameLabel)]|" 
                    options: 0 
                    metrics:nil 
                    views:views]; 
      [self.contentView addConstraints:constraints]; 

     } 
    } 
    return self; 
} 
+0

अद्भुत, मेरे कोड को सही करने के लिए धन्यवाद। कोशिकाएं 88.0 की मेरी डिफ़ॉल्ट सेल ऊंचाई फिट करने के लिए अच्छी तरह से, सिंगल लेबल वाले सेल स्केल प्रदर्शित कर रही हैं और डबल लेबल वाली कोशिकाएं समान रूप से स्थान साझा करती हैं। स्टैक ओवरफ़्लो उत्तर में मैंने पहले उल्लेख किया था कि डेवलपर कहता है: _ "इन सबव्यूव्स के आंतरिक सामग्री आकार को तालिका के दृश्य को सेल दृश्य सामग्री दृश्य को सुनिश्चित करने के लिए सुनिश्चित करें कि प्रत्येक संपीड़न के लिए लंबवत आयाम में सामग्री संपीड़न प्रतिरोध और सामग्री hugging बाधाएं सुनिश्चित करें आपके द्वारा जोड़े गए उच्च प्राथमिकता बाधाओं से ओवरराइड नहीं किया जा रहा है। "_ मैं इसे कैसे और कहां पूरा करूँगा? –

+0

@ShawnThroop, मुझे यकीन नहीं है कि यह कैसे काम करेगा - जिस तरह से पोस्टर उपयोग कर रहा है वह आमतौर पर उपयोग करने से अलग दृष्टिकोण है। क्या आपको अपनी कोशिकाओं के लिए अलग-अलग ऊंचाई की आवश्यकता है? यदि हां, तो क्या वह ऊंचाई केवल लेबल की संख्या पर निर्भर करेगी, या कुछ लेबलों में लाइनों की एक चर संख्या होगी? – rdelmar

+0

आखिरकार मैं एक ऊंचाई के साथ एक सेल का लक्ष्य रख रहा हूं जो मुख्य रूप से एक लेबल की संख्या या रेखाओं पर निर्भर है। मुझे सामग्री संपीड़न प्रतिरोध और सामग्री hugging पर और अधिक पढ़ने की जरूरत है। ऐप्पल डॉक्स के लिए ... बीटीडब्ल्यू, आप इसे सामान्य रूप से कैसे करेंगे? मैं अनुमान लगा रहा हूं कि यह आसान है कि मैं इसे लागू करने की कोशिश कर रहा हूं। –

0

आप UITableViewCell प्रोग्राम के तेज 4 में नीचे की तरह ऑटो लेआउट का उपयोग कर बना सकते हैं: तो यह कोड मुझे लगता है कि आप चाहते हैं।यह के रूप में आप प्रश्न में निर्दिष्ट अपने ऊपर समस्या का समाधान वास्तव में नहीं है, यह अधिक सामान्य कार्यान्वयन ऑटो लेआउट का उपयोग कर तेज में प्रोग्राम के tableview सेल बनाने का तरीका बताया:

class ViewController: UITableViewController { 

override func viewDidLoad() { 
    super.viewDidLoad() 
    tableView.register(CustomCell2.self, forCellReuseIdentifier: "cell") 
} 

override func numberOfSections(in tableView: UITableView) -> Int { 
    return 1 
} 
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return 2 
} 

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as? CustomCell2 else { return UITableViewCell() } 
    cell.model = CellModel(labelString: "set constriant by code") 
    return cell 
    } 
    } 

परिभाषित मॉडल:

struct CellModel { 
    let labelString : String 
} 

को परिभाषित करें कस्टम सेल:

class CustomCell2 : UITableViewCell { 
private let label : UILabel = { 
    let label = UILabel() 
    label.translatesAutoresizingMaskIntoConstraints = false // enable auto layout 
    label.backgroundColor = .green // to visualize the background of label 
    label.textAlignment = .center // center text alignment 
    return label 
}() 

private func addLabel() { 
    addSubview(label) 
    NSLayoutConstraint.activate([ 
     // label width is 70% of cell width 
     label.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.7), 
     // label is horizontally center of cell 
     label.centerXAnchor.constraint(equalTo: centerXAnchor) 
    ]) 
} 

var model : CellModel? { 
    didSet { 
     label.text = model?.labelString ?? "" 
    } 
} 

// Init 
override init(style: UITableViewCellStyle, reuseIdentifier: String?) { 
    super.init(style: style, reuseIdentifier: reuseIdentifier) 
    addLabel() 
} 

required init?(coder aDecoder: NSCoder) { 
    fatalError("init(coder:) has not been implemented") 
} 
} 

This is the output of above program.

This is the actual project, you can check out.

संबंधित मुद्दे