Delegate methods of UITableView are not responding - iphone

I am quite new to IOS development, so forgive me if this problem turns out to be trivial. The following is the case:
I want to be able to call the didSelectRowAtIndexPath method to trigger some action when a user interacts with a table view cell. However, it seems that this method is never called for some reason. I am fairly certain that my code is valid. I set the delegate and dataSource properties and I conform to the UITableViewDelegate and UITableViewDataSource protocols.
If someone could shed some light on this, I would be very grateful.
My code:
#import <UIKit/UIKit.h>
#import <MessageUI/MessageUI.h>
#class Employee;
#define kTelephoneRowIndex 0
#define kEmailRowIndex 1
#define kLeftLabelTag 4096
#define kRightLabelTag 4097
#interface PersonnelDetailsViewController : UIViewController <UITableViewDelegate,
UITableViewDataSource, MFMailComposeViewControllerDelegate> {
UITableView *contactDetailsTable;
Employee *employee;
}
#property (nonatomic, retain) UITableView *contactDetailsTable;
#property (nonatomic, retain) Employee *employee;
+ (NSString *)resourceFilePath:(NSString *)fileName ofType:(NSString *)type;
#end
and my .m file
#import <QuartzCore/QuartzCore.h>
#import "PersonnelDetailsViewController.h"
#import "Employee.h"
#implementation PersonnelDetailsViewController
#synthesize contactDetailsTable, employee;
+ (NSString *)resourceFilePath:(NSString *)fileName ofType:(NSString *)type {
return [[NSBundle mainBundle] pathForResource:fileName ofType:type];
}
- (void)loadView {
[super loadView];
// Create the header view for the table view
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 110)];
// Set the image, using rounded corners
UIImage *employeeImage;
if ([employee.image length] == 0)
employeeImage = [UIImage imageNamed:#"logoL1nda70by80"];
else
employeeImage = [UIImage imageNamed:employee.image];
UIImageView *employeeImageView = [[UIImageView alloc] initWithImage:employeeImage];
employeeImageView.frame = CGRectMake(10, 15, 70, 80);
employeeImageView.layer.masksToBounds = YES;
employeeImageView.layer.cornerRadius = 5.0;
employeeImageView.layer.borderWidth = 1.0;
employeeImageView.layer.borderColor = [[UIColor grayColor] CGColor];
[headerView addSubview:employeeImageView];
UILabel *nameView = [[UILabel alloc] initWithFrame:CGRectMake(95, 35, 180, 20)];
nameView.text = employee.name;
nameView.font = [UIFont boldSystemFontOfSize:18];
[headerView addSubview:nameView];
UILabel *functionView = [[UILabel alloc] initWithFrame:CGRectMake(95, 55, 140, 16)];
functionView.text = employee.function;
functionView.textColor = [UIColor grayColor];
functionView.font = [UIFont systemFontOfSize:14];
[headerView addSubview:functionView];
[employeeImage release];
[employeeImageView release];
[nameView release];
[functionView release];
contactDetailsTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 370) style: UITableViewStyleGrouped];
contactDetailsTable.backgroundColor = [UIColor clearColor];
contactDetailsTable.tableHeaderView = headerView;
[headerView release];
contactDetailsTable.delegate = self;
contactDetailsTable.dataSource = self;
[self.view addSubview:contactDetailsTable];
}
- (void)viewDidUnload {
self.contactDetailsTable = nil;
self.employee = nil;
[super viewDidUnload];
}
- (void)viewWillAppear:(BOOL)animated {
[contactDetailsTable reloadData];
}
- (void)dealloc {
[contactDetailsTable release];
[employee release];
[super dealloc];
}
#pragma mark -
#pragma mark Table View Data Source Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 2;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;did
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *contactDetailIdentifier = #"contactDetailIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:contactDetailIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:contactDetailIdentifier] autorelease];
UILabel *leftLabel = [[UITextField alloc] initWithFrame:CGRectMake(5, 12, 70, 25)];
leftLabel.textAlignment = UITextAlignmentRight;
leftLabel.textColor = [UIColor grayColor];
leftLabel.tag = kLeftLabelTag;
leftLabel.userInteractionEnabled = NO;
[cell.contentView addSubview:leftLabel];
[leftLabel release];
UILabel *rightLabel = [[UITextField alloc] initWithFrame:CGRectMake(90, 12, 160, 25)];
rightLabel.font = [UIFont boldSystemFontOfSize:16];
rightLabel.tag = kRightLabelTag;
rightLabel.userInteractionEnabled = NO;
[cell.contentView addSubview:rightLabel];
[rightLabel release];
}
NSUInteger row = [indexPath row];
UILabel *leftLabel = (UILabel *)[cell viewWithTag:kLeftLabelTag];
UILabel *rightLabel = (UILabel *)[cell viewWithTag:kRightLabelTag];
switch (row) {
case kTelephoneRowIndex:
leftLabel.text = #"telefoon";
rightLabel.text = employee.phone;
break;
case kEmailRowIndex:
leftLabel.text = #"e-mail";
rightLabel.text = employee.email;
break;
default:
break;
}
return cell;
}
#pragma mark -
#pragma mark Table View Delegate Methods
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
return nil;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger row = indexPath.row;
if (row == 1) {
MFMailComposeViewController *mailController = [[MFMailComposeViewController alloc] init];
[mailController setToRecipients:[NSArray arrayWithObject:employee.email]];
[mailController.navigationBar setTintColor:[UIColor blackColor]];
[self presentModalViewController:mailController animated:YES];
mailController.mailComposeDelegate = self;
[mailController release];
}
NSLog(#"Row selected is: %d", row);
}
#pragma mark -
#pragma mark MFMailCompose View Delegate Methods
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
[self dismissModalViewControllerAnimated:YES];
}
#end

