I have a button, a pickerview and a tableview. When I push the button, the current selection of pickerview will be filled in the table view. Here is the code of button which pick value from pickerview
- (IBAction)addCourse:(UIButton *)sender {
NSInteger numRow=[picker selectedRowInComponent:kNumComponent];//0=1st,1=2nd,etc
NSInteger SeaRow=[picker selectedRowInComponent:kSeaComponent];//0=fall,1=spring,2=summer
NSInteger CourseRow=[picker selectedRowInComponent:kCourseComponent];
NSString *num=Number[numRow];
NSString *season=Season[SeaRow];
NSString *course=Course[CourseRow];
NSString *msgCourse=[[NSString alloc ]initWithFormat:#"%# ",course];
NSString *msgSeason=[[NSString alloc ]initWithFormat:#"%# ",season];
NSString *msgYear=[[NSString alloc ]initWithFormat:#"%# ",num];
}
Then I want to populate msgCourse,etc to my tableview
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
...Content from above msgCourse and etc
return cell;
}
How to fix the gap in my second part please? Or any example to look at please?
Check the following code to decide whether or not that fits into your requirements based on what I understand from your question. If it does not, please leave a comment then I will try my best to follow up.
First Step: if you have not done the delegation via storyboard, here is the first thing that you should do programatically:
-(void)ViewDidLoad
{
tableView.delegate = self;
tableView.datasource = self;
}
Second Step: I have not seen a mutablearray in your code, but I assume that you are going to make msgCourse to NSMutableArray.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// I assume you have only one section
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.msgCourse count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if(!cell){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"Cell"];
}
cell.textLabel.text=[self.msgCourse objectAtIndex:indexPath.row];
return cell;
}
Last Step: By the way, do not forget to add the following line of code into your button action to reload your tableView, I assume you update the NSMutableArray and would like to refresh the tableView.
- (IBAction)addCourse:(UIButton *)sender {
.....
.....
.....
[tableView reloadData];
}
Here is the good tutorial, it is worth to duplicate for the sake of learning: http://www.appcoda.com/ios-programming-tutorial-create-a-simple-table-view-app/
Related
I am just starting iOS development. I am trying to display a multiple columns in UItableview from NSArray? So please help me anyone? I have created one column but i don,t know how to create another column?
I have done the following.
// This is my code
- (NSArray *)numbers
{
NSArray *col1 = #[#"1", #"2", #"3", #"4", #"5"];
return col1;
}
- (NSArray *)numberCodes
{
NSArray *col2 = #[#"Roy", #"Ankit", #"Jhon", #"Kem", #"Pawan"];
return col2;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.numbers.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
//cell.textLabel.text = [self.numbers objectAtIndex:indexPath.row];
cell.textLabel.text = [self.numberCodes objectAtIndex:indexPath.row];
return cell;
}
Step-1
on your viewController.h create the one Global Array like
#property (nonatomic,retain) NSMutableArray *tableData;
on your ViewController.m allocate the memory of that array like
- (void)viewDidLoad
{
[super viewDidLoad];
tableData = [[NSMutableArray alloc] initWithObjects:#"One",#"Two",#"Three",#"Four",#"Five",#"Six",#"Seven",#"Eight",#"Nine",#"Ten",nil];
}
on that tableview Datasource method do like
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [tableData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"XXXX";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [tableData objectAtIndex:indexPath.row];
return cell;
}
for sample see this
1. You may create costume cell like having multiple fields/column in table. 2. Place multiple table view, one for each column. Use auto-layout for better look.
I a UITableView called tableView. It's data array called namesArray.
I have a function that adds a name to the array that looks like this:
-(void)addName:(NSString*)name
{
[self.namesArray addObject: name];
[self.tableView reloadData];
}
After I call reloadData on tableView, the last cell (the one that was added) is not showing on tableView, numberOfRowsInSection return the actual number so there is a space for another cell but there is not an actual cell.
I was debugging cellForRowAtIndexPath and I was found out that when cellForRowAtIndexPath called for the new cell, dequeueReusableCellWithIdentifier returns nil while when it called to the other cells (except when indexPath.row == 0 of course) it returns a cell.
The code for cellForRowAtIndexPath:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier=#"Cell";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text=[self.namesArray objectAtIndex:indexPath.row];
return cell;
}
numberOfRows:
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.namesArray.count;
}
Note: if I try to print the last object of namesArray using NSLog it's looking fine (the last object is the new one that was created) so it's a problem with reloading the data of tableView
Can you please help me? Thanks!
check the number of rows you returns in numberOfRowsInSection
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
it should be something like:
[self.namesArray count];
First dataSource and delegate the tableview. after that make sure using below method with perfection
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [your array count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier=#"Cell";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text=[self.namesArray objectAtIndex:indexPath.row];
return cell;
}
After that reload tableView with
[_tableViewName reloadData];
-(void)addName:(NSString*)name
{
[self.namesArray addObject: name];
[self.tableView reloadData];
}
If you are calling this function again and again to fill the array then, do not reload tableview in this method. Because, its getting reloaded overtime you call this method and cellForRowAtIndexPath gets called every time. So, after your array gets filled completely then, reload the tableview
.h
#interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
{
IBOutlet UITextField *txtName;
IBOutlet UITableView *tableObject;
NSMutableArray *namesArray;
}
- (IBAction)btnAdd:(UIButton *)sender;
.m
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
namesArray = [[NSMutableArray alloc] init];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{
return namesArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
static NSString *cellIdentifier=#"Cell";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text=[namesArray objectAtIndex:indexPath.row];
return cell;
}
-(void)addName:(NSString*)name
{
[namesArray addObject: name];
[tableObject reloadData];
}
- (IBAction)btnAdd:(UIButton *)sender {
[self addName:txtName.text];
}
I have a tableview whose data are selected from a pickerView(3 columns).Here is the code:
- (void)viewDidLoad {
[super viewDidLoad];
//PickerView content and sort them for displaying
Number=#[#"Trans",#"2005",#"2006",#"2007",#"2008",#"2009",#"2010",#"2011",#"2012",#"2013",#"2014",#"2015",#"2016"];
Season=#[#"Spring",#"Summer",#"Fall"];
Course=#[#"CHEM1100 General Chem I",#"CHEM2100 General Chem II",#"CHEM3511 Org Chem",#"CHEM3521 Org Chem II"];
Course =[Course sortedArrayUsingSelector:#selector(compare:)];
Number =[Number sortedArrayUsingSelector:#selector(compare:)];
Season =[Season sortedArrayUsingSelector:#selector(compare:)];
_tableView.delegate = self;
_tableView.dataSource = self;
}
To populate the tableView, I use a button, when the button is pushed, the selection of pickerView will send data to tableView
- (IBAction)addCourse:(UIButton *)sender {
NSInteger numRow=[picker selectedRowInComponent:kNumComponent];//0=1st,1=2nd,etc
NSInteger SeaRow=[picker selectedRowInComponent:kSeaComponent];//0=fall,1=spring,2=summer
NSInteger CourseRow=[picker selectedRowInComponent:kCourseComponent];
NSString *num=Number[numRow];
NSString *season=Season[SeaRow];
NSString *course=Course[CourseRow];
NSString *CourseToAdd=[[NSString alloc ]initWithFormat:#"%# ",course];
NSString *SeasonToAdd=[[NSString alloc ]initWithFormat:#"%# ",season];
NSString *YearToAdd=[[NSString alloc ]initWithFormat:#"%# ",num];
[self.msgCourse addObject:CourseToAdd];
[self.msgSeason addObject:SeasonToAdd];
[self.msgYear addObject:YearToAdd];
[_tableView reloadData];
}
To show the data in tableView, I use
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if(!cell){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"Cell"];
}
cell.textLabel.text=[self.msgCourse objectAtIndex:indexPath.row];
return cell;
}
To determine the rows and sections
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
//return [self.msgYear count];
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [self.msgCourse count];
}
It is running fine. The output is shown in the picture attached.
Here are my questions:
(1) I want the tableView shown in more than one sections. For example, "2005 Fall" is one section, inside this section, the courses are shown. In other words, the first two columns selected in the pickerview will form the section title.
(2) How to sort the results in each section?
You could define number of sections and rows in it as following:
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// number of courses?
return 3;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return ((section == 0) ? 1 : 3);
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// return appropriate cell(s) based on section
if(indexPath.section == 0)
{
// Return 1 cell
}
else if(indexPath.section == 1)
{
switch(indexPath.row) {
case 0: // Initialize cell 1
break;
case 1: // Initialize cell 2
break;
...
}
}
return cell;
}
Here are the good tutorials to learn more:
http://www.appcoda.com/ios-programming-index-list-uitableview/
http://briterideas.blogspot.com/2012/07/uitableview-how-to-part-3-multiple.html
https://owenandrewsblog.wordpress.com/2012/01/29/uitableview-sections-tutorial/
I can't find a simple, concise answer anywhere and I refuse to believe that XCode makes things as hard as other tutorials I've found out there...
Say I have the following array
NSArray* days = [NSArray arrayWithObjects:#"Sunday",#"Monday",#Tuesday",#"Wednesday",#"Thursday",#"Friday",#"Saturday",nil];
I have a UI Table View, table_Days, that I would like to simply show the items from my array. What is the proper way to go about populating my table?
Here's my full explanation, starting with a case extremely similar to yours:
http://www.apeth.com/iOSBook/ch21.html#_table_view_data
So suppose days is stored as an instance variable accessed through a property self.days. Then set self as the table view's datasource and use this code:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (!self.days) // data not ready?
return 0;
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return [self.days count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:#"Cell"
forIndexPath:indexPath];
cell.textLabel.text = (self.days)[indexPath.row];
return cell;
}
You should populate your table view using the data source methods. Returning the count of the array for the number of rows.
If you need to detect when a user taps on a cell you can use the delegate methods.
#interface ViewController<UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, copy) NSArray *days;
#property (nonatomic, strong) UITableView *tableDays;
#end
#implementation ViewController
-(void)viewDidLoad
{
[super viewDidLoad];
UITableView *tableDays; // Set this up
[tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"Cell"];
tableDays.delegate = self;
tableDays.dataSource = self;
[self.view addSubview:tableDays];
self.tableDays = tableDays;
self.days = #[#"Sunday", #"Monday", #"Tuesday", #"Wednesday", #"Thursday", #"Friday", #"Saturday"];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.days count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.textLabel.text = self.days[indexPath.row];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *day = self.days[indexPath.row];
NSLog(#"Day tapped: %#", day);
}
#end
You should consider using a UITableViewController if you just want to show a table view.
Note that its better practice to use camel case for variables.
I have a viewcontroller set up on my storyboard, and I have inserted a tableView inside this view controller. I want to do a [self.tableView reloadData]; on viewDidLoad, but it says the property tableView isn't found.
Here is what the code for my tableView in the viewcontroller.m file looks like:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return #"Shared with";
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return activeUsers.count;
}
- (sharedUsersTable *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"sharedUser";
sharedUsersTable *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[sharedUsersTable alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSDictionary *key = [activeUsers objectAtIndex:indexPath.row];
NSString *name = [key objectForKey:#"shared_user_name"];
NSString *email = [key objectForKey:#"email"];
cell.textLabel.text = [NSString stringWithFormat:#"%#", name];
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#", email];
return cell;
}
Am I missing some special command to call a tableView inside a view controller which isn't a TableViewCOntroller?
You need to make a IBOutlet of tableView and call reloadData on that.
This depends on how you declared your UITableView.
If it is a property (#property (nonatomic, strong) UITableView *myTableView), it will be [self.myTableView reloadData]. If you declared it as just an instance variable (UITableView *_myTableView), it will be [_myTableView reloadData].
you'll have to define tableview datasource and delegate as self.. like table.datasource=self,
and table.delegate=self.....you can do it in viewdidload....but if you have downloaded the data somewhere, then you can do it in that place where you have downloaded and reload the table there. please assign the delegate and datasource to the table and reload the tableview after you have downloaded the data....and please make a property like(#property (nonatomic, strong) UITableView *table)and use self when you do the reload...