2011-12-23 49 views
0

我現在碰到過這個問題兩次,並且很想知道是否有正確的方法讓下面的例子工作。我知道做同樣的事情還有其他的方式/解決方法,但我想知道爲什麼編譯器不能識別我的演員,如果我在這裏失去了明顯的東西。Objective-C中的自定義類和鑄造條件語句

假設我有兩個帶有不同風格頭部視圖的表格視圖,我需要提供。 SectionHeaderViewA是一個UIView子類,具有自定義屬性textLabelASectionHeaderViewB也是一個具有自定義屬性textLabelB的UIView子類。

在該方法中:

- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 
{ 
    id headerView; 
    if (tableView.tag == TAG_A) 
    { 
     headerView = (SectionHeaderViewA*)[[SectionHeaderViewA alloc] init]; 
     headerView.textLabelA = ... // I am unable to access the custom property here even after casting (SectionHeaderViewA*) above. 
    } else if (tableView.tag == TAG_B) { 
     headerView = (SectionHeaderViewB*)[[SectionHeaderViewB alloc] init]; 
     headerView.textLabelB = ... // Same as above, even after casting the custom property is not recognised 
    } 
    return headerView; 
} 

即使鑄造(SectionHeaderViewA *)和(SectionHeaderViewB *)我headerView伊娃後,我仍然無法訪問他們各自的自定義屬性。這就像編譯器仍然將headerView視爲未知/ id類型,但爲什麼?

+0

你得到的錯誤信息是什麼? – sidyll 2011-12-23 00:14:11

+0

你導入了兩個頭文件嗎? – 2011-12-23 00:17:47

+0

Rog,當您檢查參數「tableView」的類型時,調試器是否識別表視圖的特定類型? – Ushox 2011-12-23 00:19:47

回答

2

演員是不是在正確的位置。在發送適當的textLabel A或B消息之前先投射headerView。

id headerView; 
if (tableView.tag == TAG_A) 
{ 
    headerView = [[SectionHeaderViewA alloc] init]; 
    ((SectionHeaderViewA*)headerView).textLabelA = ... // I am unable to access the custom property here even after casting (SectionHeaderViewA*) above. 
} else if (tableView.tag == TAG_B) { 
    headerView = [[SectionHeaderViewB alloc] init]; 
    ((SectionHeaderViewB*)headerView).textLabelB = ... // Same as above, even after casting the custom property is not recognized 
} 
return headerView; 

一旦你移動演員,你將能夠發送正確的消息。

+0

美麗!這正是我要找的,謝謝肖恩! – Rog 2011-12-23 01:54:29

+0

我的榮幸。出於好奇,爲什麼你使用兩個截然不同的UITextLabels視圖作爲你的節頭? – 2011-12-23 02:16:04

+0

我真的不是,這只是一個人爲的例子來說明我的觀點。但我不明白爲什麼不能有與之相關的不同格式和其他子視圖(在我的例子中,我有2個不同的標題視圖,因爲iPad版本有兩個不同的表格視圖)。 – Rog 2011-12-23 03:10:12

1

當您投射到id中時,您的演員陣容沒有任何作用。

雖然@肖恩的答案作品和它的單一出口是很醜陋讓所有的大括號,我可能會去

id headerView = nil; // Initialize to nil... you may not go into either side of your if 

if (TAG_A == tableView.tag) { 
    SectionHeaderViewA *sectionHeaderViewA = [[SectionHeaderViewA alloc] init]; 
    sectionHeaderViewA.textLabelA = ... 
    headerView = sectionHeaderViewA; 
} else if (TAG_B == tableView.tag) { 
    SectionHeaderViewB *sectionHeaderViewB = [[SectionHeaderViewB alloc] init]; 
    sectionHeaderViewB.textLabelB = ... 
    headerView = sectionHeaderViewB; 
} 

return headerView; 

或者另一種可能性(可能在工程問題)是使雙方sectionHeaderViewAsectionHeaderViewB符合協議,然後你可以使它仍然有點整齊。

SectionHeaderInterface.h

@protocol SectionHeaderInterface <NSObject> 

@property (strong, nonatomic) UILabel *textLabel; 

@end 

SectionHeaderView(A | B).H

#import "SectionHeaderInterface.h" 

@interface SectionHeaderView(A|B) : UIView <SectionHeaderInterface> 

// ... rest of interface 

@end 

SectionHeaderView(A | B).M

@implementation SectionHeaderView(A|B) 

@synthesize textLabel = _textLabel; 

// ... rest of your class 

@end 

YourController.m

id<SectionHeaderInterface> headerView = nil; // Initialize to nil... you may not go into either side of your if 

if (TAG_A == tableView.tag) { 
    headerView = [[SectionHeaderViewA alloc] init]; 
} else if (TAG_B == tableView.tag) { 
    headerView = [[SectionHeaderViewB alloc] init]; 
} 

headerView.textLabel.text = ... 

return headerView; 
+0

+1 Thanks @ Paul.s,我喜歡聲明一個協議,這兩者都符合。你說對了這個人爲的例子已經過去了,但它在其他一些情況下可能非常有用。 – Rog 2011-12-23 03:13:08

1

headerView的類型是「ID」,這意味着它不知道你額外的屬性等(投不改變「headerView」的類型)。

,你可以這樣做:

if (tableView.tag == TAG_A) 
{ 
    SectionHeaderViewA* headerView = [[SectionHeaderViewA alloc] init]; 
    headerView.textLabelA = ... 
    return headerView; 
} else if (tableView.tag == TAG_B) { 
    SectionHeaderViewB* headerView = [[SectionHeaderViewB alloc] init]; 
    headerView.textLabelB = ... 
    return headerView; 
} 
return nil; 
+0

'演員不改變headerView'的類型。你是對的,當我這樣看的時候是有道理的。我不是你條件語句中三個返回點的忠實粉絲,所以我所做的就是在'if/else'之外聲明'headerView',然後在條件聲明'h​​eaderView = headerViewA'或'headerView = headerViewB'內部聲明' ,然後'返回headerView'。 – Rog 2011-12-23 00:35:47

+0

我認爲這個答案是正確的,但同時要注意內存泄漏。 – Johnny 2011-12-23 00:36:58