I have an Array with content. as usual it contain 20 objects. I want the same array split into 2 sections in Tableview. I am trying to implement it with NSMake in current array. For example I need get in first tableview section 3 rows and second will contain all the rest (17 rows ).
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;
}
Does anyone can help me with that?
NSMakeRange
is defined as (startingIndex, length)
, not (start, end)
which it seems like how you are trying to use it.
So if you need the first 3 objects, then the rest it would look like this:
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;
}
Edit: According to your comment, you are actually looking for the count to return in number of rows in section. Since you are using a fixed number of rows, you can just return the actual number within the case statement.
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;
}
You do not actually need to use [subarrayWithRange]
, nor NSMakeRange
. If you do need to at some point reference the actual array, you will get an NSIndexPath object which you can use to get the object from your array. You will need to use the section and row properties.
Edit: NSRange
-> NSMakeRange
As others have noted you are using NSRange
improperly.
It's definition is
typedef struct _NSRange {
NSUInteger location;
NSUInteger length;
} NSRange;
so the second parameter of the struct is the length of the range, not the location of last element as you apparently think.
That being said, what you are doing it's much more complicated than it should be.
What's the purpose of producing a subarray of a known length and then returning the length of the subarray itself? With this in mind:
return [[array subarrayWithRange:NSMakeRange(3, 8)] count];
should be (using NSRange
properly)
return [[array subarrayWithRange:NSMakeRange(3, 6)] count];
but it can actually be just
return 6;
or if the range length is a parameter
return length;
Again, there's no need in the world to slice an array and count. The length is known a priori.
So in the context of UITableViewDataSource
, you have to
return the count for each section in -tableView:numberOfRowsInSection:
. Something like
switch(section) {
case 0: return 2;
case 1: return 18;
}
return the actual objects in tableView:cellForRowAtIndexPath:
. Something like
id object = nil;
switch (indexPath.section) {
case 0:
object = self.objects[indexPath.row];
break;
case 1:
object = self.objects[2 + indexPath.row];
break;
}
...
As an extra tip, I would advice using a different notation for building structs
NSMakeRange(0, 42)
can be written
(NSRange){ .location = 0, .length = 42 }
which is much more readable (and less error prone, especially when you are in doubt about the meaning of the parameters).
Even
(NSRange){ 0, 42 }
is acceptable. I think it's better (and shorter) than NSMakeRange
, but it loses the benefits or readability.
Ok I have solve my issue
In my Fetcher class I did
_sectionOne = [news objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 3)]];
_sectionTwo = [news objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(3, 17)]];
then
- (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;
}
then in method cellForRowAtIndexPath:
switch (indexPath.section) {
case 0:
item = [_sectionOne objectAtIndex:indexPath.row];
break;
case 1:
item = [_sectionTwo objectAtIndex:indexPath.row];
break;
default:
break;
}
item - it's my NSObject with MVC
So It's working As I wanted :)
Thanks for all trying to help me.
Cheers
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With