Reputation: 119
Here is my code:
Viewcontroller.m
@interface ViewController ()
{
NSArray *sectionTitleArray;
NSMutableArray *arrayForBool;
NSArray *aboutStep0neArray;
NSArray *profileArray;
}
@property (nonatomic, strong) IBOutlet UITableView *tablevw;
- (void)viewDidLoad
{
[super viewDidLoad];
_tablevw.delegate = self;
_tablevw.dataSource = self;
arrayForBool = [[NSMutableArray alloc]init];
sectionTitleArray = @[ @{@"text": @"About Step0ne"},
@{@"text": @"Profile"},
@{@"text": @"Matches"},
@{@"text": @"Messages"},
@{@"text": @"Photos"},
@{@"text": @"Settings"},
@{@"text": @"Privacy"},
@{@"text": @"Reporting issues"},
];
aboutStep0neArray = @[ @{@"text1": @"stepone1"},
@{@"text1": @"stepone2"},
@{@"text1": @"stepone3"},
@{@"text1": @"stepone4"},
@{@"text1": @"stepone5"},
@{@"text1": @"stepone6"},
@{@"text1": @"stepone7"},
@{@"text1": @"stepone8"},
];
profileArray = @[ @{@"text2": @"profile1"},
@{@"text2": @"profile2"},
@{@"text2": @"profile3"},
@{@"text2": @"profile4"},
@{@"text2": @"profile5"},
@{@"text2": @"profile6"},
@{@"text2": @"profile7"},
@{@"text2": @"profile8"},
];
for (int i=0; i<[sectionTitleArray count]; i++)
{
[arrayForBool addObject:[NSNumber numberWithBool:NO]];
}
}
#pragma mark:- UITableView Delegate and Datasource Methods
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return sectionTitleArray.count;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if ([[arrayForBool objectAtIndex:section] boolValue])
{
if (section == 0)
{
return [aboutStep0neArray count];
}
else if (section == 1)
{
return [profileArray count];
}
}
return 1;
}
-(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];
}
BOOL manyCells = [[arrayForBool objectAtIndex:indexPath.section]boolValue];
if (!manyCells)
{
cell.backgroundColor = [UIColor clearColor];
cell.textLabel.text = @"";
}
else
{
if (indexPath.section == 0)
{
cell.textLabel.text = [[aboutStep0neArray objectAtIndex:indexPath.row]objectForKey:@"text1"];
}
else if (indexPath.section == 1)
{
cell.textLabel.text = [[profileArray objectAtIndex:indexPath.row]objectForKey:@"text2"];
}
}
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
/*************** Close the section, once the data is selected ***********************************/
[arrayForBool replaceObjectAtIndex:indexPath.section withObject:[NSNumber
numberWithBool:NO]];
[_tablevw reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section]
withRowAnimation:UITableViewRowAnimationAutomatic];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([[arrayForBool objectAtIndex:indexPath.section] boolValue])
{
return 40;
}
return 0;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 40;
}
#pragma mark - Creating View for TableView Section
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *sectionView=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 280,40)];
sectionView.tag=section;
UILabel *viewLabel=[[UILabel alloc]initWithFrame:CGRectMake(13, 0, _tablevw.frame.size.width-10,
40)];
viewLabel.backgroundColor=[UIColor clearColor];
viewLabel.textColor=[UIColor purpleColor];
viewLabel.font=[UIFont systemFontOfSize:15];
viewLabel.text=[sectionTitleArray objectAtIndex:section];
[sectionView addSubview:viewLabel];
/********** Add a custom Separator with Section view *******************/
UIView* separatorLineView = [[UIView alloc] initWithFrame:CGRectMake(12, 40, _tablevw.frame.size.width-35, 1)];
separatorLineView.backgroundColor = [UIColor purpleColor];
[sectionView addSubview:separatorLineView];
/********** Add UITapGestureRecognizer to SectionView **************/
UITapGestureRecognizer *headerTapped = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(sectionHeaderTapped:)];
[sectionView addGestureRecognizer:headerTapped];
return sectionView;
}
#pragma mark - Table header gesture tapped
- (void)sectionHeaderTapped:(UITapGestureRecognizer *)gestureRecognizer
{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:gestureRecognizer.view.tag];
if (indexPath.row == 0)
{
BOOL collapsed = [[arrayForBool objectAtIndex:indexPath.section] boolValue];
for (int i=0; i<[sectionTitleArray count]; i++)
{
if (indexPath.section==i)
{
[arrayForBool replaceObjectAtIndex:i withObject:[NSNumber numberWithBool:!collapsed]];
}
}
[_tablevw reloadSections:[NSIndexSet indexSetWithIndex:gestureRecognizer.view.tag]
withRowAnimation:UITableViewRowAnimationAutomatic];
}
[_tablevw reloadData];
}
First in tableview sectionTitleArray
objects should display.After that when I click the About Stepone
row it should expand with aboutSteponeArray
objects and after clicking again it should collapse.Same incase of profileArray
too. AboutSteponeArray
and profileArray
are the sections of the sectionTitleArray
.
When I run my code I'm getting:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSDictionaryI rangeOfCharacterFromSet:]: unrecognized selector sent to instance 0x7f9cfb4bf880' error.
Upvotes: 3
Views: 454
Reputation: 3422
Your arrays are incorrectly instanciated : don't add a comma ,
after the last element in each array
sectionTitleArray = @[ @{@"text": @"About Step0ne"},
@{@"text": @"Profile"},
@{@"text": @"Matches"},
@{@"text": @"Messages"},
@{@"text": @"Photos"},
@{@"text": @"Settings"},
@{@"text": @"Privacy"},
@{@"text": @"Reporting issues"}
];
aboutStep0neArray = @[ @{@"text1": @"stepone1"},
@{@"text1": @"stepone2"},
@{@"text1": @"stepone3"},
@{@"text1": @"stepone4"},
@{@"text1": @"stepone5"},
@{@"text1": @"stepone6"},
@{@"text1": @"stepone7"},
@{@"text1": @"stepone8"}
];
profileArray = @[ @{@"text2": @"profile1"},
@{@"text2": @"profile2"},
@{@"text2": @"profile3"},
@{@"text2": @"profile4"},
@{@"text2": @"profile5"},
@{@"text2": @"profile6"},
@{@"text2": @"profile7"},
@{@"text2": @"profile8"}
];
EDIT :
The source of your problem is in - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
at the following line :
viewLabel.text=[sectionTitleArray objectAtIndex:section];
Since each element of your sectionTitleArray
is a NSDictionnary
, you are then assigning a NSDictionnay
to a the label tetxt attribute which is NSString
typed.
Since all the keys in all dictionnaries stored in sectionTitleArray
are @"text"
, replace with the following :
viewLabel.text= [[sectionTitleArray objectAtIndex:section] objectForKey:@"text"];
Upvotes: 2
Reputation: 5602
I checked your code & found few issues. Here is the corrected code:
First Removed Key Values from Array:
sectionTitleArray = [NSArray arrayWithObjects:@"About Step0ne", @"Profile", @"Matches", @"Messages", @"Photos", @"Settings", @"Privacy", @"Reporting issues", nil];
aboutStep0neArray = [NSArray arrayWithObjects:@"stepone1", @"stepone2", @"stepone3", @"stepone4", @"stepone5", @"stepone6", @"stepone7", @"stepone8", nil];
profileArray = [NSArray arrayWithObjects:@"profile1", @"profile2", @"profile3", @"profile4", @"profile5", @"profile6", @"profile7", @"profile8", nil];
Reason: You have given common keys to all objects than why its needed to give keys. That was creating an issue so removed.
Than: In Tableview method:
- (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];
}
BOOL manyCells = [[arrayForBool objectAtIndex:indexPath.section] boolValue];
if (!manyCells) {
cell.backgroundColor = [UIColor clearColor];
cell.textLabel.text = @"";
} else {
if (indexPath.section == 0) {
cell.textLabel.text = [aboutStep0neArray objectAtIndex:indexPath.row];
} else if (indexPath.section == 1) {
cell.textLabel.text = [profileArray objectAtIndex:indexPath.row];
}
}
return cell;
}
This is the only change i have done & tested. It worked fine for me.
Hope it will work for you.
Upvotes: 0