Add an external TableView inside a small view on the Main Screen - iphone

I have a simply MainWindow file created by the Interface Builder in black background. Inside this plain view, I've added from top to bottom a small view (300x100), a textLabel and a couple of buttons.
In the MainApplication.h I've defined:
IBOutlet RoundRectView* smallView;
IBOutlet UILabel* label;
In the MainApplication.h I've #synthesized these variables and with that:
[label setText:#"Test"];
I can see all in my screen and it works perfect.
Now my problem:
I want to add a table with two rows inside my small white view, and what I've done is:
Create a tableController.h who's the delegate and the data source:
#interface IncomeExpenseController :
UITableViewController
{ IBOutlet
UITableView* smallTable; NSArray
*content; }
#property (nonatomic, retain)
UITableView *smallTable; #property
(nonatomic, retain) NSArray *content;
#end
Create the .m file with:
#synthesize smallTable; #synthesize
content;
(void)viewDidLoad {
[super viewDidLoad]; content = [[NSArray alloc]
initWithObjects:#"Item1", #"Item2",
nil]; }
(NSInteger)numberOfSectionsInTableView:(UITableView
*)tableView {
// Return the number of sections.
return 0; }
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 2; }
// Customize the appearance of table
view cells.
- (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]
autorelease];
} NSLog(#"inside cell");
// Configure the cell... cell.textLabel.text = [content
objectAtIndex:indexPath.row];
return cell; }
Now in the Interface Builder, I drag and drop a UITableView inside the white small view and drag and drop a Table View Controller along with the File Owner's window and I do these connections:
Class of the Table View Controller to tableController
Outlets:
DataSource and Delegate to my Table Controller
Referencing Outlets:
customTable and View to my Table Controllers
When I execute, I can see the lines of the table view but with no content, I cannot see the NSLog either but if I put a NSLog inside the viewDidLoad I can see it.
I'm really new (2 days) on that and any help would be really appreciated.
Thanks!

Solved.
First of all, the TableView is grouped so I must return almost one section.
Second, from the Interface Builder, I had to link the "view" from the Table to my external controller.
Now it works perfectly.

Related

Label in CustomCell stays nil

