Creating programmatically a UINavigationController with UITableView - uitableview

I have been struggling a quite long time with this problem. Maybe you could help me. So i want to create programmatically a basic UINavigationController with simple UITableView.
For example UITableView will contain some info about "Colors". Item list would be something like: "Yellow", "Orange", "Green", "Purple".
I would be really really happy if you can help me to get this right.

Try this:
#interface MyViewController: UITableViewController {
NSArray *data;
}
#end
#implementation MyViewController
- (id)init
{
if ((self = [super init]))
{
data = [[NSArray alloc] initWithObjects:#"Red", #"Green", #"Blue", nil];
}
return self;
}
- (void)dealloc
{
[data release];
[super dealloc];
}
- (int)tableView:(UITableView *)tv numberOfRowsInSection:(int)s
{
return [data count];
}
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)ip
{
UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:#"CELLID"];
if (!cell) cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault identifier:#"CELLID"] autorelease];
cell.textLabel.text = [data objectAtIndex:ip.row];
return cell;
}
#end
Use it like:
MyViewController *ctrl = [[MyViewController alloc] init];
UINavigationController *navCtrl = [[UINavigationController alloc] initWithRootViewController:ctrl];
[ctrl release];
etc.

Related

UITableView memory bug

I have a problem with memory leak in UITableView. If I'm at the bottom of DetailViewController table and I want to go back to MasterViewController I have a crash. If I use UITableViewController, crash does not happen.
AppDelegate
_window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
_window.backgroundColor = [UIColor blackColor];
_window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[[MasterViewController alloc] init]];
[_window makeKeyAndVisible];
MasterViewController
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
DetailViewController *detailViewController = [[DetailViewController alloc] init];
[self.navigationController pushViewController:detailViewController animated:YES];
}
DetailViewController
#interface DetailViewController ()
#property (nonatomic, strong) UITableView *tableView;
#end
#implementation DetailViewController
- (void)viewDidLoad {
[super viewDidLoad];
_tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
_tableView.delegate = self;
_tableView.dataSource = self;
_tableView.rowHeight = 60;
[self.view addSubview:_tableView];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 30;
}
- (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];
}
return cell;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
NSLog(#"scrollViewDidScroll");
}
#end

UISearchDisplayController delegate methods not being called

