UITableViewCell is choppy when scrolled for Custom Table View Cell - ios

I have a tableview that contains 3 different types of uitableview cell. And it is choppy when i scrolled down or up. I have tried many ways to not make it choppy but fail.
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 44;
self.tableView.estimatedSectionHeaderHeight = 0;
self.tableView.estimatedSectionFooterHeight = 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
CD_Dates *dates = [self.cdMenuStream.dates objectAtIndex:indexPath.section];
MenuTableViewCell *tCell = [self.tableView dequeueReusableCellWithIdentifier:#"MenuTableViewCell" forIndexPath:indexPath];
switch ([self getRowTypeForIndexPath:indexPath]) {
case RowTypeMenu:
[tCell configMenuCell:dates.menu withAnimation:self.switchMenuAnimationFlag];
break;
case RowTypeAddon:
[tCell configAddonCell:dates.addon_menu withAnimation:self.switchMenuAnimationFlag];
break;
case RowTypeContent:
[tCell configContentCell:dates.content];
break;
default:
break;
}
tCell.delegate = self;
tCell.currentIndexPath = indexPath;
if (indexPath.section == 0 && indexPath.row == 0) {
tCell.csMarginTopTitleView.constant = 0;
}
[tCell setNeedsDisplay];
[tCell layoutIfNeeded];
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
cell = tCell;
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGFloat heightRow = 0;
switch ([self getRowTypeForIndexPath:indexPath]) {
case RowTypeMenu:
heightRow = 477.6667;
break;
case RowTypeAddon:
heightRow = 283.6667;
break;
case RowTypeContent:
heightRow = 187.6667;
break;
default:
break;
}
if (heightRow == 0) {
return UITableViewAutomaticDimension;
}
if (indexPath.section == 0 && indexPath.row == 0) {
heightRow = heightRow - 22.5;
}
return heightRow;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(MenuTableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat horizontalOffset = -17.5;
NSString *key = [NSString stringWithFormat:#"%zd %zd", indexPath.section, indexPath.row];
if ([self.contentOffsetDictionary valueForKey:key]) {
horizontalOffset = [self.contentOffsetDictionary[key] floatValue];
}
[cell setNeedsDisplay];
[cell.collectionView setContentOffset:CGPointMake(horizontalOffset, cell.collectionView.contentOffset.y)];
[cell layoutIfNeeded];
}
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat heightRow = 0;
switch ([self getRowTypeForIndexPath:indexPath]) {
case RowTypeMenu:
heightRow = 477.6667;
break;
case RowTypeAddon:
heightRow = 283.6667;
break;
case RowTypeContent:
heightRow = 187.6667;
break;
default:
break;
}
if (heightRow == 0) {
return UITableViewAutomaticDimension;
}
if (indexPath.section == 0 && indexPath.row == 0) {
heightRow = heightRow - 22.5;
}
return heightRow;
}
It is a tableview wrapped with a custom tableview cell, and that each custom tableview cell has a collection view. It is not choppy if i scroll the collection view in the custom tableview cell, but it is when i scroll the tableview. Is there any ways we can make it not choppy, thanks.

I think you should go with the sizing cell.
https://www.raywenderlich.com/129059/self-sizing-table-view-cells
Please try with this or share the cell's .xib files so that automatic sizing will be enabled.

Related

UITableView with customcell

i am developing an iPhone app with tableview that act as a form with different sections. i also have 3 custom cell that contain Text Field, Segment Control and UISwitchView. my problem is that when i pressed on of the Switches or type some text in one of the textField, the same state of the Switch or text of the text Field reappear in different row and in different section.
Here is some images and part of my code to describe my problem:
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 3;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger rows = 0;
switch (section) {
case 0:
rows = 5;
break;
case 1:
rows = 11;
break;
case 2:
rows = 9;
break;
default:
break;
}
return rows;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
// init cell
switch (indexPath.section) {
case 0:
if (indexPath.row>=0 && indexPath.row<=3)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"text_field_cell"];
}
else if (indexPath.row == 4)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"segment_cell"];
}
break;
case 1:
if (indexPath.row >=0 && indexPath.row <= 9)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"switch_cell"];
}
else if (indexPath.row == 10)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"text_field_cell"];
}
break;
case 2:
if (indexPath.row >=0 && indexPath.row <= 6)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"switch_cell"];
}
else if (indexPath.row >=7 && indexPath.row <=8)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"text_field_cell"];
}
break;
default:
break;
}
// init all text ..
return cell;
}
I would implement -tableView:willDisplayCell:forRowAtIndexPath: to set your cells to a correct state for each row.

