コンテンツを含む配列があります。通常どおり、20個のオブジェクトが含まれています。 Tableviewで同じ配列を2つのセクションに分割したい。現在の配列でNSMakeを使用して実装しようとしています。たとえば、最初のテーブルビューセクションで3行取得する必要があり、2番目には残りのすべて(17行)が含まれます。
switch (section) {
case 0:
return
[[array subarrayWithRange:NSMakeRange(3, 8)] count];
// in this line, it always takes from the first object in array, despite I told hime start from 3 (If I understand right, how to works NSMakeRange)
break;
case 1:
return
[[array subarrayWithRange:NSMakeRange(9, 19)] count];
// here my app is crashing with an error
//*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSArray subarrayWithRange:]: range {9, 19} extends beyond bounds [0 .. 19]'
default:
break;
}
誰かがそれを手伝ってくれる?
NSMakeRange
は(startingIndex, length)
ではなく(start, end)
として定義されています。
したがって、最初の3つのオブジェクトが必要な場合、残りは次のようになります。
switch (section) {
case 0:
// This returns objects 0-2 in the array
return [array subarrayWithRange:NSMakeRange(0, 3)];
case 1:
// This returns objects 3-20 in the array
return [array subarrayWithRange:NSMakeRange(3, 17)];
default:
break;
}
編集:コメントによると、実際にはセクションの行数で返されるカウントを探しています。固定数の行を使用しているため、caseステートメント内で実際の数を返すことができます。
switch (section) {
case 0:
// This returns the count for objects 0-2 in the array
return 3;
case 1:
// This returns the count for objects 3-20 in the array
return 17;
default:
break;
}
実際には[subarrayWithRange]
やNSMakeRange
を使用する必要はありません。ある時点で実際の配列を参照する必要がある場合は、配列からオブジェクトを取得するために使用できるNSIndexPathオブジェクトを取得します。セクションと行のプロパティを使用する必要があります。
編集:NSRange
-> NSMakeRange
他の人がNSRange
を不適切に使用していると述べているように。
定義は
typedef struct _NSRange {
NSUInteger location;
NSUInteger length;
} NSRange;
したがって、構造体の2番目のパラメーターは範囲の長さであり、見たところの最後の要素の場所ではありません。
そうは言っても、あなたがやっていることは、本来あるべきよりもはるかに複雑です。
既知の長さのサブ配列を作成し、サブ配列自体の長さを返す目的は何ですか?これを考慮して:
return [[array subarrayWithRange:NSMakeRange(3, 8)] count];
(正しくNSRange
を使用)
return [[array subarrayWithRange:NSMakeRange(3, 6)] count];
しかし、実際には
return 6;
または範囲の長さがパラメータの場合
return length;
ここでも、配列をスライスしてカウントする必要はありません。長さは事前にわかっています。
したがって、UITableViewDataSource
のコンテキストでは、
各セクションの数を-tableView:numberOfRowsInSection:
に返します。何かのようなもの
switch(section) {
case 0: return 2;
case 1: return 18;
}
実際のオブジェクトをtableView:cellForRowAtIndexPath:
に返します。何かのようなもの
id object = nil;
switch (indexPath.section) {
case 0:
object = self.objects[indexPath.row];
break;
case 1:
object = self.objects[2 + indexPath.row];
break;
}
...
追加のヒントとして、構造体の構築に別の表記法を使用することをお勧めします
NSMakeRange(0, 42)
書くことができます
(NSRange){ .location = 0, .length = 42 }
これは非常に読みやすくなっています(特に、パラメータの意味に疑問がある場合は、エラーが発生しにくくなります)。
でも
(NSRange){ 0, 42 }
許容範囲です。 NSMakeRange
よりは良い(そして短い)と思いますが、利点や読みやすさが失われます。
問題は解決しました
私のFetcherクラスでは
_sectionOne = [news objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 3)]];
_sectionTwo = [news objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(3, 17)]];
その後
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
switch (section) {
case 0:
return [_sectionOne count];
break;
case 1:
return [_sectionTwo count];
break;
default:
break;
}
return 0;
}
次に、メソッドcellForRowAtIndexPathで:
switch (indexPath.section) {
case 0:
item = [_sectionOne objectAtIndex:indexPath.row];
break;
case 1:
item = [_sectionTwo objectAtIndex:indexPath.row];
break;
default:
break;
}
アイテム-MVCを使用したNSObjectです
だからそれは私が望んだように働いています:)
助けてくれてありがとう。
乾杯