Custom UITableView and custom UITableViewCells within ViewController - ios

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

Related

UITableView does not load data

I am relative new to iOS development. Right now, I created 2 ViewController using storyboard. The one consist one button that lead into another controller using segue (show).
This controller is TableViewController that embedded in Navigation Controller and already connected with its responsible class that inherit from UITableViewController.
My problem is this page doesn't load its data (NSMutableArray) that already initialized in viewDidLoad using
_dataClient = [NSMutableArray arrayWithObjects:#"First City",#"Second City",#"Third City",#"Forth City",#"Fift City", nil];
This is my table delegate and datasource:
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 0;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_dataClient count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *cellIdentifier = #"cellItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
// Configure the cell...
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = [_dataClient objectAtIndex:indexPath.row];
return cell;
}
Is there any step that I forgot to do?
You must return 1 section at least. Change this line:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1; /// here
}

Using multiple UITableViews in a XIB

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:

How to work in two UITableView in a single View Controller in ios

How to work in two UITableView in a single View Controller in ios.In my app i designed the textfield and the buttons in a tableview(FirstTableVie).And i try to implement the comboBox in one of the textfield.Here the i implement the delegate function for comboBox tableview(SecondTableView), while i run this it shows the SecondTableView the FirstTableView is not displaying.So hlep me to implement the two bale view in a single ViewController.
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
if(tableView==self.FirstTableView)
{
return 0;
}
else if(tableView==self.SecondTableView){
return [stateArray count];
}
return 0;
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell;
if(tableView==self.FirstTableView)
{
}
else if(tableView==self.SecondTableView)
{
static NSString *identifier=#"Cell";
cell=[tableView dequeueReusableCellWithIdentifier:identifier];
if(cell==nil)
{
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
cell.textLabel.text=[stateArray objectAtIndex:indexPath.row];
}
return cell;
}
You can check like below.I wrote only the conditions not entire code..
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
if(tableView==self.FirstTableView)
{
return 0;
}
else if(tableView==self.SecondTableView){
return [stateArray count];
}
return 0;
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell;
static NSString *identifier=#"Cell";
cell=[tableView dequeueReusableCellWithIdentifier:identifier];
if(cell==nil)
{
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
if(tableView==self.FirstTableView)
{
}
else if(tableView==self.SecondTableView)
{
cell.textLabel.text=[stateArray objectAtIndex:indexPath.row];
}
return cell;
}
Hope it helps you..
Maybe just create custom class/objects that you set the delegate methods to let them own it and implment the delegate methods in your custom classes.
i.e.
#interface TableViewHandler : NSObject
#end
#implmentation
// implement delegate methods
#end
then initialize and allocate these objects and assign them to the delegates of your two table views.
so in your view controller you can do
tableViewHandler *one = [[TableViewHandler alloc] init]; // you can implment an init if you want otherwise it goes to the NSObject init
and then assign the delegate methods of your first table view to this object.
so instead of the typical in a viewController
myTableview.delegate = self
you would do
myTableView.delegate = self.one;
and of course dataSource as well.
The advantage of this over if this table view or that is you can segregate the code.
It depends if you want re-usability of code. There is less re-usability in ViewControllers that are structured with if this class or that or that. Custom classes can be cleanly modified and carried around to other projects as needed. For example if you want to use one of these tables in another project you'd be messing around with copying and paste from the all the delegate methods you add the if else logic to. If you isolate the code you can just port the file.
Add tags to two tableview and check the if the condition while handling in the
table view delegate like
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section ;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if(tableView.tag==1) {
} else {
}
}
I just posted the logic how to approach
Actually I don't see a problem here. Every delegate and dataSource protocol method returns a refernce to a prticular TableView. Just set you view controller as a delegate to both tables and find out which of two is used in callback. You can distinguish tables by tag.
Example:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView.tag == 1) {
return 5;
}else if (tableView.tag == 2){
return 10;
}
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
if (tableView.tag == 1) {
cell = [self configreCellForFirstTableAtIndexPath:indexPath];
}else if (tableView.tag == 2){
cell = [self configreCellForSecondTableAtIndexPath:indexPath];
}
return cell;
}

Correctly use reusable UITableViewCell

I am trying to build an application, that uses reusable UITableViewCells. In my 1st UITableView everything worked right, but now, in my 2nd table I can't use the reusable UITableViewCell, the Cell just stays blank. Here are my configurations:
1; I created a UITableViewCell class
2; I linked the UITableViewCell to the costume UITableViewClass I created in step one
3; I set the "Reuse identifier" to Cell1
4; I added some content to the reusable UITableViewCell
5; I imported the costume UITableViewCell class to my UIViewController
6; I added the standard UITableView code to my UIViewController: <UITableViewDataSource, UITableViewDelegate>, #property (weak, nonatomic) IBOutlet UITableView *tableview;,
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *costumeCell1 = #"Cell1";
AppDetailCell1 *cell1 = [tableView dequeueReusableCellWithIdentifier:costumeCell1];
if (!cell1) {
cell1 = [[AppDetailCell1 alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:costumeCell1];
}
cell1.appIconImageView.image = self.appIcon;
cell1.detailAppNameTextView.text = self.detailAppName;
cell1.developerLabel.text = [NSString stringWithFormat:#"By %#", self.appDeveloper];
return cell1;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
7; I build the project, but I only can find a blank UITableView
I made it the same way as I have done it with the other reusable TableViewCell in an other UIViewController.
Anyone have an idea how I can solve my problem?

Setting up multiple sections in UITableView

I have setup a uitableview with custom cells.
I would like these into sections with a title. Looking at the below photo I am looking for the following layout:
Section - My Profile
Custom cell - wwwwwwwwwwwwww...
Section - Application
Custom cell - Games
Custom cell - Share
Custom cell - Rate
Custom cell - Settings
Custom cell - Help
Custom cell - Log out
I can see how to add a section and control the rows in a section, but this duplicates the cells into multiple sections, I am not sure how to have one section with one row and another section with 6 rows. I also want to style these sections to show, slightly like the Facebook menu style.
Should I create custom cells for the actual sections instead and have no action on the section (cell) selection?
Here is the code for the UITableView
static NSString *CellIdentifier = #"Cell";
LeftMenuTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray* views = [[NSBundle mainBundle] loadNibNamed:#"LeftMenuTableViewCell" owner:nil options:nil];
for (UIView *view in views) {
if([view isKindOfClass:[UITableViewCell class]]) {
cell = (LeftMenuTableViewCell*)view;
}
}
}
You could define number of sections and rows in it as following:
- (UIView *) tableview:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView view;
if(section == 0) {
// Initialise view for section 1
} else {
// Initialise view for section 2
}
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return ((section == 0) ? 1 : 6);
}
-(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;
}

Resources