How to create a subarray of NSArray using NSRange?
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 likeswitch(section) { case 0: return 2; case 1: return 18;}
return the actual objects in
tableView:cellForRowAtIndexPath:
. Something likeid 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