I created a custom UITableViewCell with an UILabel in it.
In the cellForRowAtIndexPath method I initialise the custom cell and give the UILabel a value.
While the custom cell is loaded (the heights of the cells are higher than default cells), I can't seem to give the UILabel a value.
SBDownloadCell.h
#import <UIKit/UIKit.h>
#interface SBDownloadCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UILabel *title;
#property (weak, nonatomic) IBOutlet UIProgressView *progressbar;
#property (weak, nonatomic) IBOutlet UILabel *details;
- (IBAction)pause:(id)sender;
#end
SBDownloadCell.m
#import "SBDownloadCell.h"
#implementation SBDownloadCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (IBAction)pause:(id)sender {
}
#end
SBViewController.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SBDownload";
SBDownloadCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[SBDownloadCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
SBDownload *dwnld = [[SBDownload alloc] init];
dwnld = [SBdownloads objectAtIndex:indexPath.row];
//cell.title.text = [dwnld name];
cell.title.text = #"Test";
cell.progressbar.progress = [dwnld percentDone];
cell.details.text = [NSString stringWithFormat:#"%f MB of %f MB completed, %#", [dwnld completed], [dwnld length], [dwnld eta]];
return cell;
}
Storyboard
I break just after cell.title.text = #"Test"; and still this is what I see:
What could it be?
note: i use Xcode DP-5 with iOS7
I see your properties are marked with IBOutlet, which means you have an Interface Builder file (either xib or storyboard) with your table view cell. Make sure to give the correct cell identifier in Interface Builder to the prototype cell in your table view. You should not be calling initWithStyle:. If dequeueReusableCellWithIdentifier: returns nil when using a UITableViewController and storyboards, this means incorrect setup, as dequeueReusableCellWithIdentifier: should always return a cell (it creates the new one if it has to).
To elaborate a bit further, when using xibs or storyboards, a table view cell's initWithStyle: will never be called. When a nib is loaded, the correct init method is initWithCoder:.
The problem is in static NSString *simpleTableIdentifier = #"SBDownload";. In your storyboard, you have set up the identifier as SBDownloadCell.
You need to allocate your UILabels and UIProgressView. Right now you set properties for them, but in your -initWithStyle method you need to call things like
self.title = [[UILabel alloc] initWithFrame:etc...];
If you do this for each of your properties on SBDownloadCell, the labels should be allocated properly.
If you custom your prototype cells in Storyboard, you need to present your TableViewController with segue in storyboard, or if you you need to present the TableViewController by programming, you need to use instantiateViewControllerWithIdentifier: method,
- (IBAction)showTableView:(id)sender
{
UIStoryboard *storybaord = [UIStoryboard storyboardWithName:#"Main_iPad" bundle:nil];
LJTableViewController *vc = (LJTableViewController*)[storybaord
instantiateViewControllerWithIdentifier:#"TableViewControllerID"];
[self presentViewController:vc animated:YES completion:nil];
}
if you initiate TableViewController with [TableViewContrller new], this will let you get an nil label in tableView:cellForRowAtIndexPath mehtod.
I encounter same problem but my identifier is correct for creating custom cell and show data in IBOutlets custom lable, but after cell allocation lables values are null. So for this I need to add method of tableview for showing lables values
- (void)tableView:(UITableView *)tableView willDisplayCell:(DropViewTableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
cell.lblHSNCode.text = objClass.HSNCode;
}

Switch from UIView to UITableview on press of a button

I made a button and connected it to an action in interface builder. What do I need to do in the action method to switch from displaying a view to displaying a table view?
Here is some of my code:
// SwitchToTableViewController.h
#import <UIKit/UIKit.h>
#interface SwitchToTableViewController : UIViewController {
}
-(IBAction) switch : (id) sender;
#end
and
//SwitchToTableViewController.m
#import "SwitchToTableViewController.h"
#import "Table.h"
#implementation SwitchToTableViewController
-(IBAction) switch : (id) sender{
// what is i need to write here to switch to tableview
}
#end
and
//table.m
#import <UIKit/UIKit.h>
#interface Table : UITableViewController {
}
#end
and
//table.h
#import "Table.h"
#implementation Table
#pragma mark Table view methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 2;
}
// Customize the appearance of table view cells.
- (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] autorelease];
}
// Set up the cell...
return cell;
}
#end
You need:
Create an instant of Table.
Pass any data over to this instant, most likely an array so that you can use it to display cells data. You need to create some iVars in your Table class first. Currently you don't have any.
Chose one of many ways to present your Table instant.
Look into Apple's doc. It has quite a bit sample code.
Edit for sample code:
In your SwitchToTableViewController.h file, add this line:
#import "Table.h"
In your SwitchToTableViewController.m, make this changes
-(IBAction) switch : (id) sender{
    // what is i need to write here to switch to tableview
Table *myTable = [[Table alloc]init];
myTable.cellArray = [NSArray arrayWithObjects:#"Item1", #"Item2", #"Item3", nil]; //only an example to be displayed
[self presentViewController:myTable animated:YES completion:nil]; // present your Table - view controller
}
Your Table.h file should look like this:
#import <UIKit/UIKit.h>
#interface Table : UITableViewController {
}
#property (nonatomic, strong) NSArray *cellArray; // adding this line to get data from the parent
#end
In your Table.m, make this changes
#implementation Table
#synthesize cellArray; //add this line right after #implementation Table
- (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 cellArray.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:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.textLabel.text = [cellArray objectAtIndex:indexPath.row];
}
return cell;
}
You have two view controllers here, not two views. It's very important to realise the difference between those two concepts. I've put in bold in the answer below some other key words you need to read up on.
To show another view controller in response to something like a button press, you need to create a new instance of your destination view controller, then get it on the screen somehow.
There are many ways to do this but the simplest way, for a beginner, would be to do all this in storyboards. Add both of your view controllers to the storyboard.
Your initial view controller (with the button) should be embedded in a UINavigationController. Control-drag from the button to your table view controller. This will create a segue. Choose "push" from the list of options.
Hey presto, your table view will now appear on screen when you press the button.
First Create a SingleView Application (UIViewController based) name it as SwitchingView.
Then add a UITableView above the view. Connect using Interface builder. Set delegate and datasource of tableview as the SwitchingView.
Also add a button on the view (before adding table view). Set table view is Hidden using IB(interface builder).
In button Action do
tableview.hidden = NO;
This will show your Table view!!! If you want to show view again, just make
tableview.hidden = YES;
in tableView:didSelectForIndexPathRow method.

2 Table Views on One Page - Two NSArrays