Check the doc for tableView:willSelectRowAtIndexPath::
Return an NSIndexPath object other than indexPath if you want another cell to be selected. Return nil if you don't want the row selected.
You are returning nil, basically saying the table view that you don't want that row selected. Therefore tableView:didSelectRowAtIndexPath: is not called.

When I had this problem I found the solution was to use willSelectRowAtIndexPath. In other places in the same project didSelectItemAtIndexPath is getting called fine.
#pragma mark - UITableViewDelegate
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// for some reason this is getting called instead of didSelectItemAtIndexPath
[self viewDetails:indexPath.row];
return indexPath;
}
- (void)tableView:(UITableView *)tableView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
// [self viewDetails:indexPath.row];
}

Related

UISearchBar same as like iMac Finder Search Functionality

I met with an requirement in which I had UISearchBar as like follows.
Step : 1 (Initial look of the SearchBar)
Step : 2 (User types string and immediate Search)
Step : 3 (Selecting any of them in the Search List)
Step : 4 (Adding the button on the SearchBar)
Step : 5 (Finally Action on the Button)
This might continue. I mean to say is he can enter the text further more but the functionality should be the same.
Could anyone please help me ? Please, I am in a need.
UPDATE
You can watch this same functionality on your iMac Finder Search
This is what i have tried.
#import "ViewController.h"
#import "customPopOverController.h"
#import <QuartzCore/QuartzCore.h>
#interface ViewController ()
#property (strong, nonatomic) UIView *searchView;
#property (strong, nonatomic) UITableView *sampleView;
#property (strong, nonatomic) NSMutableArray *arrayForListing;
#property (strong, nonatomic) UITextField *txtFieldSearch;
#end
#implementation ViewController
#synthesize searchView = _searchView;
#synthesize customPopOverController = _customPopOverController;
#synthesize txtFieldSearch = _txtFieldSearch;
#synthesize sampleView = _sampleView;
#synthesize arrayForListing = _arrayForListing;
#synthesize btnforExtra = _btnforExtra;
- (void)viewDidLoad
{
[super viewDidLoad];
self.arrayForListing = [[NSMutableArray alloc]init];
[self loadTheSearchView];
[self applyUIStyle];
}
- (void)loadTheSearchView
{
self.searchView = [[UIView alloc]initWithFrame:CGRectMake(20, 100, 280, 44)];
[self.searchView setBackgroundColor:[UIColor whiteColor]];
[self.view addSubview:self.searchView];
[self placeTheTextView];
}
- (void)placeTheTextView
{
self.txtFieldSearch = [[UITextField alloc]initWithFrame:CGRectMake(25, 9, 230, 30)];
[self.txtFieldSearch setDelegate:self];
[self.searchView addSubview:self.txtFieldSearch];
}
- (void)applyUIStyle
{
self.searchView.layer.cornerRadius = 20.0f;
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
return YES;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
return YES;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if(textField.text.length!=0)
{
[self.arrayForListing removeAllObjects];
[self.arrayForListing addObject:[NSString stringWithFormat:#"File Contains %#",textField.text]];
[self callThePop];
}
return YES;
}
- (void)callThePop
{
UIViewController *contentViewController = [[UIViewController alloc] init];
contentViewController.contentSizeForViewInPopover = CGSizeMake(self.searchView.frame.size.width, 50);
self.sampleView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, contentViewController.contentSizeForViewInPopover.width, contentViewController.contentSizeForViewInPopover.height)];
[self.sampleView setDelegate:self];
[self.sampleView setDataSource:self];
[self.sampleView setSeparatorStyle:UITableViewCellSeparatorStyleSingleLineEtched];
[self.sampleView setBackgroundColor:[UIColor clearColor]];
[contentViewController.view addSubview:self.sampleView];
self.customPopOverController = [[customPopOverController alloc]initWithContentViewController:contentViewController];
self.customPopOverController.delegate = self;
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(callYourMethod:)];
swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
[self.sampleView addGestureRecognizer:swipeRight];
[self.customPopOverController presentPopoverFromRect:self.searchView.frame inView:self.view permittedArrowDirections:(UIPopoverArrowDirectionUp|UIPopoverArrowDirectionDown| UIPopoverArrowDirectionLeft|UIPopoverArrowDirectionRight) animated:YES];
}
- (BOOL)textFieldShouldClear:(UITextField *)textField
{
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - Table View Delegate Methods
#pragma mark
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.arrayForListing.count;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifer = #"Cell";
UITableViewCell *cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifer];
if (cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifer];
}
cell.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[cell.textLabel setTextAlignment:UITextAlignmentCenter];
[cell.textLabel setNumberOfLines:0];
[cell.textLabel setLineBreakMode:UILineBreakModeCharacterWrap];
cell.textLabel.text = [self.arrayForListing objectAtIndex:indexPath.row];
[cell.textLabel setFont:[UIFont fontWithName:#"TrebuchetMS" size:14]];
cell.textLabel.textColor = [UIColor whiteColor];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (self.customPopOverController)
{
[self.customPopOverController dismissPopoverAnimated:YES];
}
UITableViewCell * cell = (UITableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
if (self.txtFieldSearch.text.length == 0)
{
self.txtFieldSearch.text = cell.textLabel.text;
}
else
{
self.btnforExtra = [[UIButton alloc]initWithFrame:CGRectMake(10+(buttonsCount*45), 8, 45, 25)];
[self.btnforExtra setBackgroundColor:[UIColor colorWithRed:0.503 green:0.641 blue:0.794 alpha:1.000]];
[self.btnforExtra setTitle:self.txtFieldSearch.text forState:UIControlStateNormal];
[self.btnforExtra setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[self.btnforExtra.layer setCornerRadius:8.0f];
[self.txtFieldSearch setFrame:CGRectMake(self.btnforExtra.frame.origin.x+self.btnforExtra.frame.size.width+10, 9, 230, 30)];
self.txtFieldSearch.text = #"";
[self.searchView addSubview:self.btnforExtra];
buttonsCount++;
}
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView.editing == UITableViewCellEditingStyleDelete)
{
[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
[self.arrayForListing removeObjectAtIndex:indexPath.row];
[tableView endUpdates];
}
}
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"IndexPath.row == %i", indexPath.row);
}
#pragma mark - custom PopOver Delegate Methods
#pragma mark
- (BOOL)popoverControllerShouldDismissPopover:(customPopOverController *)thePopoverController
{
return YES;
}
- (void)popoverControllerDidDismissPopover:(customPopOverController *)thePopoverController
{
self.customPopOverController = nil;
}
#end
DISCLAIMER: this solution is deeply flawed, probably in many ways. It's the first solution that I came up with and I've done VERY little optimization on it (aka none).
So, I was bored, and I came up with something that I think fits the bill. Keep in mind that this only does the display of what you're asking about (and it does it somewhat poorly at that), it does not handle the actual search functionality as I'm not sure what you're searching. It also has some static values programmed in (such as file types array, and I dropped the view controller into a UINavigationController and did some static sizes based on that) that you'll want to change. I make use of WYPopoverController, which can be found here: WYPopoverController. Let me know how it works for you- feel free to critique the hell out if it.
ViewController.h
#interface ViewController : UIViewController <UITextFieldDelegate, UITableViewDelegate, UITableViewDataSource>
{
}
ViewController.m
#import "ViewController.h"
#import "WYPopoverController.h"
#import "SearchButton.h"
#import <QuartzCore/QuartzCore.h>
#interface ViewController () <WYPopoverControllerDelegate>
{
UITextField *searchField;
UIView *searchesView;
UIScrollView *scrollView;
WYPopoverController *newSearchController;
WYPopoverController *existingSearchController;
NSMutableArray *buttonsArray;
SearchButton *activeButton;
NSArray *kindsArray;
NSMutableArray *matchedKinds;
// using UITableViewController instead of just UITableView so I can set preferredContentSize on the controller
UITableViewController *searchTable;
UITableViewController *existingTable;
}
#end
#implementation ViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
searchField = [[UITextField alloc] initWithFrame:CGRectMake(20, 75, 280, 30)];
searchField.borderStyle = UITextBorderStyleRoundedRect;
searchField.autocorrectionType = UITextAutocorrectionTypeNo;
searchField.delegate = self;
[self.view addSubview:searchField];
searchesView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, searchField.frame.size.height)];
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 0, searchField.frame.size.height)];
[scrollView addSubview:searchesView];
searchField.leftView = scrollView;
searchField.leftViewMode = UITextFieldViewModeAlways;
[searchField becomeFirstResponder];
kindsArray = [NSArray arrayWithObjects:#"Audio", #"Video", #"Other", #"Text", nil];
matchedKinds = [[NSMutableArray alloc] init];
buttonsArray = [[NSMutableArray alloc] init];
[searchField addTarget:self
action:#selector(textFieldDidChange:)
forControlEvents:UIControlEventEditingChanged];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Text Field Delegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[newSearchController dismissPopoverAnimated:YES completion:^{
[self popoverControllerDidDismissPopover:newSearchController];
}];
return YES;
}
// not technically part of the TF delegate, but it fits better here
- (void)textFieldDidChange:(UITextField *)tf
{
if(tf.text.length > 0)
{
if(newSearchController == nil)
{
searchTable = [[UITableViewController alloc] init];
searchTable.tableView.delegate = self;
searchTable.tableView.dataSource = self;
searchTable.preferredContentSize = CGSizeMake(320, 136);
newSearchController = [[WYPopoverController alloc] initWithContentViewController:searchTable];
newSearchController.delegate = self;
newSearchController.popoverLayoutMargins = UIEdgeInsetsMake(10, 10, 10, 10);
newSearchController.theme.arrowHeight = 5;
searchTable.tableView.tag = 1;
[newSearchController presentPopoverFromRect:searchField.bounds
inView:searchField
permittedArrowDirections:WYPopoverArrowDirectionUp
animated:YES
options:WYPopoverAnimationOptionFadeWithScale];
}
[matchedKinds removeAllObjects];
for(NSString *type in kindsArray)
{
NSRange foundRange = [[type lowercaseString] rangeOfString:[tf.text lowercaseString]];
if(foundRange.location != NSNotFound)
{
// Found a match!
[matchedKinds addObject:type];
}
}
[searchTable.tableView reloadData];
}
else
{
[newSearchController dismissPopoverAnimated:YES completion:^{
[self popoverControllerDidDismissPopover:newSearchController];
}];
}
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if(tableView.tag == 1)
return 2;
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(tableView.tag == 1)
{
if(section == 0)
return 1;
return [matchedKinds count];
}
return 3;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if(tableView.tag == 1)
{
if(section == 0)
return #"Filenames";
else
return #"Kinds";
}
return nil;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 30.0f;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"reuser"];
// Configure the cell...
if(tableView.tag == 1)
{
if(indexPath.section == 0)
{
cell.textLabel.text = [NSString stringWithFormat:#"Name matches: %#", searchField.text];
}
else
{
cell.textLabel.text = [matchedKinds objectAtIndex:indexPath.row];
}
}
else
{
if(indexPath.row == 0)
{
switch (tableView.tag) {
case 2:
cell.textLabel.text = #"Filename";
break;
default:
cell.textLabel.text = #"Kind";
break;
}
}
else if(indexPath.row == 1)
cell.textLabel.text = #"Everything";
else
cell.textLabel.text = #"<Delete>";
}
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(tableView.tag == 1) // new search table tapped
{
SearchButton *searchedButton = [SearchButton buttonWithType:UIButtonTypeSystem];
if(indexPath.section == 0)
{
searchedButton.type = ButtonTypeName;
searchedButton.searchedString = searchField.text;
}
else
{
searchedButton.type = ButtonTypeKind;
searchedButton.searchedString = [matchedKinds objectAtIndex:indexPath.row];
}
searchedButton.defaulted = YES;
searchedButton.titleLabel.font = [UIFont systemFontOfSize:14.0f];
[searchedButton setTitleColor:[UIColor darkTextColor]
forState:UIControlStateNormal];
[searchedButton addTarget:self
action:#selector(buttonTapped:)
forControlEvents:UIControlEventTouchUpInside];
[searchedButton setBackgroundColor:[UIColor colorWithWhite:0.9f alpha:1.0f]];
searchedButton.layer.cornerRadius = 5.0f;
searchedButton.clipsToBounds = YES;
[buttonsArray addObject:searchedButton];
activeButton = searchedButton;
searchField.text = #"";
[self updateButtonsFromCreation:YES];
[newSearchController dismissPopoverAnimated:YES completion:^{
[self popoverControllerDidDismissPopover:newSearchController];
}];
}
else // text field of an existing search
{
switch (indexPath.row) {
case 0:
activeButton.defaulted = YES;
break;
case 1:
activeButton.defaulted = NO;
break;
default:
[buttonsArray removeObject:activeButton];
break;
}
[self updateButtonsFromCreation:NO];
[existingSearchController dismissPopoverAnimated:YES completion:^{
[self popoverControllerDidDismissPopover:existingSearchController];
}];
}
}
#pragma mark - Popover delegate
- (void)popoverControllerDidDismissPopover:(WYPopoverController *)controller
{
if(controller == newSearchController)
{
newSearchController = nil;
}
else
{
existingSearchController = nil;
}
}
#pragma mark - Other functions
- (void)updateButtonsFromCreation:(BOOL)creation
{
[[searchesView subviews] makeObjectsPerformSelector:#selector(removeFromSuperview)];
float widthTotal = 0;
for(SearchButton *button in buttonsArray)
{
NSString *buttonText;
if(button.defaulted)
{
if(button.type == ButtonTypeName)
buttonText = #"Name: ";
else
buttonText = #"Kind: ";
}
else
buttonText = #"Any: ";
buttonText = [buttonText stringByAppendingString:button.searchedString];
[button setTitle:buttonText forState:UIControlStateNormal];
CGSize buttonSize = [buttonText sizeWithAttributes:#{NSFontAttributeName:[UIFont systemFontOfSize:14.0f]}];
button.frame = CGRectMake(widthTotal + 2, 2, buttonSize.width + 4, searchField.frame.size.height - 4);
widthTotal += button.frame.size.width + 2;
[searchesView addSubview:button];
}
searchesView.frame = CGRectMake(0, 0, widthTotal, searchesView.frame.size.height);
scrollView.frame = CGRectMake(0, 0, ((widthTotal > 200) ? 200 : widthTotal), scrollView.frame.size.height);
scrollView.contentSize = CGSizeMake(widthTotal, scrollView.frame.size.height);
if(creation)
{
scrollView.contentOffset = CGPointMake(activeButton.frame.origin.x, 0);
}
}
- (void)buttonTapped:(SearchButton *)sender
{
activeButton = sender;
existingTable = [[UITableViewController alloc] init];
existingTable.tableView.delegate = self;
existingTable.tableView.dataSource = self;
existingTable.preferredContentSize = CGSizeMake(160, 90);
existingSearchController = [[WYPopoverController alloc] initWithContentViewController:existingTable];
existingSearchController.delegate = self;
existingSearchController.popoverLayoutMargins = UIEdgeInsetsMake(10, 10, 10, 10);
existingSearchController.theme.arrowHeight = 5;
existingTable.tableView.tag = sender.type;
[existingSearchController presentPopoverFromRect:sender.frame
inView:scrollView
permittedArrowDirections:WYPopoverArrowDirectionUp
animated:YES
options:WYPopoverAnimationOptionFadeWithScale];
}
#end
SearchButton.h
typedef enum {ButtonTypeName = 2,
ButtonTypeKind = 3} ButtonType;
#interface SearchButton : UIButton
#property (nonatomic) ButtonType type;
#property (nonatomic) BOOL defaulted;
#property (nonatomic, retain) NSString *searchedString;
#end
SearchButton.m
no changes to default generated

How to expand and collapse rows using header section in a UITableView

I have a table view. Now I want to collapse and expand rows by tapping on the section header. In other words, when I tap the header the rows display for that section. How can I do this?
I draft up some code to give you the idea. The concept is we keep track of collapsed section in NSMutableSet and add/remove it according to the user touch on the section. The collapse/expand animation is actually the animation of adding/removing cells.
#import "ViewController.h"
#interface ViewController () < UITableViewDataSource, UITableViewDelegate> {
NSMutableSet* _collapsedSections;
}
#property (nonatomic, weak) IBOutlet UITableView* tableView;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_collapsedSections = [NSMutableSet new];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 3;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_collapsedSections containsObject:#(section)] ? 0 : 10;
}
-(NSArray*) indexPathsForSection:(int)section withNumberOfRows:(int)numberOfRows {
NSMutableArray* indexPaths = [NSMutableArray new];
for (int i = 0; i < numberOfRows; i++) {
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:i inSection:section];
[indexPaths addObject:indexPath];
}
return indexPaths;
}
-(void)sectionButtonTouchUpInside:(UIButton*)sender {
sender.backgroundColor = [UIColor greenColor];
[self.tableView beginUpdates];
int section = sender.tag;
bool shouldCollapse = ![_collapsedSections containsObject:#(section)];
if (shouldCollapse) {
int numOfRows = [self.tableView numberOfRowsInSection:section];
NSArray* indexPaths = [self indexPathsForSection:section withNumberOfRows:numOfRows];
[self.tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationTop];
[_collapsedSections addObject:#(section)];
}
else {
int numOfRows = 10;
NSArray* indexPaths = [self indexPathsForSection:section withNumberOfRows:numOfRows];
[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationTop];
[_collapsedSections removeObject:#(section)];
}
[self.tableView endUpdates];
//[_tableView reloadData];
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIButton* result = [UIButton buttonWithType:UIButtonTypeCustom];
[result addTarget:self action:#selector(sectionButtonTouchUpInside:) forControlEvents:UIControlEventTouchUpInside];
result.backgroundColor = [UIColor blueColor];
[result setTitle:[NSString stringWithFormat:#"Section %d", section] forState:UIControlStateNormal];
result.tag = section;
return result;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell* result = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
result.textLabel.text = [NSString stringWithFormat:#"Cell %d", indexPath.row];
return result;
}
#end
As already this is a old question now.Me too also searched and in the last got 1 sample code from Github.So I thought of sharing the link,if in near future any one comes up with the same issues.
https://github.com/iSofTom/STCollapseTableView
TLIndexPathTools does this with only a few lines of code on your part. Try running the Collapse sample project. It subclasses TLCollapsibleTableViewController, which has a couple of nice options. It supports expanding a single section at a time or multiple sections. It also optimizes the scroll position when you expand a section to show as many rows of the section as possible. So if you tap on a section near the bottom of the screen, it will scroll up automatically.
The full view controller code of the sample project is as follows:
#import "TLCollapsibleTableViewController.h"
#interface CollapseTableViewController : TLCollapsibleTableViewController
- (IBAction)toggleSingleSectionExpanded:(UISwitch *)sender;
#end
#import "CollapseTableViewController.h"
#import "TLIndexPathSectionInfo.h"
#import "TLCollapsibleDataModel.h"
#define SECTION1_NAME #"Section 1"
#define SECTION2_NAME #"Section 2"
#interface CollapseTableViewController ()
#property (strong, nonatomic) TLIndexPathDataModel *backingDataModel;
#end
#implementation CollapseTableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//define items for two sections
NSArray *section1Items = #[
#"Fredricksburg",
#"George Washington",
#"Grand Canyon"];
NSArray *section2Items = #[
#"Jelly Bean",
#"Bibliography",
#"Keyboard Shortcut",
#"Metadata",
#"Fundamental",
#"Cellar Door"];
//We're using plain string items, so we don't have a sectionNameKeyPath property
//to use, so instead we explicitly create section info objects
TLIndexPathSectionInfo *section1 = [[TLIndexPathSectionInfo alloc] initWithItems:section1Items andName:SECTION1_NAME];
TLIndexPathSectionInfo *section2 = [[TLIndexPathSectionInfo alloc] initWithItems:section2Items andName:SECTION2_NAME];
//create the backing model, which contains all sections and items
self.backingDataModel = [[TLIndexPathDataModel alloc] initWithSectionInfos:#[section1, section2]
andIdentifierKeyPath:nil andCellIdentifierKeyPath:nil];
[self collapseAll];
}
- (void)tableView:(UITableView *)tableView configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
NSString *item = [self.dataModel itemAtIndexPath:indexPath];
cell.textLabel.text = item;
}
- (IBAction)toggleSingleSectionExpanded:(UISwitch *)sender {
self.singleExpandedSection = sender.isOn;
[self collapseAll];
}
- (void)collapseAll
{
self.dataModel = [[TLCollapsibleDataModel alloc] initWithBackingDataModel:self.backingDataModel
collapsedSectionNames:[NSSet setWithArray:self.backingDataModel.sectionNames]];
}
#end
configure viewForHeaderInSection:
like this
(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
UILabel *lblHeader = [[UILabel alloc]init];
lblHeader.text = #"Section 0";
lblHeader.backgroundColor = [UIColor blueColor];
lblHeader.font = [UIFont fontWithName:#"Avenir" size:18];
lblHeader.textAlignment=NSTextAlignmentLeft;
lblHeader.userInteractionEnabled=YES;
UIGestureRecognizer *gr;
if(section==0){
lblHeader.text = #"Section 0";
gr = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleGesture:)];
}else if(section == 1){
lblHeader.text = #"Section 1";
gr = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleGesture1:)];
}
[lblHeader addGestureRecognizer:gr];
return lblHeader;
}
then write seperate action calls
- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer {
}
- (void)handleGesture1:(UIGestureRecognizer *)gestureRecognizer {
}

Hovering UITableViewController over a UIViewController on iPhone not displaying cell content (e.g. FB notification view)

I am trying to create a hovering UITableViewController over a UIViewController. I have managed to open the TableView over the ViewController. (Picture)
When first loading the view the data is loaded and I can see the rows for split second, but then it disappears. I understand that I must be assigning something over the actual view in the memory. However I can't fins what I am doing wrong.
Here is how I try to do it:
I create it as a object and load it with animation
BINotificationView *notifView = [[BINotificationView alloc] init];
notifView.view.frame = CGRectMake(10, 10, 300, 400);
[notifView.tableView setDataSource:notifView];
[notifView.tableView setDelegate:notifView];
[notifView setResultSet:_notifSet];
notifView.view.layer.masksToBounds = YES;
[self.view addSubview:notifView.view];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.2];
[notifView.view setAlpha:1.0];
[UIView commitAnimations];
[UIView setAnimationDuration:0.0];
When view is loaded the tableview is populated (with same cell identifier in storyboard)
#interface BINotificationView ()
#end
#implementation BINotificationView
#synthesize resultSet;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.view.alpha = 0.0;
self.view.layer.cornerRadius = 5;
self.view.layer.borderWidth = 3.0f;
self.view.backgroundColor = [UIColor whiteColor];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (resultSet.count) {
return resultSet.count;
}
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"notif";
NotificationCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[NotificationCell alloc] init];
cell.frame = CGRectMake(0, 0, 300, 80);
}
cell.notification = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 280, 80)];
[cell addSubview:cell.notification];
[cell.notification setFont:[UIFont fontWithName:#"AvenirNextCondensed-Regular" size:16]];
if (resultSet.count) {
BINotification *obj = [resultSet objectAtIndex:indexPath.row];
cell.notification.text = obj.type;
}
else {
cell.notification.text = #"Empty List";
}
[cell.notification setEditable:NO];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 80.0;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
#end
My UITableViewCell is defined as
#interface NotificationCell : UITableViewCell
#property (nonatomic, retain) IBOutlet UITextView *notification;
#end
#implementation NotificationCell
#synthesize notification;
#end
The UITableViewController .h file is like this
#interface BINotificationView : UITableViewController
#property (nonatomic, strong) NSMutableArray *resultSet;
#end
Thanks for your help
It looks like notifView is released when its scope ends. But its view is added as a subview, this may explain why it is seen for a while. The solution is to extend the scope of notifView, try making it a property of the controller which adds notifView's view as a subview.
notification = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 270, 80)];
[self addSubview:notification];
Add this in your UITableViewCell file

