How to implement table with row and column - iphone

How to implement a table like in the image? Table with Row and column? Can any tell me the refrence for iphone

The columns are just an illusion.
This is done by subclassing UITableViewCell and designing the cell to have a UIImageView and three UILabels.
Assign the imageView and labels to properties of your subclass and you can configure it this way...
Object *object = [self.datasource objectAtIndexPath:indexPath];
cell.imageView.image = object.image;
cell.subCategoryLabel.text = object.subcategory;
cell.dateLabel.text = object.dateString;
cell.scoreLabel.text = [NSString stringWithFormat:#"%i", object.score];
or something like this.
Then the layout of the labels gives the illusion of having columns.

You need to create custom cell exact according to your requirement. Add data dynamically by adding row and column. Read this http://developer.apple.com/library/ios/#documentation/userexperience/conceptual/tableview_iphone/TableViewCells/TableViewCells.html documentation before implementing custom cell.

Related

Iterate all cells in s UITableView

I want to iterate all uitablewview cells and display the text of a uitextview contained in each cell.
My table can have many rows and to reach all you must scroll. I made an implementation, but it displays the text only for current visible cells in scroll, for the others gives me null.
for (int i = 0; i < [propertiesTableView numberOfRowsInSection:0]; i++) {
UITableViewCell* cell = [propertiesTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
UITextView* tx = (UITextView*)[cell viewWithTag:2];
NSString* temp = tx.text;
NSLog(#"%#", temp);
}
How to fix this?
This happens because only the visible cells are instantiated (remember the dequeueReusableCellWithIdentifier: function?). You should extract the needed information from the table data source.
Yes this behavior is expected, because of performance considerations the table view does not holds all cells initialized all the time. Your solution is just to update your data source - if it's an array for example, iterate though it and change the values accordingly - this is the power of MVC (fast UI, separate model)

Is it possible to create multiple columns in UITableView?

I want to add more columns in my iPhone/iPad application. Is it possible to add more columns in one UITableView? Can you please suggest any sample code/block/project that using multiple columns in one UITableView? Please help me. Thanks in advance.
No it is not possible, in fact UITableView is badly named a represents a List more than a Table.
If you want to have multiple column, one method is to create specific cells, with multiple label, and pack your data by row then column.
short answer is no, but you always can create custom cell what will look like multiple columns
You can use my library, UIGridView.
It is created with UITableView, in which UITableViewCell contains many cells inside.
Here is how it looks like:
No Yuvaraj.M we can't create. but you do something like multicolumn by adding component like label or image or button what u want or else using custom cell.
I've done a grid by using a table view where I have basically faked it by adding subviews to a cell. So if you for example create a cell, add three subviews to it, you can then get the items you need by doing something like this when it asks you for a cell for a specific row:
// get the items for the row (a row is one cell)
NSArray *rowItems = nil;
int startIndex = indexPath.row * NumOfItemViewsPerRow;
if (startIndex + NumOfItemViewsPerRow < [items count]) {
rowItems = [items subarrayWithRange:NSMakeRange(startIndex, NumOfItemViewsPerRow)];
} else {
rowItems = [items subarrayWithRange:NSMakeRange(startIndex, [items count] - startIndex)];
}
Then just after that you can loop the subviews of your row something like this:
[cell.itemViews enumerateObjectsUsingBlock:^(MyItemView *itemView, NSUInteger idx, BOOL *stop) {
NSDictionary *item = [rowItems objectAtIndex:idx];
itemView.titleLabel.text = [item valueForKey:#"title"];
};
It is a bit fiddly, but the upside is that you get row unloading for free from the table view, so you don't have to mess with your own custom grid views or anything like that.
Hope that helps.

Adding different icons to each cells in table view

I want to add different icons to the table view present in my app.Can anyone guide me through a proper array or if possible show some sample code or example.Any help will be appreciated.
Thanks,
Christy
Say the icons are stored as icon0.png, icon1.png and so on in the app bundle.
You can give the icon for each cell as
cell.imageView.image = [UIImage imageNamed:
[NSString stringWithFormat:#"icon%d.png",indexPath.row]];
Swift
cell.imageView?.image = UIImage(named: "icon\(indexPath.row).png")
Well, you have an array somewhere to return the correct number in numberOfRowsInSection. That array is the one you use to fill up the cells. If you only want to display icons in your cells, your array of icons is like that.
So, for example:
UIImage *one = ...;
UIImage *two = ...;
[arrayIcons addObject: one];
[arrayIcons addObject: two];
and in numberOfRowsInSection, return [arrayIcons count].
In the method cellForRowAtIndexPath, you have the variable indexPath. If you want to know which cell you have, you use: indexPath.row.
So, if you load the cell (probably custom, see other answers), which has a UIImageView (say it's named: imageView), and you load the icons in the cells like this:
cell.imageView = [UIImage imageWithContentsOfFile:[arrayIcons objectAtIndex:indexPath.row]];
You wil have to define custom cells for your UITableView.
This tutorial is what you are looking for.

UIButton inside UITableViewController

I have a UIButton that is created inside of each table cell. I want to hook up a touch event like so:
[imageButton addTarget:self
action:#selector(startVote:)
forControlEvents:UIControlEventTouchUpInside];
I want to pass data about the current row (the id of the object for that row) to the startVote method. Is there a method that I am missing to do this or am I breaking some best practice. This seems like a very normal thing to do?
I assume you have some sort of NSArray with the data that gets passed on to the buttons in cellForRowAtIndexPath.
Try this in startVote:
- (void)startVote:(id)sender {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSDictionary *myData = [myArray objectAtIndex:indexPath.row];
}
EDIT:
If for some reason the row is not selected, you can assign a unique tag to every button upon creation and then:
- (void)startVote:(id)sender {
int myTag = [(UIButton *)sender tag];
NSDictionary *myData = [myArray objectAtIndex:myTag];
}
Maybe you would do some sort of operation with the tag so it can be used as an index (I add a certain amount to every tag so it will not conflict with "automatic" tagging used by the OS.
The UITableViewCell doesn't know, out of the box, what row it's displaying in the table. Remember, the intent is that the same cell instances are re-used all over the table to display its data. That said, your UITableViewController is responsible for setting up the cells and passing them to the system (and has the index path, of course). You could, at that point, do something like:
Assuming it's a custom cell class, set a property on the cell instance to identify what row it's displaying, and which your button can later use.
If you're putting these buttons in the cells as their accessory views, take a look at the table delegate's tableView:accessoryButtonTappedForRowWithIndexPath: method.
If it's a one-section table, you could do something really cheesy like store the row index in the button's tag property. Your startVote: method is passed the button, and could then extract its tag.

How can a UITableViewCell know of its own indexPath?

The standard Grouped UITableView style allows UITableViewCells to be drawn with rounded corners at the top and bottom of each section. How is this accomplished? How does the cell know its own location within its section, and how does it know when to change its rounded edges?
I want to make my own rounded cells, and I have images to use, but don't know when to show which image
Note: I already know how the UITableView works, and I know how to use it. I just thought that since a UITableView is able to automatically draw rounded corners at the correct places, I should be able to as well, without needing to add anything to my data source or delegate.
NSIndexPath *indexPath = [(UITableView *)self.superview indexPathForCell: self];
int rows = [(UITableView *)self.superview numberOfRowsInSection:indexPath.section];
if (indexPath.row == 0 && rows == 1) {
// the one and only cell in the section
}
else if (indexPath.row == 0) {
//top
}
else if (indexPath.row != rows - 1) {
//middle
}
else {
//bottom
}
It's very simple. suppose cell is the object, whose position is to be found out.
UITableView* table = (UITableView *)[cell superview];
NSIndexPath* pathOfTheCell = [table indexPathForCell:cell];
NSInteger sectionOfTheCell = [pathOfTheCell section];
NSInteger rowOfTheCell = [pathOfTheCell row];
There is sectionLocation method of UITableViewCell that returns integer telling you what you need:
1 - middle cell
2 - top cell
3 - bottom cell
4 - single cell
I had no issues using this in several production apps since 2010.
UPDATE: one of our binaries was automatically rejected recently (end of 2018) because we were using 'sectionLocation' property, so it's not a good option anymore.
Add something like this into your header files and you can use it:
typedef NS_ENUM(NSInteger, MMMTableViewCellLocation) {
MMMTableViewCellLocationUndefined = 0,
MMMTableViewCellLocationMiddle = 1,
MMMTableViewCellLocationTop = 2,
MMMTableViewCellLocationBottom = 3,
MMMTableViewCellLocationSingle = 4
};
#interface UITableViewCell ()
/** Undocumented method of UITableViewCell which allows to know where within section the cell is located,
* so the cell can draw its borders properly. */
- (MMMTableViewCellLocation)sectionLocation;
/** Override this one to know when the value of sectionLocation changes. */
- (void)setSectionLocation:(MMMTableViewCellLocation)sectionLocation animated:(BOOL)animated;
#end
You can use
- (NSIndexPath *)indexPathForCell:(UITableViewCell *)cell
for this issue. In my example I am using this to scroll the cell (with custom content) to the top of the view.
If you need more robust and general stuff, take a look at http://cocoawithlove.com/2009/04/easy-custom-uitableview-drawing.html - Matt Gallagher shows what you need, pretty effectively. He basically recreates UITableViewController from UIViewController, while adding ability to use your own custom graphics. I'm just working on applying this to one my projects, so far it looks it would do the job.
Unfortunately, I have found no solution to this problem, and have resorted to subclassing UITableViewController and UITableViewCell into a generic solution that I can extend as necessary.
You don't do this in cell. Rounded corners are drawn in [tableView viewForHeaderInSection] and viewForFooterInSection.
The way I do it is to use Plain tableview style, then use these two views for roundness and cells are normal, no rounds.
Without getting into who draws what, you can know which cell is the last cell in its section inside of cellForRowAtIndexPath very easily.
You're passed in the indexPath of the cell you need to provide, right? You're also passed the tableView.
call [tableView numberofRowsInSection:indexPath.section] and if it's == ([indexPath.row]-1) you know you're being asked to supply the last cell in that section.
At the time that cellForRowAtIndexPath is being called, the cell is guaranteed to be at the indexPath passed in.
To expand upon Darren's answer (which I found most useful, thanks Darren!), what you can do is to iterate through all of the superviews' until you find the parent UITableView. This should be future proof since you do not rely on a fixed hierarchy of views.
I use a recursive method that will return the UITableView if it finds one or return nil if there is none.
- (UITableView *)parentTableViewOf:(UIView *)view {
Class class = [view.superview class];
NSLog(#"Class : %#", NSStringFromClass(class));
if([view.superview isKindOfClass:[UITableView class]]) {
return (UITableView *)view.superview;
} else {
return [self parentTableViewOf:view.superview];
}
return nil;
}
So far I've used this one and it seems to work without hiccups. Hope it helps! :)
The cells dont know where they go...The table view has cells, You are the one telling the table view WHAT goes in the cell. You do this in the DataSource where you implement cellForRowAtIndexPath...The way this works :
An index path has a row and a section
For a grouped table view
A section pertains to a group, and a row pertains to 1 entry in that section,
the way UITableView knows how many rows are in a section and how many sections there are is the DataSources methods numberOfSectionInTableView and the method numberOfRowsInSection, this will make the right calls to cellForRowAtIndexPath, it is up to you to recognize which section and row is being queried and you need to build your cell according to these specifications.
A good way to do this i s you can have a Dictionary with keys of section names and values of NSArray with the values that go in that section.
So you implementation for numberOfSectionsInRows would look like
return [[dictionary allKeys] count]
And the implmentation of numberOfRowsInSection would look like
NSString* key=[[dictionary allKeys] objectAtIndex:sectionNumber]
return [[dictionary objectForKey:key] count]
You can always refer to the UITableView programming guide at http://developer.apple.com/iphone/library/documentation/UserExperience/Conceptual/TableView_iPhone/Introduction/Introduction.html
Hope that helps
Simply add a property to your custom UITableViewCell (depending on implementation) class that contains an int, NSNumber, or an NSIndexPath specifying which one it is. In you're using a data structure instead, then put it in you element in that data structure. Then you simply set the property when you create the data structure, something like elt.id=i, and then you access it in the cellForRowAtIndexPath, something like if (elt.id == 0 || elt.id == n-1) where n is the number of rows in your section.
I might have totally missed your question, but if I did, just comment and I'll post again.