Hello I am brand new to xCode and iPhone development. I have two different TableView controls on one page. I have NSArray #1 that needs to be the datasource of TableView #1 and NSArray #2 that needs to be the datasource for TableView #2.
The only trouble is that NSArray#1 populates both TableView1 and TableView2. I looked through the code and can't seem to find where you can distinguish which NSArray belongs to each TableView.
Any help will be appreciated. Thanks in advance!
#interface GrainBinContentsEstimatorViewController : UIViewController
<UITableViewDelegate, UITableViewDataSource>
{
UITableView *tableViewGrainBinType;
UITableView *tableViewGrainType;
}
#property (strong, nonatomic) NSArray *arrayGrainBinTypes;
#property (strong, nonatomic) NSArray *arrayGrainTypes;
#property (nonatomic, retain) UITableView *tableViewGrainBinType;
#property (nonatomic, retain) UITableView *tableViewGrainType;
#implementation GrainBinContentsEstimatorViewController
#synthesize arrayGrainBinTypes, arrayGrainTypes, tableViewGrainBinType, tableViewGrainType;
- (void)viewDidLoad
{
[super viewDidLoad];
self.arrayGrainBinTypes = [[NSArray alloc]
initWithObjects:#"RF", #"RC45", #"RC60", nil];
self.arrayGrainTypes = [[NSArray alloc]
initWithObjects:#"Wheat", #"Corn", #"Soybeans", #"Rice", #"Milo", #"Barley", nil];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
return #"Select Bin Type";
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [self.arrayGrainBinTypes 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];
}
cell.textLabel.text = [self.arrayGrainBinTypes objectAtIndex: [indexPath row]];
return cell;
}
In every delegate method (callback) the caller (tableview) is passed as a parameter. So you can switch based on this parameter like:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
   if (tableView == self.tableViewGrainBinType) return [self.arrayGrainBinTypes count];
else return [self.arrayGrainTypes count];
}
You get the idea...
First of all, welcome to SO.
So, you have a reasonable design concept here: One array populates one table view. The data source/delegate of your table view is typically a UITableViewController or UIViewController, but it certainly doesn't have to be. In your case, it's your UIViewController. So, what happens is that when each table view loads, it asks its data source "Hey, how many rows/sections do I have? What do my cells look like?" and other questions.
In your case, you're not distinguishing between table views! So tableView1 is asking "what do my cells look like? Let's see what tableView:cellForRowAtIndexPath: has to say!" and you're giving it info from your arrayGrainByTypes array. Then tableView2 comes along and asks the same question, and uses the same method to get its answer. In each of these data source methods, you are typically given, as an argument to the method, which table view is asking for this information. So, just check which table view is asking!
if (tableView == self.tableViewGrainType) {
// table view 1's information is set here
else if (tableView == self.tableViewGrainBinType) {
// table view 2's information is set here
}

UITabBarController with UITableView

i am trying to display a list on my first view so added this in the first.h :
#import <UIKit/UIKit.h>
#interface argospineFirstViewController : UIViewController
<UITableViewDelegate,UITableViewDataSource>
{
NSMutableArray *Journals;
IBOutlet UITableView *myTableView;
}
#property (nonatomic,retain) NSMutableArray *Journals;
#property (nonatomic, retain) UITableView *myTableView;
#end
and then i added this on my first.m :
#implementation argospineFirstViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
Journals=[NSMutableArray arrayWithObjects:#"journal1",#"journal2",nil];
}
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 2;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier];
}
cell.text=[Journals objectAtIndex:indexPath.row];
return cell;
}
I am newbie so i don't really know what kind of connections i have got to make, i am also using a storyboard with a tableview dropped on the first view.
is there something i have to add to the delegate?
Any help?
Thank you for your time
Right click on the tableView in the storyboard. You will see "delegate" and "dataSource" under Outlets. Drag the bubble on the right of those to the view controller icon at the bottom of the view. This will make your viewcontroller the delegate and datasource for the table view if you don't want to do it programmatically.
Do not make property of your table view object.
Also,
in viewDidLoad method write:
myTableView.dataSource = self;
myTableView.delegate = self;
Tell me if it helps!
Use initWithStyle instead of initWithFrame for creating your cell.
In your storyboard, select your table view and open the Connections Inspector. Make sure that the delegate and datasource connections are linked to your argospineFirstViewController object.
in IBOutlet set delegete and datasource of the tableview to filesOwner
you use cell.text for show the data i think its not work in tableview just try this line:-
cell.textlabel.text=[yourArrayname objectatindex:index.row];
no need to connect delegate you already define in protocol.

Table view controller on view controller

I am creating an app in which i want to display a text box and when i enter an word in it ,then it will display the contents from the dictionary which are matching to that word.Now i want to display the list which will generate from my dictionary according to the word entered in text box ,in a table view and that table view should be on the same view controller where i am having the text box.Is it possible to do so. I mean is it possible to create a table view with scrolling option so that user can scroll through the list and then select the word which he wants.
Yes it is possible. Take IBOutlet for UITableView and wire it up. Define its datasource and delegate to your controller. Implement UITableViewDelegate to your controller and override all the methods like cellForRowAtIndex and others.
//FilterDataViewController.h
#import <UIKit/UIKit.h>
#interface FilterDataViewController : UIViewController <UITableViewDelegate>
{
IBOutlet UITableView *tblView;
IBOutlet UITextField *txtFld;
NSMutableArray *arrSrch;
NSMutableArray *srchedData;
}
-(IBAction)srchBtnTapped:(id)sender;
#end
//FilterDataViewController.m
#import "FilterDataViewController.h"
#implementation FilterDataViewController
-(IBAction)srchBtnTapped:(id)sender
{
if(![txtFld.text isEqualToString:#""])
{
[srchedData removeAllObjects];
for (NSString *allStrings in arrSrch)
{
NSComparisonResult result = [allStrings compare:txtFld.text options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [txtFld.text length])];
if (result == NSOrderedSame)
{
[srchedData addObject:allStrings];
}
}
[tblView reloadData];
}
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
arrSrch = [[NSMutableArray alloc] initWithObjects:#"One",#"One Two",#"Two",#"Three",#"Four",#"One Five",#"Six",nil];
srchedData = [[NSMutableArray alloc] init];
}
#pragma mark -
#pragma mark Table view data source
// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [srchedData count];
}
// Customize the appearance of table view cells.
- (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] autorelease];
}
cell.textLabel.text = [srchedData objectAtIndex:indexPath.row];
// Configure the cell.
return cell;
}
#end
This is surely possible. Create a View based Application and put both of your table view and Text Field in the same view and you can do what ever you are planning to do.