Adding different views to UITableViewCell - iphone

In my app, i have addressbook which has a tableview to list contacts and in the right panel, i display the contact detail. In my contact detail page, i have fields like email, cellphone, workphone and homephone etc., and i have separate UIView for each field like cellphone, workphone etc., The Concept is to display the UIview of cellphone or workphone or such field only if there is a value for it. So its better to do it with a tableview right. My question is, can we add the UIView of those fields to the tableViewCell? i have attached the screenshot of the normal view. can i implement tableview here and add the UIView of each field to tableViewCell?

Create different custom cell for the different types you need and they should be with different identifiers. Then you can create a method that takes the correct identifier:
- (NSString *)identifierForIndexPath:(NSIndexPath *)indexPath
{
if (someCondition) {
return #"youCellIdentifier";
} else if (otherCondition) {
return #"yourCellOtherIdentifier";
}
}
Then you can use this method in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
If you have questions concerning this, feel free to ask.

CellView.frame=CGrectMake(0,0,150,50);
HomeView.frame=CGrectMake(0,60,150,50);
WorkView.frame=CGrectMake(0,120,150,50);
EmailView.frame=CGrectMake(0,180,150,50);
[Cell.contentview addsubview:cellview];
[Cell.contentview addsubview:HomeView];
[Cell.contentview addsubview:WorkView];
[Cell.contentview addsubview:EmailView];

