2011-02-08 37 views
0

試圖實現一個「簡單」一個CustomCell, 我有一個正常的tableViewController,使用正常的「默認」方法,但我需要實現一個自定義單元格與一些UILabel和UIImage罰款。Iphone UITableViewCell CustomCell

因此,我創建了CustomCell.h,CustomCell.m,CustomCell.xib

的.H

@interface CustomCell : UITableViewCell <UITextViewDelegate> 
{ 
    IBOutlet UIImageView *image; 
    IBOutlet UILabel *name; 
    IBOutlet UILabel *date; 
    IBOutlet UILabel *comment; 
} 

@property (retain,nonatomic) IBOutlet UIImageView *image; 
@property (retain,nonatomic) IBOutlet UILabel *name; 
@property (retain,nonatomic) IBOutlet UILabel *date; 
@property (retain,nonatomic) IBOutlet UILabel *comment; 

和.M

@implementation CustomCell 

@synthesize image; 
@synthesize name; 
@synthesize date; 
@synthesize comment; 


#pragma mark - 
#pragma mark View lifecycle 

- (id) initWithController: (Controller *) ctnlr 
{ 
    ControllerPointer = ctnlr; 
    return(self); 
} 

- (void) SetImage:(UIImageView*)Image 
{ 
    image = Image; 
} 

- (void) SetName:(NSString*)Name 
{ 
    [Name retain]; 
    [name.text release]; 
    name.text = Name; 
} 

- (void) SetDate:(NSString*)Date 
{ 
    [Date retain]; 
    [date.text release]; 
    date.text = Date; 
} 

- (void) SetComment:(NSString*)Comment 
{ 
    [Comment retain]; 
    [comment.text release]; 
    comment.text = Comment; 
} 

反正,當我嘗試創建cellForRowAtIndexPath中的這些自定義單元(正如我們期望的那樣可能會實現),我只剩下一個空白屏幕。所以很顯然我缺少一些大的東西......當我用「Interface Builder」創建.XIB文件時,我確保將「引用插座」連接到適當的標籤和圖像。

這樣的Xcode的框架出現的工作方式隱含邏輯下, 我遵循同樣的理由(因爲缺乏一個確切的例子)沒有worky ... 無論如何,如果有任何IPhone怪才,就是想來開導我... (是的,沒有「[釋放]」的電話,我甚至不知道是否需要分配任何東西,請告訴我只有幾個電話我要離開,它可以「T比簡單的東西像這樣的權太大更多...?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"Cell";   
    CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    if(cell == nil) 
    { 
     cell = [[[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil] lastObject]; 
    } 

    NSUInteger row = [indexPath row]; 
    SnsObject *sObj = [SnsArray objectAtIndex:row]; 
    [cell SetName:[sObj getUserName]]; 

    NSUInteger row = [indexPath row]; 
    SnsObject *sObj = [SnsArray objectAtIndex:row]; 
    cell.name = [[UILabel alloc]init]; 
    cell.name.text = [sObj getUserName]; 

    cell.date = [[UILabel alloc]init]; 
    cell.date.text = [sObj getDateTime]; 

    cell.comment = [[UILabel alloc]init]; 
    cell.comment.text = [sObj getCommentText]; 

    cell.image = [[UIImageView alloc]init]; 
    cell.image.image = [sObj getImageUrl]; 
    return(cell) 
} 

提前感謝!

回答

2

從.xib加載UITableViewCell時,不需要手動創建控件。

例如,這種事情是不必要的:

cell.name = [[UILabel alloc]init]; 

這將取代從廈門國際銀行加載了具有零幀新的標籤的標籤 - 即新標籤將設在0,0並沒有寬度或高度。因此,沒有工作

假設您已將xib正確連接到CustomCell的IBOutlets,它們控制的您正在尋找的應該已經存在。

P.S.原諒我,如果我讀太多到方法的名字,但我不認爲這條線會擦出火花,因爲物業圖像配預計一個UIImage:

cell.image.image = [sObj getImageUrl]; 
4

有與超出代碼等問題什麼mrcrowl提到了現在需要「分配 - 初始化」網點。特別是,這一行:

cell = [[[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil] lastObject]; 

這不是用於從.xib加載自定義tableview單元格的典型習慣用法。首先,您傳遞「owner:self」,這意味着您想要將.xib文件中的插座對象與您的tableview控制器對象中的插座成員掛鉤,可能不是您想要的。 其次,您依賴於loadNibNamed:owner:options:返回的對象的順序,雖然它今天可能有效,但可能無法在明天或iOS新版本上運行。

相反,通常的成語是聲明的出路在tableviewcontroller整個tableviewcell: (在.h文件):

... 
    UITableViewCell *tvCell; 
... 

@property (nonatomic, retain) IBOutlet UITableViewCell *tvCell; 

然後在地方你行,你有這樣的:

[[NSBundle mainBundle] loadNibNamed:@"NewsArchiveTitleTvCell" owner:self options:nil]; 
cell = tvCell; 
self.tvCell = nil; 

通常情況下,這不是通過子類來完成的,請注意我沒有將類聲明爲CustomCell,而是作爲vanilla UITableViewCell聲明。那麼怎樣才能得到那些煩人的子視圖,以便配置它們呢?使用標籤是正常的方式:

... 
#define kMyKewlLabelTag 1 
... 
    UILabel *kewlLabel = (UILabel *) [cell viewWithTag:kMyKewlLabelTag]; 
    kewlLabel.text = [NSString stringWithFormat:@"Hi there from row %d!", indexPath.row]; 
... 

編輯: 編輯:「這是怎麼回事的」這裏有更詳細一點,評論太短,以解決題。下面是從我的應用程序之一,從一個的.xib加載的UITableViewCell的摘錄:

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

    static NSString *CellIdentifier = @"MyShoppingCartTvCell"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) 
    { 
     [[NSBundle mainBundle] loadNibNamed:@"ShoppingCartTvCell" owner:self options:nil]; 
     cell = tvCell; 
     self.tvCell = nil; 
    } 
     ... 
     // (insert code to grab model data for this row) 
     ... 
    UILabel *nameLabel = (UILabel *) [cell viewWithTag:1]; 
    nameLabel.text = itemNameStr; 

    UILabel *countLabel = (UILabel *) [cell viewWithTag:2]; 
    countLabel.text = [NSString stringWithFormat:@"%d", itemCount]; 

    UIImageView *iv = (UIImageView *) [cell viewWithTag:3]; 
     ... 

這裏就是這裏發生了:

  • 沒有自定義的UITableViewCell子類中,只有一個的.xib名爲「ShoppingCartTvCell.xib」的文件包含一個UITableViewCell,以及置於UITableViewCell內部的UI元素。其數據必須在每行更改的UI元素被分配一個唯一標記(標記字段位於IB中的CMD-1屬性檢查器中),以便您的代碼可以獲取這些對象的句柄以更改它們(自定義標籤,圖像等) 。確保你不使用「0」,因爲所有元素默認都有0標籤。另外,請確保CMD-1屬性檢查器中的UITableViewCell的標識符字段是CellIdentifier字符串。

  • 中的.xib文件的文件的所有者是要顯示你的細胞表視圖控制器。更確切地說,它可以是任何包含IBOutlet UITableViewCell * tvCell的類;會員。它是您以擁有者的身份傳遞給loadNibNamed:owner:options:的此類的一個實例。只要連接插座的價值爲零的老闆,當你調用loadNibNamed:業主:選項,主人的出口填充來自的.xib對象(只要連接是在做。 IB中的xib)。瞭解這是Apple編程中的一個神奇時刻,它爲您打開全新的前景:)。

  • 您必須設置self.tvCell = nil;以準備需要從.xib加載的下一個cellForRowAtIndexPath。我有時也會在loadNibNamed:owner:options:之前設置爲nil,我認爲這實際上更安全一些。

