2014-10-15 14 views
15

पर अटक गया है, वर्तमान में मैं स्टोरीबोर्ड का उपयोग किए बिना कस्टम सेल के साथ एक साधारण UITableView बनाने की कोशिश कर रहा हूं।आईओएस 8 पर UITableView सेल चौड़ाई 320pt

मैं 6 सिम्युलेटर जहां तालिका दृश्य 375 की चौड़ाई है (जैसा कि होना चाहिए) iPhone पर एक मुद्दा हो रही है, लेकिन कोशिकाओं के अंदर संख्या 320 कहीं नहीं है 320.

की चौड़ाई हो रही है प्रोजेक्ट में पाया जा सकता है क्योंकि मैं इसे कड़ी मेहनत नहीं कर रहा हूं। जब मैं सेल का पृष्ठभूमि रंग सेट कर रहा हूं, तो यह 375 की पूरी चौड़ाई बढ़ाता है, लेकिन मुझे दाईं ओर एक छवि को संरेखित करने की आवश्यकता है, जो नीचे दी गई तस्वीर में दिखाए गए अनुसार 320 को केवल संरेखित करता है।

image of weird tableviewcell sizing

मुझे यकीन है कि अगर यह है क्योंकि मैं याद आ रही बाधाओं हूँ या अगर कोई एक बग है नहीं कर रहा हूँ। हर प्रकार की सहायता का स्वागत है, धन्यवाद!

कोड तालिका स्थापित करने के लिए:

- (TBMessageViewCell *)getMessageCellforTableView:(UITableView *)tableView atIndexPath:(NSIndexPath *)indexPath 
{ 

    static NSString *cellIdentifier = @"MessageCell"; 
    TBMessageViewCell *cell = (TBMessageViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 
    if (cell == nil) { 
     cell = [[TBMessageViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; 
     [cell createSubviews]; 
    } 

    // Set the new message and refresh 
    [cell setMessage:self.viewModel.messages[indexPath.row]]; 
    [cell populateSubviews]; 
    cell.backgroundColor = [UIColor blueColor]; 

    NSLog(@"cell Width: %f", cell.contentView.frame.size.width); 

    return cell; 
} 

पूरा TBMessageViewCell:

@implementation TBMessageViewCell 

const CGFloat MARGIN = 10.0f; 
const CGFloat AVATAR_SIZE = 40.0f; 

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

// Sets background and selected background color 
self.backgroundColor = [UIColor clearColor]; 
UIView *selectionColor = [[UIView alloc] init]; 
selectionColor.backgroundColor = [UIColor clearColor]; 
self.selectedBackgroundView = selectionColor; 

return self; 
} 

- (void)populateSubviews 
{ 
    // Set the message body 
    [self.messageBodyLabel setText:self.message.body]; 
    [self.messageBodyLabel setTextAlignment:NSTextAlignmentRight]; 
    CGRect bodyFrame = CGRectMake(MARGIN, MARGIN, self.frame.size.width - (AVATAR_SIZE + (MARGIN * 3)), self.frame.size.height); 
    // Calculates the expected frame size based on the font and dimensions of the label 
    // FLT_MAX simply means no constraint in height 
    CGSize maximumLabelSize = CGSizeMake(bodyFrame.size.width, FLT_MAX); 
    CGRect textRect = [self.message.body boundingRectWithSize:maximumLabelSize 
    options:NSStringDrawingUsesLineFragmentOrigin 
    attributes:@{NSFontAttributeName:self.messageBodyLabel.font} 
    context:nil]; 
    bodyFrame.size.height = textRect.size.height; 

    // Setup the new avatar frame (Right aligned) 
    CGRect avatarFrame = CGRectMake(bodyFrame.size.width + (MARGIN * 2), MARGIN, AVATAR_SIZE, AVATAR_SIZE); 

    // Align to the LEFT side for current user's messages 
    if ([[TBConfig userID] isEqualToString:self.message.user.userID]) { 
     // Set avatar to left if it's me 
     avatarFrame.origin.x = MARGIN; 
     bodyFrame.origin.x = AVATAR_SIZE + (MARGIN * 2); 
     [self.messageBodyLabel setTextAlignment:NSTextAlignmentLeft]; 
    } 

    self.avatar.frame = avatarFrame; 
    self.avatar.layer.cornerRadius = self.avatar.frame.size.width/2; 
    self.messageBodyLabel.frame = bodyFrame; 

    // Set the new cell height on the main Cell 
    CGFloat cellHeight = MAX(bodyFrame.size.height, self.frame.size.height) + MARGIN; 
    self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, cellHeight); 

    // Set the new Profile avatar 
    if (![self.avatar.profileID isEqualToString:self.message.user.facebookID]) { 
     [self.avatar setProfileID:nil]; 
     [self.avatar setProfileID:self.message.user.facebookID]; 
    } 
} 

- (void)createSubviews 
{ 
    self.messageBodyLabel = [[UILabel alloc] init]; 
    self.messageBodyLabel.textColor = [UIColor whiteColor]; 
    self.messageBodyLabel.lineBreakMode = NSLineBreakByWordWrapping; 
    self.messageBodyLabel.numberOfLines = 0; 
    [self addSubview:self.messageBodyLabel]; 

    // Creates the avatar 
    self.avatar = [[FBProfilePictureView alloc] init]; 
    [self.avatar setPictureCropping:FBProfilePictureCroppingSquare]; 
    [self addSubview:self.avatar]; 
} 
+1

यदि आप स्टोरीबोर्ड में सेल्स का उपयोग नहीं कर रहे हैं, तो आप उन्हें कैसे बना रहे हैं? निब फ़ाइल? कोड? यदि कोड कोड – Paulw11

उत्तर

8

आप सेल के आकार प्रिंट कर रहे इससे पहले कि यह प्रदर्शित करने के लिए जोड़ दिया गया है - इससे पहले कि यह आकार कर दिया गया है । आप कौन सोच रहे हैं सेल का आकार बदल जाएगा? आपको लगता है कि ओटी को टेबल व्यू चौड़ाई कहाँ से मिलनी चाहिए? यह यह भी नहीं जानता कि कौन सा तालिका दृश्य इसे अभी तक सौंपने जा रहा है।

प्रदर्शन में जोड़े जाने पर कोशिकाओं को उचित फ्रेम दिया जाएगा।

संपादित करें: ओह, और शायद आप cellIdentifierstatic नहीं चाहते हैं। आप शायद *const चाहते थे।

+0

बहुत बढ़िया धन्यवाद दिखाता है, तो चीजों को चारों ओर ले जाने का प्रयास करेगा। चीजों को करने के लिए सबसे अच्छा आदेश के लिए कोई सुझाव? –

+1

सेल को अपने आकार के आधार पर निर्धारण करने के लिए जिम्मेदार होना चाहिए और आकार परिवर्तन में हर बार प्रतिक्रिया दे सकती है (जहां शास्त्रीय स्प्रिंग्स और स्ट्रेट्स हैं, और अब भी 'NSLayoutConstraint' आपको बॉयलरप्लेट कोड लिखने से बचाने के लिए माना जाता है) । यदि कोई तालिका दृश्य की चौड़ाई के आधार पर लेआउट निर्णय लेना चाहता है, तो उसे सीधे इसके आकार के लिए देखना चाहिए। – Tommy

+0

मैं स्थिर के बजाय कॉन्स का उपयोग क्यों करना चाहूंगा? आम तौर पर मैं इसे किसी अन्य फ़ाइल में # परिभाषित करता हूं। क्या वह भयानक है? –

7

पता नहीं है कि आपको उत्तर मिला है या नहीं। मुझे एक ही समस्या का सामना करना पड़ा जब मैं UITableViewCell को उपclass करने की कोशिश कर रहा था और xib का उपयोग किए बिना प्रोग्रामिक रूप से कस्टम सबव्यूव्स जोड़ता था।

आखिरकार मेरे लिए काम किया गया समाधान self.frame के बजाय सबव्यूज़ 'फ्रेम की गणना करते समय उपयोग करना है।

3

इसे हल करने का सही तरीका लेआउटस्यूव्यूज़ विधि में अपना लेआउट निष्पादित करना है।

आपके मामले में, बस, "populateSubviews" कहते हैं "layoutSubviews" विधि के भीतर इस तरह:

- (void)layoutSubviews { 

    [super layoutSubviews]; 
    [self populateSubviews]; 

} 

... लेकिन ऐसा करने से पहले मैं एक अलग विधि में सुझाव है कि आप सामग्री जनसंख्या कर (यानी , label.text = ... पर कॉल करता है), और उपरोक्त विधि में सभी लेआउट-प्रभावित कॉल (यानी, label.frame = ...) नीचे [super layoutSubviews] रखें।

ऐसा ही कुछ परिणाम होगा:

- (void)layoutSubviews { 

    [super layoutSubviews]; 

    CGRect bodyFrame = CGRectMake(MARGIN, MARGIN, self.frame.size.width - (AVATAR_SIZE + (MARGIN * 3)), self.frame.size.height); 

    // Calculates the expected frame size based on the font and dimensions of the label 
    // FLT_MAX simply means no constraint in height 
    CGSize maximumLabelSize = CGSizeMake(bodyFrame.size.width, FLT_MAX); 
    CGRect textRect = [self.message.body boundingRectWithSize:maximumLabelSize 
    options:NSStringDrawingUsesLineFragmentOrigin 
    attributes:@{NSFontAttributeName:self.messageBodyLabel.font} 
    context:nil]; 

    bodyFrame.size.height = textRect.size.height; 

    // .. the rest of your layout code here .. 

} 

- (void)populateSubviews { 

    [self.messageBodyLabel setText:self.message.body]; 

    // .. the rest of your code here .. 
} 
0

आप में अपने अवतार फ्रेम सेट करने के बाद:

self.avatar.frame = avatarFrame; 
self.avatar.layer.cornerRadius = self.avatar.frame.size.width/2; 
self.messageBodyLabel.frame = bodyFrame; 

लिखने

self.avatar.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin; 

यह सही करने के लिए अपने अवतार छवि हुक चाहिए मार्जिन और बाएं मार्जिन को लचीला के रूप में छोड़ दें।

0

अपने तालिका दृश्य सेल के कनेक्शन निरीक्षक का चयन करें और देखें कि क्या आप गलती

enter image description here

0

द्वारा editingAccessoryView कनेक्ट नहीं किया है हालांकि इस जवाब के रूप में सरल रूप में आप UIKit देने के लिए उम्मीद थी नहीं हो सकता है, की वजह से UITableView में एक बग - प्रोग्रामिंग के दौरान काम करते समय - आपको अपने हाथों को गंदे करना होगा। Xib प्रेमियों - चेतावनी दी - यह जवाब आपके लिए नहीं है। यह शायद बस काम कर रहा है।
बाद में आईओएस संस्करणों में, आइए उम्मीद करते हैं कि यह समस्या हल हो जाएगी। समस्या यह है कि uitableview सेल के आयामों को 320 तक हार्डकोड कर रहा है। एक प्रोजेक्ट में मेरे पास था - मैं इसे ठीक करने के लिए फ्रेम आकार को मजबूर कर रहा था। N.B. इसमें आईपैड पर स्प्लिटव्यू कंट्रोलर के साथ समस्याएं हैं।

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{ 
NSLog(@"cell frame width:%f",cell.frame.size.width); // you should see <- 320! WTH 

// you can crudely correct this here 
cell.frame = CGRectMake(0,0,[[UIScreen mainScreen] applicationFrame].size.width,CELL_HEIGHT); 

} 

एक और विकल्प - यह मेरे लिए बेहतर काम कर रहा है संदर्भ के लिए एक स्थानीय चौड़ाई चर है। मुझे पता है कि यह कोड आदर्श नहीं है - लेकिन यह लगातार काम करता है।

@interface AbtractCustomCell : UITableViewCell { 
    float width; 
} 
@end 


@implementation AbtractCustomCell 
    - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 
     self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 
     if (self) { 
      //optimise speed 
      // [self setOpaque:YES]; 
      if ([SDiPhoneVersion deviceSize] == iPhone47inch) { 
       width = 375; 
      } 
      else if ([SDiPhoneVersion deviceSize] == iPhone47inch) { 
       width = 414; 
      } 
      else { 
       width = 320;   // hardcode iphone 4/5 /ipad2 
      } 
     } 
     return self; 
    } 

@end 

तो आप TBMessageViewCell इस AbstractCustomCell का एक उपवर्ग जो आप के लिए वहाँ इस चर होगा बनाने के लिए विकल्प होता है। Self.contentView.bounds.size.width/self.bounds.size.width का उपयोग करने के बजाय बस चौड़ाई का उपयोग करें।

0

मैं स्टोरीबोर्ड के बिना प्रोग्रामेटिक लेआउट हूं और एक ही समस्या का सामना कर रहा हूं, और मुझे सेल को cellForRowAt indexPath पर वापस करने की आवश्यकता है जो बदले में अभी भी कंटेनर आकार प्राप्त करने में सक्षम नहीं था।

और मैं लेआउट कोड को willDisplay cell प्रतिनिधि में ले जाकर इसे हल करने का प्रबंधन करता हूं।

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