Use custom UITableViewCells:
In your storyboard, create prototype cells. Drag there the elements you want for the different kinds of cells and position them appropriately. In your example, you will need one prototype cell for the blue cells and another one for the gray cell.
Subclass UITableViewCell. Create new Objective-C class for the new kinds of cells and select UITableViewCell as superclass.
Link the storyboard and the new classes. Go to the storyboard and select the cells. Enter as cell class the names of the newly created classes (instead of the default UITableViewCell. Create IBOutlets for the elements in the cells.
In your view controller, when creating new cells, set the values for the cell elements.
Hope, that helps you.

Related

How to set the height of subviews of UItableViewCell when cell is created programaticalliy

I have custom cell created with nib. In the table view I am using the method -(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath to set the height of cell
Everything works fine.
But the problem is that I also want to change the size of UIlabel which is added as subview in nib of cell.
How do I do that?
Which metod to override in customcell class ?
The method you are looking for is:
-(void)layoutSubviews
{
[super layoutSubview];
//Do your magic
}
layoutSubviews is call after the cell is created and whenever the device orientation changes, to allow you to resize and/or move the subviews (plus make any other minor adjustments) to compensate for differences between the orientations, but in this case you can also use it to redraw your subviews.
As you have UILabel in your custom cell class, make a function in that class that take frame you want to set as parameter. Set frame of label in that function. You need to call this function from your cellForRowAtIndexPath method before returning the cell.
If you are reusing your custom cell you should call method only when the (cell == nil)
Also if you can add some code in your question that would be helpful and you can get more precise answer.
You need to treat your custom cell in the same way you would treat a normal view or view controller class with a xib. i.e. You need to create IBOutlets for the controls in you custom cell and during creation of the cell you can access the controls quite easily.
myCell.myCustomUILabel.text = #"blah"
There are some gotchas when using custom cells in a xib and onnecting up the IBOutlets. This SO answer (of mine) explains how to create and link up IBOutlets of a custom cell.

Adding UIPickerView to a UITableViewCell

I want to add a UIPickerView to a UITableViewCell. Right now I am just getting a black window. Can someone also explain me the concept of subclassing UI objects to a cell ie:when do we make our cell as the delegate and the datasource delegate? Thanks
EDIT: Here is the code of what i am doing right now
case 1: {
cell = [tableView dequeueReusableCellWithIdentifier:#"groups"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"groups"];
}
/*NSString *myGroupDetail = [_groupArray objectAtIndex:indexPath.row];
NSLog(#"the group detail label is %#",myGroupDetail);
cell.textLabel.text = myGroupDetail;
*/
[cell addSubview:_groupPicker];
break;
}
The groups is the section in which I want the picker view, I am getting that data from an array.
you would have to allocate and initialize a pickerview in your cellForRow method of the tableviewdelegate. ill sketch it for you =) how to initialize a cell itself should not be hard to find out if you google a bit ;-)
...(tableView *)... cellForRowAtIndexPath... {
if(indexPath.row == pickerRow){
UIPickerView *pickerView = [[UIPickerView alloc]init];
cell = ... // alloc and initialize a cell
cell addSubview:pickerView];
}
else{ // your other cells }
return cell;
}
UPDATE: im currently having trouble with git, so i uploaded a sample project to my private server: UITablePicker example
github: https://github.com/sebamisc/UItableViewWithPicker
yu can modify and use the code however you want =)
sebastian
Well, I never did exactly that.
Does it have to be in a cell or could you use the table's header or footer view for that? (I would not suggest a section header/footer view.)
Assuming it is within a UITableViewCell.
Yes, I personally would subclass UITableViewCell. Did that a lot. In that case you cell object could be the data source delegate of the picker. For doing so your subclass of UITableViewCell (let's assume you name it MyTableViewCell) needs to fulfil the related protocol. You add that UIPickerView programmatically within the init Method (initWithStyle) of MyTableViewCell. For the layout within the table cell, you should overwrite the method layoutSubviews. If your app can be rotated to landscape and portrait orientations and/or if your app is designed to run on iPad as well, then this method should dynamically consider the table's bounds. (Screen or windwo bounds are often used hiere but that is not save when the table is displayed within a split master view or a popup view on iPads.)
Strictly spoken your MyTableViewCell should not be the data source delegate, simply because it is a view element and view objects are not supposed to manage any business logic within an MVC design pattern. Smarter would be the implementation of some dedicated view controller for your table view cell hat fulfills the protocol and is assigned as the delegate. However, both would work. In the event that it is the only picker view within your sell, then you could easily use your UITableViewController subclass even without tagging the UIPickerView.
An alternative to subclassing a UITableViewCell is to create the UIPickerView within the cellForRowAtIndexPath method of your tableViewController. That is fine for singe-orientation apps. However, you may setup it in a way that it re-arranges its the UIPickerView automatically.
In any case you should overwrite the heightForRowAtIndexPath method of UITableViewController when your table views do not have the same hight any more. If all of them still have the same height, then you can simply set the rowHeight property of your UITableView.

Using rounded-rect button for TableView footer in iPhone?

I'm trying to put a button to footer of TableView.
This is what i did and I can't see the button but the string "RESULT" is displayed.
I've tried everything I can think of. but I couldn't figure out what's wrong. I need you help!
- (void)viewDidLoad {
btnSeeResult = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btnSeeResult setTitle:#"RESULT" forState:UIControlStateNormal];
viewResult = [[UIView alloc] initWithFrame:btnSeeResult.frame];
[viewResult addSubview:btnSeeResult];
self.tableView.tableFooterView = btnSeeResult;
}
-(CGFloat) tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
return viewResult.bounds.size.height;
}
Anyway, what's the difference between setting the footer view directly like
tableView.tableFooterView = footerView;
and using (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section method??
There's no reason for the viewResult wrapper. A UIButton is a UIView, so there's no reason to wrap it in another UIView in this case - especially since you then assign the button to the table's footer property which means the table should be taking control of how and when the button view ultimately displays.
You may have to set the btnSeeResult's frame so that it has a height set. It's possible the height is 0 by default in that case since you don't ever set a frame for it. You might also try something like [btnSeeResult sizeToFit]; after you set the title which should resize it enough to make room for the label text, at least.
As to your second question, the difference between tableFooterView and -(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section is that the former defines a view to attach to the bottom of the entire table, whereas the delegate method allows you to give each sub-section in your table different footers. Both can be used at the same time and in that case the last section's footer view would appear followed finally by the tableFooterView.
SeniorLee,
Welcome to StackOverflow!
You've got the right answer in your question - it's the latter code:
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
When the table view goes to construct your table, it calls back to 2 classes - the table's delegate, and the table's data source.
Data Source is just what the name implies - the source of the data that is in your table. The Delegate, on the other hand, handles real-time interaction with the table and how it is to be displayed (e.g. what happens when the row is pressed?).
In many many cases, programmers set both the Data Source and the Delegate of the table view to the same class - the UITableViewController that owns the table view.
Anyhow, on to your question:
It's highly likely that the direct assignment isn't working explicitly because there is a delegate callback. When the table view goes to lay itself out, it will ask its delegate "do you have a view for the footer in section x?". That's the method above.
If you don't implement that method, the table view will have a default implementation that does something - in this case, probably set it to nil.
So, my guess is that even though you set this property directly in viewDidLoad, it's being overwritten to nil by the table view because you're not implementing the delegate callback. Instead, move your view code to the callback method and it should work beautifully.
Also, I don't think you need to wrap your UIButton in a UIView - UIButton is a subclass of UIView and thus should work just fine.

Text under a UITableView cell

The iPhone's settings application is build around a UITableview. In some views there are additional texts between cells. For example in "Settings" -> "General" -> "Network" there is the text
"Using 3G loads data faster, but may descrease battery life" under a cell with an UISwitch. Any ideas how to implement this?
Images of what I mean can be found here:
http://www.tipb.com/2008/07/12/how-to-disable-3g-on-the-iphone-3g-for-more-talk-but-less-speed/
If you have a grouped table view, the tableView:titleForFooterInSection: method found in the UITableViewDataSource protocol and the UITableViewController class handles this for you:
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
if (section == 0) {
return #"Footer text for first section, goes below cells in that group.";
}
return nil;
}
To place that text between cells, you have to have multiple sections and tell your tableView:cellForRowAtIndexPath: method to place cells that you want beneath that text in the next section.
In XCode 6.1 you can specify footer text for Table View Sections in the Story Board.
Select your TableViewControler in the Story Board, then select the TableViewSection that you want the footer on. Then in the Attributes Inspector, in the Footer field, enter your text.
You can also create your own UIView of any type (images, texts etc) and add them to the table cell, by using the [[mycell contenView] addSubView:WHATEVER_IS_MY_VIEW_TO_ADD];

Look like iPhone inbuilt contact applications image selection

I have created an application in which i have to add users to the sqlite database.
Now the problem is I want the look of the standard iPhone Contact application Where while adding user we have the width of first cell smaller than other cells and the image before that cell..
Can you please give me the idea how such thing is possible.
How to make one cell small and rest others of normal size..
Thanks for any help in advance
There are three UITableViewDelegate messages you can listen for to adjust height
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
However, even thought I didn't write Contacts.app I have a feeling they are also using
- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
To adjust the views as well. Remember, you don't have to pack everything into a single monolithic custom table view cell. You can create multiple custom table view cells and load them each appropriately depending on the index path.
The contact detail view is a grouped tableview. Each cluster of cells is a section. The top section is a single custom cell with two subviews that look like squashed tableview cells. The left view shows the contact's photo. The right view shows the name.
To reproduce, create a custom UITableView subclass and lay it out like you want either programmatically or in Interface Builder. Then in the tableview delegate's cellForRowAtIndexPath check indexPath.section and return the proper row for the section.
It appears that the Contacts app uses a custom tableHeaderView when presenting the contact details with an image and label. A similar implementation is included in the sample project iPhoneCoreDataRecipes. The RecipeDetailView loads a separate nib in tableViewHeaderView that is used to set the tableView.tableHeaderView property. Have a look at RecipeDetailViewController.{h,m} and DetailHeaderView.xib. When the Contacts app switches to editing mode, the headerView appears to be swapped out for another view that has a button and a tableView with a single cell. This will allow you to set up a separate tableViewDelegate to handle the Name parts of the contact and a delegate to handle the address / telephony details.