2012-07-01 139 views
1

在我的甜蜜應用程序中,您可以使用項目列表中的兩種項目。有equipable項目,袋子項目。當您導航到庫存屏幕時,表格視圖有兩個部分,每個部分有4個單元格。四個細胞用於裝備物品,四個細胞用於「袋子」中的物品。如果你沒有裝備什麼,單元格就會說「空」。如何從獲取的結果對象填充稀疏的UITableView?

如何根據結果對象的形狀有條件地填充表格單元格?

下面是代碼我希望我有:

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

    static NSString *CellIdentifier = @"Cell"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    if (cell == nil) { 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 
    } 

    // this returns 'nil' if the index path was out of bounds 
    NSManagedObject * item = [self.fetchedResultsController carefullyGetObjectAtIndexPath:indexPath]; 

    if (nil == item) { 
    cell.textLabel.text = @"empty"; 

    } else { 
    cell.textLabel.text = [item valueForKey:@"name"]; 

    } 

} 

我遇到想實現這個「小心」 objectAtIndexPath一些問題:

我試着邊界檢查,但我有麻煩因爲fetchedArray是平坦的,而我試圖導航的概念模型並不平坦:行是'in'部分。

我試圖用一個try/catch,但後來我想起了出界外因素是不確定的,而不是零......所以有時我得到我可以捕捉和反應,有時我只是一個錯誤得到隨機有趣的東西。設置我現在有:

@try { 

    NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:indexPath]; 

    return managedObject; 
} 
@catch (NSException * e) { 
    return nil; 
} 

一直給我5項,在正確的地方與4奇1球是從其他部分重複。

不確定如何手動導航獲取的結果。我在玩四種物品,每種都有兩種。我曾希望它會像一個雙重嵌套的數組一樣簡單,外部的部分和行中的部分。似乎事情比這更棘手。當我檢查fetchedResults NSArray時,我發現它是平坦的。所有的「袋子」項目都是第一個,而「equipable」則是下一個。儘管如此,我不認爲我可以依賴於這種排序,所以我不覺得安全的做一個映射函數,從indexPath部分到數組索引。 (我可以確信對此感到安全)。

另一個我想到的方法是用8個'空'項目填充我的廣告資源,這些項目在部分沒有完全填充時會作爲佔位符結果返回。儘管如此,這並不適合我。

我意識到爲什麼這不起作用:表不應該有'空'行。但我希望我的桌子有空行!

UPDATE

下面是我用現在的方法...

- (NSManagedObject*) carefullyGetObjectAtIndexPath:(NSIndexPath*)indexPath 
{ 
    NSLog(@"in %@ %s", [self class], _cmd); 

    NSString * desiredType = (indexPath.section == BAG_SECTION)? @"bag" : @"equipable"; 
    NSArray * fetchedObjects = [self.fetchedResultsController fetchedObjects]; 
    NSInteger sectionStartIndex = -1; 

    // iterate until you hit a type you like 
    NSUInteger i, count = [fetchedObjects count]; 
    for (i = 0; i < count; i++) { 
    NSObject * obj = [fetchedObjects objectAtIndex:i]; 
    NSString * fetchedType = (NSString*)[obj valueForKey:@"type"]; 

    if ([desiredType isEqualToString:fetchedType]) { 
     sectionStartIndex = i; 
     break; 
    } 
    } 

    if (-1 == sectionStartIndex) { 
    // maybe there aren't any of that type of item 

    } else { 

    NSInteger calculatedEntityIndex = sectionStartIndex + indexPath.row; 
    NSLog(@"calculated index %d", calculatedEntityIndex); 

    // if we are still in the array 
    if (calculatedEntityIndex < [fetchedObjects count]) { 

     // then we can get the object 
     NSManagedObject * entity = [fetchedObjects objectAtIndex:calculatedEntityIndex]; 

     // and if we are still in the right section 
     NSString * typeForEntityAtIndex = [entity valueForKey:@"type"]; 

     if ([desiredType isEqualToString:typeForEntityAtIndex]) { 
     // then this is what we wanted 

     return entity; 
     } 
    } 
    } 

    return nil; 
} 

我真的不覺得我應該要遍歷這樣的事情...

z。

完全披露:這是一個術語項目,但項目是通過任何必要的手段來製作應用程序。這包括第三方庫,提問stackoverflow,& c ...這個術語項目的目標是體驗更大的東西,像一個甜美的應用程序,而不是學習Objective-C的工作。

+0

看這裏定製tableviews,http://cocoawithlove.com/2009/04/easy-custom-uitableview-drawing.html – trumpetlicks

回答

1

齊格,

NSFetchedResultsController有很大的侷限性。如果你不能讓你的模式符合其嚴格的要求,而且看起來你可能沒有,那麼你應該從多個NSFetchRequest中構建tableView。它很簡單。大多數有趣的tableView都是這樣做的。核心數據在您執行較大的讀取操作時效果最佳,然後使用集合類上的集合和過濾操作優化搜索。

tableView s可以有空行。您只需在各種代理和單元配置代碼中將其與自定義代碼進行協調。

你有很多選擇來解決你的問題。看起來你對一個非常有限的框架API不滿意。你是一個萌芽的程序員。滾動你自己的。

Andrew

P.S.您有一個好奇的目標,無需學習Objective-C就可以編寫Mac OS X/iOS應用程序。實際上,您已經選擇了框架中的一項技術,即Core Data,它可以使Objective-C達到其最大能力。 (在我看來,作爲iOS的編程人員的教育,你的教育可能會得到更好的服務學習的一個非常不同的持久性模型,核心數據模型的複雜性,不是退回到平凡的,主流的SQL解決方案。)如果您希望使用不同的語言,MacRuby/RubyMotion相當有效。

+0

大回味無窮!順便說一句,沒有學習目標-C是不是我的目標:我喜歡Objective-C和我喜歡學習新的語言。我只是想澄清的是,回答這個問題不會與作業標籤(因爲這個問題從作業站了起來,本身不是作業)發生衝突。 – Ziggy