這裏是你如何去從的.xib加載你的UITableViewCells:

  • 在Xcode中,添加一個IBOutlet的UITableViewCell * tvCell;您的UITableViewController類(包括財產申報,如果你喜歡)

  • 在Xcode項目,創建一個新文件,用戶界面,空XIB。在IB

  • 在IB打開這個的.xib,從庫中拖拽一個TableViewCell到您空。下急救員廈門國際銀行文件

  • 點擊文件擁有者,CMD-4(標識檢查),並根據類別選擇包含IBOutlet中的UITableViewCell * tvCell您添加(可能是你的UITableViewController子類,這個類在那裏你操縱類你的桌子)。

  • 控制 - 從文件所有者拖動到UITableViewCell,然後選擇要連接的插座。當您調用loadNibNamed:owner:options作爲「所有者」參數的文件所有者實例時,這個字段將保存新加載的xib UITableViewCell。

  • 將UI元素添加到UITableViewCell中(確保它們是,在的UITableViewCell層次結構中)。您想要按行自定義的任何元素都需要唯一的標記值。

  • 跟隨我的cellForRowAtIndexPath上面給出的配方

  • 有一個神奇的時刻,你開始瞭解的.xib文件和文件的所有者對象真正工作起來,並開始創建大量的涼爽UITableViewCells和其他自定義視圖對象在IB中,因爲它比在代碼中創建它們更容易和方便(IMNSHO)。

+0

好吧......有點困惑你在做什麼,但確定...所以不是在tableViewController類的標題引用了我的「CustomCell * customCell」的,我要引用通用「的UITableViewCell * tvCell「...確定....就我的」CustomCell.m&.h「他們不會改變...?並在「TableViewController.m」cellForRowAtIndexPath()我有點失去了我究竟會創造什麼......?以及我的「CustomCell」如何被實例化,如果它甚至沒有被引用......請賜教我......先謝謝了! – chinasailor 2011-02-09 01:47:53

-1

好吧...感謝所有爲良好的輸入,但有時最簡單的答案是不僅是最有說服力的,這是最好的......這裏就是我發現工作,,保持它儘可能簡單,而不改變一個功能之外的東西。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"CustomCellIdentifier"; 
    CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if(cell == nil) 
    { 
     NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil]; 
     for(id oneObject in nib) 
     { 
      if([oneObject isKindOfClass:[CustomCell class]]) 
      { 
       cell = (CustomCell*)oneObject; 
      } 
     } 
    } 
    NSUInteger row = [indexPath row]; 
    printf("MainMessageBoard.m cellForRowAtIndexPath = [%i]\n",row); 
    SnsObject *sObj = [SnsArray objectAtIndex:row]; 
    cell.Name.text = [sObj getUserName]; 
    cell.Date.text = [sObj getDateTime]; 
    cell.Comment.text = [sObj getCommentText]; 
    cell.Image.image = [self resizeImage: [self imageFromURLString: [sObj getImageUrl]] scaledToSize:CGSizeMake(32.0f, 32.0f)]; 
    cell.CommentCount.text = [NSString stringWithFormat:@"(%d)", [sObj getCommentCount]]; 
    cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; 
    return(cell); 
}