Attempting to add an inline UIDatePicker to a UITableViewCell

I'm attempting to create an inline DatePicker inside a TableView cell, similar to this and this SO thread.
I create the date picker using the method below, which is called when the view is loaded:
- (void)createDatePicker{
_datePicker = [[UIDatePicker alloc]init];
_datePicker.datePickerMode = UIDatePickerModeTime;
_datePicker.clipsToBounds = YES;
_datePicker.backgroundColor = [UIColor colorWithRed:0.922 green:0.937 blue:0.949 alpha:1];
NSLog(#"date picker created");
}
I then check to see if the bottom row of the third section in my table view is selected. If it is, and the date picker already isn't showing, then I call the method to show the date picker's cell:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == HourTimeZoneRow && self.datePickerIsShowing == NO)
{
NSLog(#"Time of day section");
[self showDatePickerCell];
} else
{
[self hideDatePickerCell];
}
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}
Below are the methods to show the date picker's cell:
- (void)showDatePickerCell {
[self.tableView addSubview:_datePicker];
self.datePickerIsShowing = YES;
self.datePicker.hidden = NO;
[self.tableView reloadData];
NSLog(#"Show date picker");
}
...and hide the cell:
- (void)hideDatePickerCell {
self.datePickerIsShowing = NO;
self.datePicker.hidden = YES;
[self.tableView reloadData];
NSLog(#"Hide date picker");
}
Below is the method to determine if the table view needs to add an extra cell to display the UIDatePicker.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
switch (section) {
case TableSectionOne:
return TotalRowsSection1;
break;
case TableSectionTwo:
return TotalRedZoneRows;
break;
case TableSectionThree:
if (self.datePickerIsShowing == YES) {
return TableSectionThree + 1;
}
else {
return TableSectionThree;
}
break;
default:
return 0;
break;
}
}
Finally, the method below is what is supposed to determine the height of the date picker's cell:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGFloat rowHeight = self.tableView.rowHeight;
if (indexPath.row == HourTimeZoneRow){
rowHeight = 164;
}
else {
rowHeight = self.tableView.rowHeight;
}
return rowHeight;
}
However, what's happening is that when the last row of the third section is selected, the date picker is displayed in the first row of the first section. Does anyone have any suggestions on what I'm doing wrong?
You're adding the datePicker to the tableView, not to a cell within the tableView.
Remove this line from showDatePickerCell:
[self.tableView addSubview:_datePicker];
Then add it (or unhide it) within the proper cell within cellForItemAtIndexPath.
(something like:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
if (indexPath.row == HourTimeZoneRow) {
// show the datePicker here
}
cell.textLabel.text = [tableData objectAtIndex:indexPath.row];
return cell;
}
)

UITableViewCell - check mark retained for selected row