UITableview Crash when scroll up or down and how to set horizontal scroll view to every cell

I want to display table view in which every cell contain nested UIview but i am facing some problems.
1) My app crash when i try to scroll table view.
Solved by add root view instead of subview into app delegate
Now problem number 2
2) I want to add horizontal scroll view inside table cell.so i can display 3 subview in single cell and i can scroll horizontally with in cell..how can i do that.
I want to do this..
To achive this i have code this..
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
UIView *wagon = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 430, 187)];
UIColor *background = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"wagon.png"]];
wagon.backgroundColor = background;
UIScrollView *scrollview = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, 830, 187)];
scrollview.showsVerticalScrollIndicator=YES;
scrollview.scrollEnabled=YES;
scrollview.userInteractionEnabled=YES;
UIView *videoview = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 220 , 100)];
UIImageView *video = [[UIImageView alloc]initWithFrame:CGRectMake(wagon.frame.origin.x+18, wagon.frame.origin.y+35, 220, 100)];
UIImage *bgImage = [UIImage imageNamed:#"video.png"];
video.image = bgImage;
videoview.contentMode = UIViewContentModeLeft;
[videoview addSubview:video];
UIView *textview = [[UIView alloc]initWithFrame:CGRectMake(wagon.frame.origin.x+238,wagon.frame.origin.y+28, 150 , 187)];
textview.contentMode = UIViewContentModeRight;
UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(28,10, 150 , 87)];
label.text=#"This is testing text for IOS app to check line are aligned or not and to check video image and nested views for UIviews";
label.backgroundColor = [UIColor clearColor];
label.textColor=[UIColor redColor];
label.numberOfLines = 4;
[textview addSubview:label];
[wagon addSubview:textview];
[wagon addSubview:videoview];
[scrollview addSubview:wagon];
[self addSubview:scrollview];
}
return self;
}
and call this view from table cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = #"StateCell";
UITableViewCell *cell;
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Wagon1 *wg=[[Wagon1 alloc]init];
[cell addSubview:wg];
return cell;
}
by adding wg i get one train boggi, wagon view.. i want 2 wagon view and engine at last or first.
** Table crashing problem is solve**
1) to solve crashing problem i search on stackoverflow and i found solution like adding to delegates or change to retain or strong bla bla.. but non of these work for me.
Here is my code. and one more thing i am not use XIB , nib or storyboard..
#interface MainScreenViewController : UIViewController
{
UITableView* table;
NSString * name;
}
#property (strong, retain) UITableView *table;
#property (strong, retain) NSString *name;;
#end
.m file
#interface MainScreenViewController ()
#end
#implementation MainScreenViewController
#synthesize table;
#synthesize name;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:Nil bundle:Nil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
name=[[NSString alloc]init];
name=#"testing of row";
CGRect frame = self.view.frame;
table= [[UITableView alloc] initWithFrame:frame];
table.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
[table setDelegate:self];// app crash here
table.dataSource = self;// here also
[table reloadData];
[self.view addSubview:table];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 8;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return #"test";
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath*)indexPath;
{
return 190;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (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];
}
cell.textLabel.text = name;
return cell;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I tried your code and it is working perfectly for me , I guess problem should be with view controller initialisation , try this Applications are expected to have a root view controller at the end of application launch and let me know.
As you have mentioned
i have added both but still it crash..i got this 2013-04-23 12:37:28.361 AMM[2231:c07] Application windows are expected to have a root view controller at the end of application launch 2013-04-23 12:37:32.533 AMM[2231:c07] * -[MainScreenViewController respondsToSelector:]: message sent to deallocated instance 0x71edb70
In the application delegate file have you added the mainview controller to window's rootviewcontroller? Also could you try with some hardcoded text instead of assigning name to cell text.
Here,
Check this is happening in App Delegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[MainScreenViewController alloc] initWithNibName:#"MainScreenViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
and in MainScreenViewController.m
#interface MainScreenViewController () <UITableViewDataSource,UITableViewDelegate>
#property (nonatomic, strong)UITableView * table;
#property (nonatomic, strong)NSString * name;
#end
#implementation MainScreenViewController
#synthesize table,name;
- (void)viewDidLoad
{
[super viewDidLoad];
name = [[NSString alloc]init];
name = #"testing of row";
CGRect frame = self.view.frame;
table = [[UITableView alloc] initWithFrame:frame];
table.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
[table setDelegate:self];
[table setDataSource:self];
[self.view addSubview:table];
// Do any additional setup after loading the view, typically from a nib.
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 8;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return #"Test";
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath*)indexPath;
{
return 190;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (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];
}
// cell.textLabel.text = name;
// Add UIScrollView for Horizontal scrolling.
NSArray * colors = [NSArray arrayWithObjects:[UIColor redColor], [UIColor greenColor],[UIColor blueColor],[UIColor orangeColor], [UIColor blackColor],[UIColor purpleColor], nil];
UIScrollView * scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0.0,0.0,320.0,190.0)];
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * colors.count,scrollView.frame.size.height);
for (int i = 0; i < colors.count; i++) {
CGRect frame;
frame.origin.x = scrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = scrollView.frame.size;
UIView *subview = [[UIView alloc] initWithFrame:frame];
subview.backgroundColor = [colors objectAtIndex:i];
[scrollView addSubview:subview];
}
[cell.contentView addSubview:scrollView];
return cell;
}

