I have created a custom widget as a XIB file where I have multiple UITableViews and a UIButton. In the corresponding swift file which is the owner of this XIB, I have outlets to these TableViews.
I have added this widget to a view inside a view in a UIViewController. Now in the corresponding swift file of this controller, I need to assign dataSource and delegate to each of the tableviews, and an action to the button.
I have been looking online for long, and seems like #IBInspectable vars are the way to go, but seems like I cannot make a var which of type UITableView,UITableViewDelegate or UITableViewDatasource as #IBInspectable.
So how do I use the tableviews and the button? Can anyone direct me to the correct documentation, example, or explain?
No need to use an #IBInspectable. You can simply use each table source within the UITableViewDelegate methods conditionally. Here's one way to go about doing this:
First within your storyboard's UITableViewController, add a prototype cell, then within that prototype cell add a UITableView with its own prototype cell.
Then set both the inner and outer table view cell's reuse identifiers like so:
Outer table view cell:
Inner table view cell:
Then link that inner tableview's data source and delegate to the UITableViewController's own data source and delegate:
Then within your UITableViewController class, you can set your tables' elements conditionally, for example:
- (void)viewDidLoad {
[super viewDidLoad];
dataSource1 = [NSArray arrayWithObjects:#"1", #"2", #"3", #"4", #"5", #"6", #"7", nil];
dataSource2 = [NSArray arrayWithObjects:#"a", #"b", #"c", nil];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == self.tableView) {
return 80;
} else {
return 20;
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
if (tableView == self.tableView) {
return dataSource1.count;
} else {
return dataSource2.count;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
if (tableView == self.tableView) {
cell = [tableView dequeueReusableCellWithIdentifier:#"reuseIdentifier" forIndexPath:indexPath];
} else {
cell = [tableView dequeueReusableCellWithIdentifier:#"reuseIdentifier2" forIndexPath:indexPath];
}
// Configure the cell...
if (tableView == self.tableView) {
cell.textLabel.text = [dataSource1 objectAtIndex:indexPath.row];
} else {
cell.textLabel.text = [dataSource2 objectAtIndex:indexPath.row];
cell.backgroundColor = [UIColor blueColor];
}
cell.textLabel.backgroundColor = [UIColor clearColor];
return cell;
}
Which in this case produces the following result:
Related
I am developing Iphone Application.Using Three table view on Single viewcontroller. value show on those tableview's on single array but problem is that those array value show on first tableview not on other two tableview's. please help Thanks in advance
code..
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_arrayResult 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];
}
MEObject *obj = [_arrayResult objectAtIndex:indexPath.row];
if (tableView == _tableView) {
cell.textLabel.text= obj.emp_client_name;
}
if (tableView == _secondTableView) {
cell.textLabel.text= obj.emp_event_name;
}
if (tableView == _thirdTableView) {
cell.textLabel.text=obj.emp_client_name;
}
return cell;
}
Please cross check if you are setting datasource and delegates of all 3 tables to viewcontroller.
When you set your _arrayResult, you need to reload all 3 table view
_arrayResult = #[a,b,c];
[table1 reloadData];
[table2 reloadData];
[table3 reloadData];
After once you set the datasource/Delegate to the all three tableview. I haven't seen any datasource allocation as per your tableview. Like
if tableview == tableview1 {
Return first array
}
Can you please try giving name to those tableview on outlet and then for each datasource and delegates function call as per your requirement but before check which tableview is displayed.
I have a UITableViewController that I'm building up in my application. This UITableViewController (SelectedLanguages) is called from another UITableViewController (ChooseLanguage) where there is a static list of languages for the user to select.
In the SelectedLanguages UITableViewController, I want to achieve the following:
2 Sections
The first section will have between 1 and 5 cells
The second section will always have 12 cells.
The number of cells in the first section is entirely dependent on which language the user chooses in the ChooseLanguage UITableViewController. For example, clicking on English will mean the first section in the SelectedLanguage UITableViewController will have 5 cells, but choosing French in the ChooseLanguage UITableViewController will mean the first section in the SelectedLanguage will only have 1 cell.
As mentioned, the second section will always have 12 cells in the SelectedLanguage.
I have designed this UITableViewController in Interface Builder. What I've seen is that only if the the Content is specified as Static Cells can you have multiple "sections".
Even if you set the Content to Dynamic and Grouped, I can't seem to find a way to determine sections other than in code.
The reason I'm defining this in Interface Builder is because section 1 and section 2 will need to have a very customised layout of the size of the cells, as well as the labels that go into each cell.
The content of the first section is not dynamic; it is static because while building this application, I'll know exactly how many cells there should be in the first section for each language, so in my head, it is correct to use a Static cell.
My question is, how can I achieve setting the number of cells in the top section, in code?
In the prepareForSegue of the ChooseLanguage, I could check the called cell title and then perform some action in the SelectedTransactions. The action to perform here is what I'm confused about.
I know there's the method - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section in the UITableView Data Source, but I'm not sure how and what to do with this with my particular situation.
Any guidance would be really appreciated.
My easiest answer for your question is below
in .m
import "ViewController.h"
#interface ViewController ()
{
NSMutableArray *arraysection1;
NSMutableArray *arraysection2;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
arraySection1 = [[NSMutableArray alloc]initWithObjects:#"One",#"Two",#"Three",#"Four",#"Five",nil];
arraySection2 = [[NSMutableArray alloc]initWithObjects:#"1",#"2",#"3",#"4",#"5",nil];
}
#UITableView Delegate Methods
#UITableView DataSource Methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
//If you have 2 sections,
return 2;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//set row of two sections with condition
if(section==0)
{
return arraySection1.count;
}
else
{
return arraySection2.count;
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *strCellIdentifier = #"CellIndentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:strCellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:strCellIdentifier];
}
if(indexPath.section==0)
{
cell.textLabel.text = [NSString stringWithFormat:#"%#",[arraySection1 objectAtIndex:indexPath.row]];
NSLog(#"The textLabel is-%#",cell.textLabel.text);
}
else
{
cell.textLabel.text = [NSString stringWithFormat:#"%#",[arraySection2 objectAtIndex:indexPath.row]];
NSLog(#"The textLabel is-%#",cell.textLabel.text);
}
return cell;
}
#UITableView Delegate Methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.section==0)
{
if(indexPath.row==0)
{
//Do whatever you want here
}
else if(indexPath.row==1)
{
//Do whatever you want here
}
else if(indexPath.row==2)
{
//Do whatever you want here
}
else if(indexPath.row==3)
{
//Do whatever you want here
}
else
{
//Do whatever you want here
}
}
else
{
if(indexPath.row==0)
{
//Do whatever you want here
}
else if(indexPath.row==1)
{
//Do whatever you want here
}
else if(indexPath.row==2)
{
//Do whatever you want here
}
else if(indexPath.row==3)
{
//Do whatever you want here
}
else
{
//Do whatever you want here
}
}
}
From what you are describing it sounds like your tableView should be dynamic.
You will have to handle this programmatically, forget about interface builder
Here is what you need:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;//2 Sections
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
switch (section) {
case 0:
//The first section will have between 1 and 5 cells
//Put the logic to return the correct number of cells
return 5;
break;
case 1:
//The second section will always have 12 cells.
return 12;
break;
default:
break;
}
return 0;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
switch (indexPath.section) {
case 0:
[[cell textLabel] setText:#"same title section 1"];
break;
case 1:
[[cell textLabel] setText:#"same title section 2"];
break;
default:
break;
}
return cell;
}
Then, I have my ViewController displaying a TableView containing 2 custom cells:
So, I created 2 Cocoa Touch file classes: CellClassOne and CellClassTwo, I set the custom classes to appropriate cells in interface builder via the Identity Inspector, and after, I import header files to the View Controller implementation file:
And now I implement methods and protocols for UITableView (protocols declared in the ViewController header file), my code looks like this, but I know that it is not correct at all...
Am I missing some things ?
#pragma mark Cell Classes Table View data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 2;
}
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0) {
CellClassOne *cellClassOne = [tableView dequeueReusableCellWithIdentifier:#"CellClassOne" forIndexPath:indexPath];
if (cellClassOne == nil) {
cellClassOne = [[CellClassOne alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"CellClassOne"];
}
return cellClassOne;
}
else if (indexPath.row == 1) {
CellClassTwo *cellClassTwo = [tableView dequeueReusableCellWithIdentifier:#"CellClassTwo" forIndexPath:indexPath];
if (cellClassTwo == nil) {
cellClassTwo = [[CellClassTwo alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"CellClassTwo"];
}
return cellClassTwo;
}
return nil;
}
#end
1.Select the cell1 in interface builder and assign the "CellClassOne" cellIdentifier there...Do the same for cell2 i.e. CellClassTwo.
2.Add UITableViewDataSource and UITableViewDelegate next to #interface ViewController
i want to use two tableviews like…..
i am using popover controller
first tableview is in the popover controller
in that popover controller i have two buttons(add notes button and remainder button)
when i click on the remainder button i am hiding the first tableview and enabling the second tableview
ut for the second tableview cellforrowatindexpath is not calling
only for the first tableview it is calling,not calling for the second table view
here my code is………..
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView==self.remainderTableView)//second Tbleview {
static NSString *cellIdentifier=#"Celliden";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell==nil) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
cell.textLabel.text=#"hhh";
return cell;
}
else if (tableView==self.NotesandRemainderTable)//first Tableview {
static NSString *cellIdentifier = #"bookingCell";
CustomTableViewSwipeCell *cell = (CustomTableViewSwipeCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
NSString *note=[jsondata valueForKey:#"TeacherNotes"];
NSLog(#"teacher notes %#",note);
// if (cell==nil) {
// cell=[[CustomTableViewSwipeCell alloc]init];
// }
// Add utility buttons
NSMutableArray *rightUtilityButtons = [NSMutableArray new];
[rightUtilityButtons sw_addUtilityButtonWithColor:
[UIColor colorWithRed:1.0f green:0.231f blue:0.188 alpha:1.0f]
title:#"Delete"];
_SubjectLabel.text=AppDel.sub;
NSLog(#"the date %#",AppDel.date);
_DateLabel.text=_dateToDisplay;
if (indexPath.section==0)
{
if (indexPath.row==0)
{
cell.Noteslabel.text=note;
}
return cell;
}
if (indexPath.section==1){
cell.Noteslabel.text=[_notesArray objectAtIndex:indexPath.row];
//NSLog(#"notes index %#",[notesArray objectAtIndex:indexPath.row]);
cell.rightUtilityButtons = rightUtilityButtons;
cell.delegate=self;
return cell;
}
}
//cell.rightUtilityButtons = rightUtilityButtons;
return nil;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView==self.NotesandRemainderTable) {
if (section==0) {
return 1;
}
else if (section==1) {
if (leanerNots==nil || [leanerNots isEqual:[NSNull null]]) {
return 0;
}
else{
return [_notesArray count];
}
}
}else{
return 3;
}
return 0;
}
//This my remainder button code......
-(IBAction)addRemainderAction:(id)sender{
self.lineLabel.hidden=NO;
self.remainderTableView.hidden=NO;
self.addButtonObj.hidden=NO;
//self.remainderTableView.frame=CGRectMake(0, 62, 300, 321);
//[self.view addSubview:self.remainderTableView];
self.NotesandRemainderTable.hidden=YES;
self.notesBtnObj.hidden=YES;
self.remainderBtnObj.hidden=YES;
_SubjectLabel.hidden=YES;
}
Can any one help to solve this bug...i am new to Xcode
Did you set the datasource and delegate of your second tableview?
for example in viewDidLoad:
self.remainderTableView.datasource = self;
self.remainderTableView.delegate = self;
And you probably want to reload your tableviews before they are displayed. To do so use the following code for your second tableview
[self.remainderTableView reloadData];
It's not totally clear from this code whether you have set the delegate and dataSource correctly for both UITableView instances. If you have not, then these delegate methods will never get called.
Regardless, this case might be better handled by using two data sets instead of two tableViews. Implement cellForRowAtIndexPath the same way you are now, except instead of creating your cell conditionally based on the value of tableView, just use the value of your UIButton. Two UITableViews seems like overkill for this situation when the UITableViewDelegate and UITableViewDataSource methods allow you to source from different data sets easily already.
I have a cell prototype in storyboard. So I custom the height, subview (Labels and Images).
But eventually the cell does not appear to be used for SearchDisplayController...
Code snippet >>
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
#warning Reusable cell not working for custom cell.
ItemCell *cell = [tableView dequeueReusableCellWithIdentifier:itemCell];
if (cell == nil) {
cell = [[ItemCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:itemCell];
}
if (tableView == self.searchDisplayController.searchResultsTableView){
cell.itemLabel.text = [_filteredList objectAtIndex:indexPath.row];
cell.priceLabel.text = #"RM 7.00";
// TODO : Insert Image Here
} else {
cell.itemLabel.text = [_items objectAtIndex:indexPath.row];
cell.priceLabel.text = #"RM 7.00";
// TODO : Insert Image Here
}
return cell;}
I'm out of idea. Even if I use self.tableView instead of tableView it shows something like this.
add the following code before cell for row method.
- (void)searchDisplayController:(UISearchDisplayController *)controller didLoadSearchResultsTableView:(UITableView *)tableView
{
tableView.rowHeight = 24.0f; // this should be the same hight as the re usable cell you implemented
}
Then when the table view loads and search is performed the cell hight of the searchcontroller and the tableview would be the same.
you should make further changes using this method, for example:
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[controller.searchResultsTableView setBackgroundColor:[UIColor colorWithRed:0xED/255.0 green:0xED/255.0 blue:0xED/255.0 alpha:1.0]];
controller.searchResultsTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
return YES;
}