This is a follow-up question to UITableViewCell - check mark one row per section.
Here I have 2 sections with 3 rows each as follow:
SEARCH DISTANCE
250 feet
1000 feet
4000 feet
MAP TYPE
Standard
Satellite
Hybrid
I have a problem in section2(MAP TYPE). I want to have 'standard' checked as default and whatever option user chooses later on can be saved and passed on to another view controller which contains map view to display according to map type selected. My current code does not allow me to do so for section2. Anyone, please help check my code and suggest me what need to be added/modified?
I've been trying to learn how it works for section1(SEARCH DISTANCE) but I just don't quite get it. It seems to involve delegate file to do cache things.
Here my code is:
#import "PAWSettingsViewController.h"
#import "PAWAppDelegate.h"
#import <Parse/Parse.h>
#interface PAWSettingsViewController ()
- (NSString *)distanceLabelForCell:(NSIndexPath *)indexPath;
- (PAWLocationAccuracy)distanceForCell:(NSIndexPath *)indexPath;
- (NSString *)maptypeLabelForCell:(NSIndexPath *)indexPath;
- (PAWMaptypeSelect)maptypeForCell:(NSIndexPath *)indexPath;
#property (nonatomic, assign) CLLocationAccuracy filterDistance;
#end
typedef enum {
kPAWSettingsTableViewDistance = 0,
kPAWSettingsTableViewMaptype,
kPAWSettingsTableViewNumberOfSections
} kPAWSettingsTableViewSections;
typedef enum {
kPAWSettingsTableViewDistanceSection250FeetRow = 0,
kPAWSettingsTableViewDistanceSection1000FeetRow,
kPAWSettingsTableViewDistanceSection4000FeetRow,
kPAWSettingsTableViewDistanceNumberOfRows
} kPAWSettingsTableViewDistanceSectionRows;
typedef enum {
kPAWSettingsTableViewMaptypeSectionStandardRow = 0,
kPAWSettingsTableViewMaptypeSectionSatelliteRow,
kPAWSettingsTableViewMaptypeSectionHybridRow,
kPAWSettingsTableViewMaptypeNumberOfRows
} kPAWSettingsTableViewMaptypeSectionRows;
#implementation PAWSettingsViewController
#synthesize tableView;
#synthesize filterDistance;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
PAWAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
self.filterDistance = appDelegate.filterDistance;
}
return self;
}
#pragma mark - Custom setters
// Always fault our filter distance through to the app delegate. We just cache it locally because it's used in the tableview's cells.
- (void)setFilterDistance:(CLLocationAccuracy)aFilterDistance {
PAWAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
appDelegate.filterDistance = aFilterDistance;
filterDistance = aFilterDistance;
}
#pragma mark - View lifecycle
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Private helper methods
- (NSString *)distanceLabelForCell:(NSIndexPath *)indexPath {
NSString *cellText = nil;
switch (indexPath.row) {
case kPAWSettingsTableViewDistanceSection250FeetRow:
cellText = #"250 feet";
break;
case kPAWSettingsTableViewDistanceSection1000FeetRow:
cellText = #"1000 feet";
break;
case kPAWSettingsTableViewDistanceSection4000FeetRow:
cellText = #"4000 feet";
break;
case kPAWSettingsTableViewDistanceNumberOfRows: // never reached.
default:
cellText = #"The universe";
break;
}
return cellText;
}
- (PAWLocationAccuracy)distanceForCell:(NSIndexPath *)indexPath {
PAWLocationAccuracy distance = 0.0;
switch (indexPath.row) {
case kPAWSettingsTableViewDistanceSection250FeetRow:
distance = 250;
break;
case kPAWSettingsTableViewDistanceSection1000FeetRow:
distance = 1000;
break;
case kPAWSettingsTableViewDistanceSection4000FeetRow:
distance = 4000;
break;
case kPAWSettingsTableViewDistanceNumberOfRows: // never reached.
default:
distance = 10000 * kPAWFeetToMiles;
break;
}
return distance;
}
- (NSString *)maptypeLabelForCell:(NSIndexPath *)indexPath {
NSString *cellText = nil;
switch (indexPath.row) {
case kPAWSettingsTableViewMaptypeSectionStandardRow:
cellText = #"Standard";
break;
case kPAWSettingsTableViewMaptypeSectionSatelliteRow:
cellText = #"Satellite";
break;
case kPAWSettingsTableViewMaptypeSectionHybridRow:
cellText = #"Hybrid";
break;
case kPAWSettingsTableViewMaptypeNumberOfRows: // never reached.
default:
cellText = #"?";
break;
}
return cellText;
}
- (PAWMaptypeSelect)maptypeForCell:(NSIndexPath *)indexPath {
PAWMaptypeSelect maptype = nil;
switch (indexPath.row) {
case kPAWSettingsTableViewMaptypeSectionStandardRow:
maptype = #"Standard";
break;
case kPAWSettingsTableViewMaptypeSectionSatelliteRow:
maptype = #"Satellite";
break;
case kPAWSettingsTableViewMaptypeSectionHybridRow:
maptype = #"Hybrid";
break;
case kPAWSettingsTableViewMaptypeNumberOfRows: // never reached.
default:
maptype = nil;
break;
}
return maptype;
}
#pragma mark - UINavigationBar-based actions
- (IBAction)done:(id)sender {
[self.presentingViewController dismissModalViewControllerAnimated:YES];
}
#pragma mark - UITableViewDataSource methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return kPAWSettingsTableViewNumberOfSections;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
switch ((kPAWSettingsTableViewSections)section) {
case kPAWSettingsTableViewDistance:
return kPAWSettingsTableViewDistanceNumberOfRows;
break;
case kPAWSettingsTableViewMaptype:
return kPAWSettingsTableViewMaptypeNumberOfRows;
break;
case kPAWSettingsTableViewNumberOfSections:
return 0;
break;
};
}
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = #"SettingsTableView";
if (indexPath.section == kPAWSettingsTableViewDistance) {
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:identifier];
if ( cell == nil )
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier];
}
// Configure the cell.
cell.tag = indexPath.section;
cell.textLabel.text = [self distanceLabelForCell:indexPath];
if (self.filterDistance == 0.0) {
NSLog(#"We have a zero filter distance!");
}
PAWLocationAccuracy filterDistanceInFeet = self.filterDistance * ( 1 / kPAWFeetToMeters);
PAWLocationAccuracy distanceForCell = [self distanceForCell:indexPath];
if (abs(distanceForCell - filterDistanceInFeet) < 0.001 ) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
} else if (indexPath.section == kPAWSettingsTableViewMaptype){
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:identifier];
if ( cell == nil )
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier];
}
// Configure the cell.
cell.tag = indexPath.section;
cell.textLabel.text = [self maptypeLabelForCell:indexPath];
//**** I don't know how to do here? ****
return cell;
} else {
return nil;
}
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
switch ((kPAWSettingsTableViewSections)section) {
case kPAWSettingsTableViewDistance:
return #"Search Distance";
break;
case kPAWSettingsTableViewMaptype:
return #"Map Type";
break;
case kPAWSettingsTableViewNumberOfSections:
return #"";
break;
}
}
#pragma mark - UITableViewDelegate methods
// Called after the user changes the selection.
- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == kPAWSettingsTableViewDistance) {
[aTableView deselectRowAtIndexPath:indexPath animated:YES];
// if we were already selected, bail and save some work.
UITableViewCell *selectedCell = [aTableView cellForRowAtIndexPath:indexPath];
if (selectedCell.accessoryType == UITableViewCellAccessoryCheckmark) {
return;
}
// uncheck all visible cells.
for (UITableViewCell *cell in [aTableView visibleCells]) {
if (cell.accessoryType != UITableViewCellAccessoryNone && cell.tag == indexPath.section) {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;
PAWLocationAccuracy distanceForCellInFeet = [self distanceForCell:indexPath];
self.filterDistance = distanceForCellInFeet * kPAWFeetToMeters;
}
else if (indexPath.section == kPAWSettingsTableViewMaptype){
[aTableView deselectRowAtIndexPath:indexPath animated:YES];
// if we were already selected, bail and save some work.
UITableViewCell *selectedCell = [aTableView cellForRowAtIndexPath:indexPath];
if (selectedCell.accessoryType == UITableViewCellAccessoryCheckmark) {
return;
}
// uncheck all visible cells.
for (UITableViewCell *cell in [aTableView visibleCells]) {
if (cell.accessoryType != UITableViewCellAccessoryNone && cell.tag == indexPath.section) {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;
//**** I don't know how to do here? ****
}
}
#end
Use an bool variable. Like isFirstTime.
and then in viewDidLoad: initilize your isFirstTime variable as YES.
isFirstTime = YES;
in your
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
update this part
else if (indexPath.section == kPAWSettingsTableViewMaptype){
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:identifier];
if ( cell == nil )
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier];
}
if ( isFirstTime == YES && indexPath.row == 0)
{
} // Configure the cell.
cell.tag = indexPath.section;
cell.textLabel.text = [self maptypeLabelForCell:indexPath];
//**** I don't know how to do here? ****
return cell;
}
I have figured out my own question. I decided to go for global variable to save selected choice in section2.
I declared global variable in .m file:
int gmaptypeSelected;
In cellForRowAtOIndexPath section I put a condition like this:
else if (indexPath.section == kPAWSettingsTableViewMaptype){
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:identifier];
if ( cell == nil )
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier];
}
// Configure the cell.
cell.tag = indexPath.section;
cell.textLabel.text = [self maptypeLabelForCell:indexPath];
MKMapType maptypeForCell = [self maptypeForCell:indexPath];
if (maptypeForCell == gmaptypeSelected) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
And in MapView Controller > viewWillAppear will look like this:
- (void)viewWillAppear:(BOOL)animated {
extern int gmaptypeSelected;
if (gmaptypeSelected == 0) {
self.mapView.mapType = MKMapTypeStandard;
} else if (gmaptypeSelected == 1) {
self.mapView.mapType = MKMapTypeSatellite;
} else if (gmaptypeSelected == 2) {
self.mapView.mapType = MKMapTypeHybrid;
}
[locationManager startUpdatingLocation];
[super viewWillAppear:animated];
}