I am trying to gain some knowledge on UISearchDisplayController and going through some tutorial with examples, I have the below class ready with a search bar and table view with data on it.
Header file:
#import <UIKit/UIKit.h>
#interface MyClass : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchDisplayDelegate, UISearchBarDelegate>
#property (nonatomic, strong) IBOutlet UITableView *suggestionsTableView;
#property (nonatomic, strong) IBOutlet UISearchBar *searchBar;
#end
Implementation file:
#import "MyClass.h"
#interface DVWNoteTypeSuggestionDisplayController ()
#property (nonatomic, strong) NSArray *items;
#property (nonatomic)BOOL isSearching;
#property (nonatomic, strong) NSMutableArray *filteredList;
#end
#implementation MyClass
- (id)init
{
self = [super initWithNibName:#"SuggestionDisplayController" bundle:BUNDLE];
if (self)
{
// Set the title.
self.title = #"test";
}
return self;
}
- (void)viewDidLoad
{
self.searchBar = [[UISearchBar alloc] init];
[[UISearchDisplayController alloc] initWithSearchBar:self.searchBar contentsController:self];
self.searchDisplayController.searchResultsDelegate = self;
self.searchDisplayController.searchResultsDataSource = self;
self.searchDisplayController.delegate = self;
self.searchBar.frame = CGRectMake(0, 0, 0, 38);
self.suggestionsTableView.tableHeaderView = self.searchBar;
self.items = [[NSArray alloc] initWithObjects:#"Item No. 1", #"Item No. 2", #"Item No. 3", #"Item No. 4", #"Item No. 5", #"Item No. 6", nil];
self.isSearching = NO;
self.filteredList = [[NSMutableArray alloc] init];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
//- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
// // Return the number of rows in the section.
// // Usually the number of items in your array (the one that holds your list)
// return [self.items count];
//}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
if (self.isSearching)
{
//If the user is searching, use the list in our filteredList array.
return [self.filteredList count];
} else
{
return [self.items count];
}
}
//- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
// //Where we configure the cell in each row
//
// static NSString *CellIdentifier = #"Cell";
// UITableViewCell *cell;
//
// cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// if (cell == nil) {
// cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
// }
// // Configure the cell... setting the text of our cell's label
// cell.textLabel.text = [self.items objectAtIndex:indexPath.row];
// return cell;
//}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// Configure the cell...
NSString *title;
if (self.isSearching && [self.filteredList count]) {
//If the user is searching, use the list in our filteredList array.
title = [self.filteredList objectAtIndex:indexPath.row];
} else
{
title = [self.items objectAtIndex:indexPath.row];
}
cell.textLabel.text = title;
return cell;
}
- (void)filterListForSearchText:(NSString *)searchText
{
[self.filteredList removeAllObjects]; //clears the array from all the string objects it might contain from the previous searches
for (NSString *title in self.items) {
NSRange nameRange = [title rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (nameRange.location != NSNotFound) {
[self.filteredList addObject:title];
}
}
}
#pragma mark - UISearchDisplayControllerDelegate
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
//When the user taps the search bar, this means that the controller will begin searching.
self.isSearching = YES;
}
- (void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller {
//When the user taps the Cancel Button, or anywhere aside from the view.
self.isSearching = NO;
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterListForSearchText:searchString]; // The method we made in step 7
// Return YES to cause the search result table view to be reloaded.
return YES;
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption
{
[self filterListForSearchText:[self.searchDisplayController.searchBar text]]; // The method we made in step 7
// Return YES to cause the search result table view to be reloaded.
return YES;
}
#end
Whenever I try to search for any items in the data set (eg: "Item No. 5") its not hitting the breakpoints on any of the delegate i.e. actually the search is not working. Please suggest what am I missing here as this is just my learning project right now.
It appears that a UISearchDisplayController created programatically in this way is prematurely zeroing the delegate, even though the view controller is retaining the UISearchDisplayController as expected.
Add the following to the end of your viewDidLoad and you'll see that the first log will be a valid object, but the second will be null.
NSLog(#"Delegate should be %#", self.searchDisplayController.delegate);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(#"Delegate is %#", self.searchDisplayController.delegate);
});
The quickest way I've found to get around this is to store your own reference to the UISearchDisplayController via a private property or ivar.
If you have to create object for search bar controller and set delegate search bar its work.
UISearchBar *searchBar = [[UISearchBar alloc] init];
[[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
self.searchDisplayController.searchResultsDelegate = self;
self.searchDisplayController.searchResultsDataSource = self;
self.searchDisplayController.delegate = self;
searchBar.frame = CGRectMake(0, 0, 0, 38);
self.tableView.tableHeaderView = searchBar;

Sending a data model between UITableViewControllers

I know there are already lots of questions about this but none of them have helped me yet. I have two UITableViewControllers. I want to push a QuicklistViewController (using this like a quick menu to list different shows) onto a CurrentShowViewController.
I have a Show model that only contains a name property right now. I am have trouble moving the data from my selection in QuicklistViewController to the CurrentShowViewController so that I can display the currentShow information there.
I am totally stuck on how I can do this.Please help!
Here is my CurrentShowViewController:
#import "CurrentShowViewController.h"
#import "QuicklistViewController.h"
#interface CurrentShowViewController ()
#end
#implementation CurrentShowViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
self.tabBarItem.image = [UIImage imageNamed:#"tab_icon_episodes.png"];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
//self.navigationItem.rightBarButtonItem = self.editButtonItem;
// Add a UIBarButton button that will display a Quicklist Modal View
UIBarButtonItem *quicklistButton = [[UIBarButtonItem alloc] initWithTitle:#"Quicklist"
style:UIBarButtonItemStylePlain
target:self
action:#selector(quicklistButtonPressed)];
self.navigationItem.leftBarButtonItem = quicklistButton;
self.currentShow = [[Show alloc] init];
NSLog(#"Current show name is: %#", self.currentShow.name);
self.title = self.currentShow.name;
}
- (void) viewWillAppear:(BOOL)animated {
self.title = self.currentShow.name;
}
- (void) quicklistButtonPressed {
QuicklistViewController *quicklistVC = [[QuicklistViewController alloc] init];
[self.navigationController pushViewController:quicklistVC animated:YES];
}
Here is my QuicklistViewController:
#import "QuicklistViewController.h"
#import "CurrentShowViewController.h"
#interface QuicklistViewController ()
#end
#implementation QuicklistViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
self.title = #"Quicklist";
self.tabBarItem.image = [UIImage imageNamed:#"tab_icon_quicklist.png"];
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"Back"
style:UIBarButtonItemStylePlain
target:self
action:#selector(backButtonPressed)];
self.navigationItem.leftBarButtonItem = backButton;
// Create a temp array of Show objects filled with test data
NSMutableArray *temp= [[NSMutableArray alloc] init];
[temp addObject:[[Show alloc] initWithName:#"The Walking Dead"]];
[temp addObject:[[Show alloc] initWithName:#"How I Met Your Mother"]];
[temp addObject:[[Show alloc] initWithName:#"Grey's Anatomy"]];
[temp addObject:[[Show alloc] initWithName:#"The Mentalist"]];
[temp addObject:[[Show alloc] initWithName:#"Stargate SG1"]];
NSArray *testShows = [[NSArray alloc] initWithArray:temp];
self.shows = testShows;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
self.currentShow = [[Show alloc] init];
}
- (void) backButtonPressed {
//Archive changes to currentShow object
[Show saveShow:self.currentShow];
[self.navigationController popViewControllerAnimated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.shows count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"Cell"];
}
cell.textLabel.text = [self.shows[indexPath.row] name];
return cell;
}
- (void) tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// Change the current show to the selected show
self.currentShow = self.shows[indexPath.row];
//Archive changes to currentShow object
[Show saveShow:self.currentShow];
}
Use delegation.
CurrentShowViewController
- (void) quicklistButtonPressed
{
QuicklistViewController *quicklistVC = [[QuicklistViewController alloc] init];
quicklistVC.delegate = self;
[self.navigationController pushViewController:quicklistVC animated:YES];
}
- (void) selectedShow:(Show) show
{
// show : current show
}
QuicklistViewController
#protocol QuicklistViewControllerDelegate
- (void) selectedShow:(Show) show
#end
#property (nonatomic, weak) id delegate;
- (void) backButtonPressed
{
//Archive changes to currentShow object
[Show saveShow:self.currentShow];
[delegate selectedShow:self.currentShow];
[self.navigationController popViewControllerAnimated:YES];
}
You've mistakenly implemented didDeselectRowAtIndexPath instead of didSelectRowAtIndexPath.

UITableView datasource methods not called on reloadData in IOS

I am stucked in this problem for many hours and have n't found any solution on SO...
I have got a table as a subview in UIViewController. When view loads, all datasource methods are called for tableview, but as I receive data from server and call [someTable reloadData], none of the data source methods are called. I have confirmed through breakpoints that my array do contains 100 objects. Also both delegate and datasource are bind to File owner in IB.
What can be possibly missing ? Please help me... Thanks :(
OutLogController.h
#interface OutLogController : UIViewController<UITableViewDataSource,UITableViewDelegate,ASIHTTPRequestDelegate>
{
NSMutableArray *outstandingKeys;
}
#property (strong, nonatomic) IBOutlet UITableView *someTable;
#end
OutLogController.m
#interface OutLogController ()
#end
#implementation OutLogController
#synthesize someTable;
- (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.
outstandingKeys = [[NSMutableArray alloc] init];
someTable = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStylePlain];
someTable.rowHeight = 85;
[self retrieveOutstandingLogFromServer];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return outstandingKeys.count;
}
- (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];
}
// Configure the cell...
LogUnit *unit = [outstandingKeys objectAtIndex:indexPath.row];
cell.textLabel.text = unit.symbol;
return cell;
}
-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 85;
}
-(void) requestFinished:(ASIHTTPRequest *)request
{
NSLog(#"%#",request.responseString);
NSArray *list = [request.responseString JSONValue];//contains 100 objects
for (int i = 0; i < list.count; i++) {
NSArray *singleTrade = [[list objectAtIndex:i] JSONValue];
LogUnit *unit = [[LogUnit alloc] init];
unit.symbol = [singleTrade objectAtIndex:0];
unit.type = [singleTrade objectAtIndex:1];
unit.price = [singleTrade objectAtIndex:2];
unit.remaining = [singleTrade objectAtIndex:3];
unit.order = [singleTrade objectAtIndex:4];
unit.time = [singleTrade objectAtIndex:5];
[outstandingKeys addObject:unit];
}
if(outstandingKeys.count > 0)
{
[someTable reloadData];//does reload table
}
}
EDIT
After removing line:
someTable = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStylePlain];
Datasource methods are called except cellForRowAtIndexPath and table disappears from view since this method is not called. Any idea why it can't get called?
Note: I have confirmed that I have count = 100 after response from server.
someTable = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStylePlain];
You have already bind your UITableView from nib/storyboard. In this case you did not have to alloc again the tableview. Removing this line will do the work
someTable = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStylePlain];
You create new tableView and it doesn't add to current view.
check your outstandingKeys Count may it zero count
Try to reload data by performing it on main thread..
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableRating reloadData];
});
This will solve your problem. Happy Coding..

How to use UITableView in Multi View application

i have some other viewcontroller which triggers another viewcontroller which have UItableView as subView my code is following two file .h , .m
when i use single view based application with this code it works fine but when i use two view for examlpe 1st is logingscreen n call 2nd nib file using this
Viewcomment *b=[[SimpleTableViewController alloc] initWithNibName:#"SimpleTableViewController" bundle:nil];
[self presentModalViewController:b animated:YES];
or
self.window= [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[Viewcomment alloc] initWithNibName:#"Viewcomment" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
it shows "SIGABRT" !!!
Where i am wrong ?
.h file:
#import <UIKit/UIKit.h>
#interface SimpleTableViewController : UIViewController <UITableViewDelegate,UITableViewDataSource>{
NSArray *listData;
}
#property(nonatomic, retain) NSArray *listData;
#end
.m file
#import "SimpleTableViewController.h"
#implementation SimpleTableViewController
#synthesize listData;
- (void)viewDidLoad {
NSArray *array = [[NSArray alloc] initWithObjects:#"iPhone", #"iPod", #"iPad",nil];
self.listData = array;
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
}
- (void)dealloc {
}
#pragma mark -
#pragma mark Table View Data Source Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.listData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];
if (cell == nil) { cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SimpleTableIdentifier] ;
}
NSUInteger row = [indexPath row]; cell.textLabel.text = [listData objectAtIndex:row]; return cell;
}
#end
Your missing:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
from your UITableViewDataSource which will cause a crash.
If thats doesn't work make sure the view is connecting in the nib file of your view controller and make sure your UITableView is connected correctly to the data source.

Resources