UITableView in UINavigationController causes EXC_BAD_ACCESS

below test code causes EXC_BAD_ACCESS when it's scrolled many time.
would somebody like to tell me the problem?
-myview.h---------------------------------------------------
#interface MyView : UINavigationController < UITableViewDataSource, UITableViewDelegate, UINavigationBarDelegate >
{
UITableView* mTableView;
NSMutableArray* data;
}
-myview.m---------------------------------------------------
#implementation MyView
- (void)viewDidLoad
{
[super viewDidLoad];
int th = self.navigationBar.frame.size.height;
int w = self.view.frame.size.width;
int h = self.view.frame.size.height;
mTableView = [[[UITableView alloc] initWithFrame:
CGRectMake(0.0f, th, w, h - th) style:UITableViewStylePlain] retain];
mTableView.autoresizingMask = UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight;
mTableView.dataSource = self;
mTableView.delegate = self;
[mTableView setRowHeight:55];
[self.view addSubview:mTableView];
data = [[[NSMutableArray alloc] init] retain];
for (int i = 0; i < 150; i++)
{
[data addObject:[NSDictionary
dictionaryWithObjects:[NSArray arrayWithObjects:#"good", [UIColor blackColor], nil]
forKeys:[NSArray arrayWithObjects:#"name", #"color", nil]]];
}
}
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 150;
}
- (UITableViewCell *)tableViewCellWithReuseIdentifier:(NSString *)identifier
{
UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
cell.textLabel.text = #"goooood";
return cell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [self tableViewCellWithReuseIdentifier:CellIdentifier];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (void)dealloc
{
[super dealloc];
}
- (BOOL)canBecomeFirstResponder
{
return YES;
}
#end
You should have a view controller that contains your table view (it could even be a subclass of UITableViewController). I don't believe that UINavigationController is mean't to be subclassed as you have. If you want a navigation controller you should create an instance of CustomTableViewController, containing your tableview, and then use the initWithRootViewController: method of UINavigationController:
CustomTableViewController * ctvc = [[CustomTableViewController alloc] init];
UINavigationController * navigationController = [[UINavigationController alloc] initWithRootViewController:ctvc];
[ctvc release];
// Superview is where you want this added
// probably your window in app did finish launching
[superview addSubview:navigationController.view];
[navigationController release];