UITableViewCell - check mark one row per section

I have 2 sections and 3 rows each as follow:
SEARCH DISTANCE
250 feet
1000 feet
4000 feet
MAP TYPE
Standard
Satellite
Hybrid
I want to have one check mark for a row per section but my current code will uncheck all visible cells for the entire table view and leave one selected row with check mark. In other word, I will have one check mark for the entire table (2 sections). Here I posted my entire code. I have google'd many but there seems none to resolve my problem. Anyone, please help correct my code. Thanks in advance.
#import "PAWSettingsViewController.h"
#import "PAWAppDelegate.h"
#import <Parse/Parse.h>
#interface PAWSettingsViewController ()
- (NSString *)distanceLabelForCell:(NSIndexPath *)indexPath;
- (PAWLocationAccuracy)distanceForCell:(NSIndexPath *)indexPath;
- (NSString *)maptypeLabelForCell:(NSIndexPath *)indexPath;
- (PAWMaptypeSelect)maptypeForCell:(NSIndexPath *)indexPath;
#property (nonatomic, assign) CLLocationAccuracy filterDistance;
#end
typedef enum {
kPAWSettingsTableViewDistance = 0,
kPAWSettingsTableViewMaptype,
kPAWSettingsTableViewNumberOfSections
} kPAWSettingsTableViewSections;
typedef enum {
kPAWSettingsTableViewDistanceSection250FeetRow = 0,
kPAWSettingsTableViewDistanceSection1000FeetRow,
kPAWSettingsTableViewDistanceSection4000FeetRow,
kPAWSettingsTableViewDistanceNumberOfRows
} kPAWSettingsTableViewDistanceSectionRows;
typedef enum {
kPAWSettingsTableViewMaptypeSectionStandardRow = 0,
kPAWSettingsTableViewMaptypeSectionSatelliteRow,
kPAWSettingsTableViewMaptypeSectionHybridRow,
kPAWSettingsTableViewMaptypeNumberOfRows
} kPAWSettingsTableViewMaptypeSectionRows;
#implementation PAWSettingsViewController
#synthesize tableView;
#synthesize filterDistance;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
PAWAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
self.filterDistance = appDelegate.filterDistance;
}
return self;
}
#pragma mark - Custom setters
// Always fault our filter distance through to the app delegate. We just cache it locally because it's used in the tableview's cells.
- (void)setFilterDistance:(CLLocationAccuracy)aFilterDistance {
PAWAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
appDelegate.filterDistance = aFilterDistance;
filterDistance = aFilterDistance;
}
#pragma mark - View lifecycle
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Private helper methods
- (NSString *)distanceLabelForCell:(NSIndexPath *)indexPath {
NSString *cellText = nil;
switch (indexPath.row) {
case kPAWSettingsTableViewDistanceSection250FeetRow:
cellText = #"250 feet";
break;
case kPAWSettingsTableViewDistanceSection1000FeetRow:
cellText = #"1000 feet";
break;
case kPAWSettingsTableViewDistanceSection4000FeetRow:
cellText = #"4000 feet";
break;
case kPAWSettingsTableViewDistanceNumberOfRows: // never reached.
default:
cellText = #"The universe";
break;
}
return cellText;
}
- (PAWLocationAccuracy)distanceForCell:(NSIndexPath *)indexPath {
PAWLocationAccuracy distance = 0.0;
switch (indexPath.row) {
case kPAWSettingsTableViewDistanceSection250FeetRow:
distance = 250;
break;
case kPAWSettingsTableViewDistanceSection1000FeetRow:
distance = 1000;
break;
case kPAWSettingsTableViewDistanceSection4000FeetRow:
distance = 4000;
break;
case kPAWSettingsTableViewDistanceNumberOfRows: // never reached.
default:
distance = 10000 * kPAWFeetToMiles;
break;
}
return distance;
}
- (NSString *)maptypeLabelForCell:(NSIndexPath *)indexPath {
NSString *cellText = nil;
switch (indexPath.row) {
case kPAWSettingsTableViewMaptypeSectionStandardRow:
cellText = #"Standard";
break;
case kPAWSettingsTableViewMaptypeSectionSatelliteRow:
cellText = #"Satellite";
break;
case kPAWSettingsTableViewMaptypeSectionHybridRow:
cellText = #"Hybrid";
break;
case kPAWSettingsTableViewMaptypeNumberOfRows: // never reached.
default:
cellText = #"?";
break;
}
return cellText;
}
- (PAWMaptypeSelect)maptypeForCell:(NSIndexPath *)indexPath {
PAWMaptypeSelect maptype = nil;
switch (indexPath.row) {
case kPAWSettingsTableViewMaptypeSectionStandardRow:
maptype = #"Standard";
break;
case kPAWSettingsTableViewMaptypeSectionSatelliteRow:
maptype = #"Satellite";
break;
case kPAWSettingsTableViewMaptypeSectionHybridRow:
maptype = #"Hybrid";
break;
case kPAWSettingsTableViewMaptypeNumberOfRows: // never reached.
default:
maptype = nil;
break;
}
return maptype;
}
#pragma mark - UINavigationBar-based actions
- (IBAction)done:(id)sender {
[self.presentingViewController dismissModalViewControllerAnimated:YES];
}
#pragma mark - UITableViewDataSource methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return kPAWSettingsTableViewNumberOfSections;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
switch ((kPAWSettingsTableViewSections)section) {
case kPAWSettingsTableViewDistance:
return kPAWSettingsTableViewDistanceNumberOfRows;
break;
case kPAWSettingsTableViewMaptype:
return kPAWSettingsTableViewMaptypeNumberOfRows;
break;
case kPAWSettingsTableViewNumberOfSections:
return 2;
break;
};
}
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = #"SettingsTableView";
if (indexPath.section == kPAWSettingsTableViewDistance) {
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:identifier];
if ( cell == nil )
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier];
}
// Configure the cell.
cell.textLabel.text = [self distanceLabelForCell:indexPath];
if (self.filterDistance == 0.0) {
NSLog(#"We have a zero filter distance!");
}
PAWLocationAccuracy filterDistanceInFeet = self.filterDistance * ( 1 / kPAWFeetToMeters);
PAWLocationAccuracy distanceForCell = [self distanceForCell:indexPath];
if (abs(distanceForCell - filterDistanceInFeet) < 0.001 ) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
else if (indexPath.section == kPAWSettingsTableViewMaptype){
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:identifier];
if ( cell == nil )
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier];
}
// Configure the cell.
cell.textLabel.text = [self maptypeLabelForCell:indexPath];
return cell;
}
else {
return nil;
}
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
switch ((kPAWSettingsTableViewSections)section) {
case kPAWSettingsTableViewDistance:
return #"Search Distance";
break;
case kPAWSettingsTableViewMaptype:
return #"Map Type";
break;
case kPAWSettingsTableViewNumberOfSections:
return #"";
break;
}
}
#pragma mark - UITableViewDelegate methods
// Called after the user changes the selection.
- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == kPAWSettingsTableViewDistance) {
[aTableView deselectRowAtIndexPath:indexPath animated:YES];
// if we were already selected, bail and save some work.
UITableViewCell *selectedCell = [aTableView cellForRowAtIndexPath:indexPath];
if (selectedCell.accessoryType == UITableViewCellAccessoryCheckmark) {
return;
}
// uncheck all visible cells.
for (UITableViewCell *cell in [aTableView visibleCells]) {
if (cell.accessoryType != UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;
PAWLocationAccuracy distanceForCellInFeet = [self distanceForCell:indexPath];
self.filterDistance = distanceForCellInFeet * kPAWFeetToMeters;
}
else if (indexPath.section == kPAWSettingsTableViewMaptype){
[aTableView deselectRowAtIndexPath:indexPath animated:YES];
// if we were already selected, bail and save some work.
UITableViewCell *selectedCell = [aTableView cellForRowAtIndexPath:indexPath];
if (selectedCell.accessoryType == UITableViewCellAccessoryCheckmark) {
return;
}
// uncheck all visible cells.
for (UITableViewCell *cell in [aTableView visibleCells]) {
if (cell.accessoryType != UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;
PAWMaptypeSelect maptypeForCell = [self maptypeForCell:indexPath];
}
}
#end
you have an error with this
// uncheck all visible cells.
for (UITableViewCell *cell in [aTableView visibleCells]) {
if (cell.accessoryType != UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
Here the for loop deselect all the cell. you have to check also the section in if loop
you can set tag for your cell like this
cell.tag = indexPath.section;
and in for loop if condition is
for (UITableViewCell *cell in [aTableView visibleCells]) {
if (cell.accessoryType != UITableViewCellAccessoryNone && cell.tag == indexPath.section) {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
problem in your code is that You only checkmark row for section 0 by replace below method you can solved your problem.
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = #"SettingsTableView";
if (indexPath.section == kPAWSettingsTableViewDistance) {
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:identifier];
if ( cell == nil )
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier];
}
// Configure the cell.
cell.textLabel.text = [self distanceLabelForCell:indexPath];
if (self.filterDistance == 0.0) {
NSLog(#"We have a zero filter distance!");
}
PAWLocationAccuracy filterDistanceInFeet = self.filterDistance * ( 1 / kPAWFeetToMeters);
PAWLocationAccuracy distanceForCell = [self distanceForCell:indexPath];
if (abs(distanceForCell - filterDistanceInFeet) < 0.001 ) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
else if (indexPath.section == kPAWSettingsTableViewMaptype){
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:identifier];
if ( cell == nil )
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:identifier];
}
// Configure the cell.
cell.textLabel.text = [self maptypeLabelForCell:indexPath];
PAWLocationAccuracy filterDistanceInFeet = self.filterDistance * ( 1 / kPAWFeetToMeters);
PAWLocationAccuracy distanceForCell = [self distanceForCell:indexPath];
if (abs(distanceForCell - filterDistanceInFeet) < 0.001 ) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
else {
return nil;
}
}
For now I have found the following bugs
You don't save which cell is selected for map type.
The way how you checkmark your cell is incorrect.
In switch you don't have to use break after return statement
In case kPAWSettingsTableViewNumberOfSections: you should return kPAWSettingsTableViewNumberOfSections
First two defects causes many boilerplate code. I think you should store the NSIndexPath's for each section that is selected as additional #property. Instead of unchecking all and checking tapped, you can do in tableView:didSelectRowAtIndexPath::
Determine which one should be selected.
Store local old value of your selectedIndexPath.
Change selectedIndexPath proprty to new one.
Reload both rows.
Then you have to add in tableView:cellForRowAtIndexPath: the following code:
if (indexPath.row == self.selectedIndexPath.row && indexPath.section == self.selectedIndexPath.section) {
// Change to checkmark.
} else {
// Change to not checked.
}
I got very similar way to checkmark cell in my own project. I hope the code below also will help you understand my way to fix your problem:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (/*condition*/) {
[...]
}
else if (/*checkmark section*/) {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CheckmarkCellId forIndexPath:indexPath];
cell.textLabel.text = [self labelForRow:indexPath.row];
cell.accessoryType = (indexPath.row == [self defaultAgglomerationIndex]) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
cell.imageView.image = (indexPath.row == [self selectedAgglomerationIndex]) ? [UIImage imageNamed:#"icoMap"] : [UIImage imageNamed:#"region"];
return cell;
}
else if (/*Another condition */) {
[...]
}
return nil;
}
And essencial code in tableView:didSelectRowAtIndexPath: (I reload whole section)
self.selectedIndex = indexPath;
NSIndexSet *set = [NSIndexSet indexSetWithIndex:indexPath.section];
[self.tableView reloadSections:set withRowAnimation:UITableViewRowAnimationNone];
Try this, worked just fine for me:
-VARIABLES:
#property NSInteger checkedCellRow;
#property NSInteger checkedCellSection;
-FUNCTIONS:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (checkedCellSection == indexPath.section)
{
if (checkedCellRow == indexPath.row)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
checkedCellRow = indexPath.row;
checkedCellSection = indexPath.section;
[myTable reloadData];
}

Trying to add sections with headers to UITableViewController (iOS)

I'm still very new to objective-c, and I've looked all for an answer. I haven't been able to successfully implement anything I've found yet. I'm using an open source sliding menu that I found, and I haven't found anything that fits within the code it uses. (I'd post a link to it, but I can't remember where I found it.)
EDIT: I've got the sections added. Now, I just need to make it so the first cell in the second section only shows up in the first section. http://i.imgur.com/gSIRNJ3.png
I've updated the code below. Here's a reference of what I'm trying to do. Right now, cell 1 shows up in both section 1 and section 2.
SECTION 1: (no header)
- cell 1: "Search Nouns"
SECTION 2: "Noun Conjugation"
- cell 2: "Regular Nouns"
- cell 3: "Irregular Nouns"
- cell 4: "Uncountable Nouns"
#import "BaseTableViewController.h"
#import "KYSlideMenuViewController.h"
#interface BaseTableViewController () {
int _currentCtrNum;
}
#end
#implementation BaseTableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// 最初に表示するビューを設定する
_currentCtrNum = -1;
NSIndexPath *path = [NSIndexPath indexPathForRow:0 inSection:0];
[self tableView:self.tableView didSelectRowAtIndexPath:path];
}
#pragma mark -
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2 ;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(section == 0)
return 1;
else
return 4;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
if(section==0)
return 0;
else
return 25;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if (section == 0)
return #"";
else
return #"reference";
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
switch (indexPath.row) {
case 0:
cell.textLabel.text = #"名詞検索";
break;
case 1:
cell.textLabel.text = #"Side B";
break;
case 2:
cell.textLabel.text = #"Side C";
break;
case 3:
cell.textLabel.text = #"Side D";
default:
break;
}
cell.backgroundColor = [UIColor grayColor];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
for (int i = 0 ; i < [tableView numberOfRowsInSection:0] ; i++) {
NSIndexPath *path = [NSIndexPath indexPathForRow:i inSection:0];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:path];
if (i == indexPath.row) {
cell.textLabel.textColor = [UIColor whiteColor];
} else {
cell.textLabel.textColor = [UIColor blackColor];
}
}
// 現在のビューコントローラなら表示するだけ
if (_currentCtrNum == indexPath.row) {
[(KYSlideMenuViewController *)self.parentViewController slideChildTo:KYS_CLOSE];
return;
}
_currentCtrNum = (int)indexPath.row;
// 新しいビューコントローラを生成してコンテナのビューコントローラを入れ替え
UIViewController *toCtr;
switch (indexPath.row) {
case 0: // noun search
toCtr = [[self storyboard] instantiateViewControllerWithIdentifier:#"itemTableView"];
break;
case 1: // navigationあり
toCtr = [[self storyboard] instantiateViewControllerWithIdentifier:#"mainView"];
break;
case 2: // navigationなし
toCtr = [[self storyboard] instantiateViewControllerWithIdentifier:#"subView"];
break;
case 3: // navigationあり
toCtr = [[self storyboard] instantiateViewControllerWithIdentifier:#"srdView"];
break;
default:
return;
}
[(KYSlideMenuViewController *)self.parentViewController changeTo:toCtr];
}
#end
There also supposed to be a delegate for numberOfSectionsInTableView: where you would return 2;

Resources