UITableView Cell at Index 0 Size - iphone

What is the best way to customize the first cell in a table to display like the Netflix application (i.e. bigger/different)? For ease of future use, I have been asked to use IB as much as possible to make it easier for future editing.
Here is a photo of the Netflix table. http://cl.ly/3j1d473d1j160502160t

Use the table header view. Drag a view to the top of the table view and it will become the "table header view".
If you have other such "cells" which are essentially constant (and might be switched on/off) you can consider putting UITableViewCell objects in your xib, and returning them from the tableView:cellForRowAtIndexPath: delegate method. Also implement the tableView:heightForRowAtIndexPath: method.
Both can have the same general outline, like:
-(UITableViewCell*)tableView:(UITableView*)tv cellForRowAtIndexPath:(NSIndexPath*)ip
{
if ( ip.section==0 ) return headerCell;
// ...handle regular cells
}
-(CGFloat)tableView:(UITableView*)tv heightForRowAtIndexPath:(NSIndexPath*)ip
{
if ( ip.section==0 ) return headerCell.frame.size.height;
// ...handle regular cells
return 44;
}

Either make it something that isn't a cell (like the table's header view), or implement -[UITableViewDelegate tableView:heightForRowAtIndexPath:] to return a different height. You can use IB to install a table header, but more complex ways of attacking this problem will require working in code.

Here is a snippet that you can use.It is table's header view...
-(UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
if(section==0){ UIView *view=[[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableview.frame.size.width, 44)];
[view setBackgroundColor:[UIColor redColor]]; UILabel
*label=[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 44)];
[label setText:#"Hello!!"];
[label setBackgroundColor:[UIColor clearColor]];
[view addSubview:label]; return view;
}return nil;
}
Here You can set the height for the tableViewHeaderSection.
(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
return 100;
}

Related

Add tableview in scrollview with table scrolling disabled in Iphone

I have scroll view with label and a table view and a button . I just want to scroll the scrollview and the table view must display all the contents but tableview must not scroll. Below the tableview i have a button. How to set the frame of the button so it comes exactly below the table?
Thanks
Maybe you would like to set the YourTableView.userInteractionEnabled = NO?
Yes we can disable the scrolling the tableview.
Goto->xib->select table->Goto 1st tab->unselect the scrolling Enabled.
The answer for your Second Question.
Put the UiView in footer of your table and then place the button in that UIView you want to show in bottom.
It will always show at the bottom.
If you want to place button programmatically use following code in viewDidload method.
///--------Table Footer is Set here
UIView *footer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 260, 44)];
UIButton *adddays = [[UIButton alloc] initWithFrame:CGRectMake(10, 0, 260, 44)];
[adddays setBackgroundImage:[UIImage imageNamed:#"abcd.png"] forState:UIControlStateNormal];
[adddays addTarget:self action:#selector(buttonaction) forControlEvents:UIControlEventTouchDown];
UILabel *text = [[UILabel alloc] initWithFrame:CGRectMake(75, 12, 250, 20)];
[text setBackgroundColor:CLEAR_COLOR];
[text setText:#"Title for your button"];
[text setTextColor:XDARK_BLUE];
text.font=[UIFont fontWithName:#"Arial-BoldMT" size:18.0f];
[footer addSubview:adddays];
[footer addSubview:text];
[table setTableFooterView:footer];
This is assuming you have created IBOutlets for your scrollView, tableView and button, and hooked them up appropriately.
I find it useful to remember that we're only messing with the y-values of a CGRect (origin.y & size.height) - The x-values should be set up in the xib.
I've commented this profusely to illustrate my point better, usually I would only comment where appropriate
-(void)viewDidLoad {
[self.tableView setScrollEnabled:NO];
// Get the number of rows in your table, I use the method
// 'tableView:numberOfRowsInSection:' because I only have one section.
int numOfRows = [self.tableView numberOfRowsInSection:0];
// Get the height of your rows. You can use the magic
// number 46 (44 without including the separator
// between rows) for the height of your rows, but because
// I was using a custom cell, I had to declare an instance
// of that cell and exctract the height from
// cell.frame.size.height (adding +2 to compensate for
// the separator). But for the purpose of this demonstration
// I'm going to stick with a magic number
int rowHeight = 46; //Eww, Magic numbers! :/
// Get a reference to the tableViews frame, and set the height
// of this frame to be the sum of all your rows
CGRect frame = self.tableView.frame;
frame.size.height = numOfRows * rowHeight;
// Now we have a frame with the exact size of our table,
// so set the 'tableView.frame' AND the 'tableView.contentSize'
// to that. (Because we want ALL rows visible as you
// disabled scrolling for the 'tableView')
self.tableView.frame = frame;
self.tableView.contentSize = frame.size;
// Now we want to set up the button beneath the table.
// We still have the 'frame' variable, which gives us
// the tableView's Y-origin and height. We just add these
// two together (with +20 for padding) to get the origin of the button
CGRect buttonFrame = self.button.frame;
buttonFrame.origin.y = frame.origin.y + frame.size.height + 20;
self.button.frame = buttonFrame;
// Finally, we want the `scrollView`'s `contentSize` to
// encompass this entire setup (+20 for padding again)
CGRect scrollFrame = self.scrollView.frame;
scrollFrame.size.height = buttonFrame.origin.y + buttonFrame.size.height = 20;
self.scrollView.contentSize = scrollFrame.size;
}
You could stop the scrolling the table view. But you shouldn't be adding a tableview inside a scrollview. UITableView is subclass of UIScrollView and adding one scrollView on another will create problem. I suggest you to remove the scrollview and use the tableview alone ( as the tableview itself is a scrollview).

Can i change the height of a uitableview's tableHeaderView?

I'm trying to change the tableView.tableHeaderView frame so i can make it bigger but with no effect. Is tableView.tableHeaderView's frame fixed or is it adjustable?
tableView.tableHeaderView = nil;
tableView.tableHeaderView = your_headerView;
See also: Resizing a UITableView's tableHeaderView
It is flexible, If you have tried following code and its still not working,
then Try changing Header View size in Interface builder.
Create a UIView with the things you want for your Header and add view
UIView *tempView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, heightYouWant)];
tempView.backgroundColor = [UIColor whiteColor];
[yourTableView setTableHeaderView:tempView];
//[yourTableView setTableFooterView:tempView]; you can also use Footer in same way
[emptyView release];
you can add other controls in the tempView to create it run time.
Write this into your UITableViewDelegate
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
{
return 100;
}

UITextView in TableCell, How to set correct Width for Universal app

i am using a UITextView inside a tableView cell in order edit text.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITextField *textName = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 270, 24)];
[cell addSubview:textName];
[textName release];
}
This works, but when running it on the iPad it isn't correct.
I've tried to determine the width of cell using
cell.contentView.frame.size.width
but this always returns 320.0 for both iPhone and iPad
Also on the iPad when in landscape mode shouldn't the width of cell be bigger?
Teo
Ideally you'd create a custom UITableViewCell and adjust your control sizes/positions in layoutSubviews.
If you're going to add the control in tableView:cellForRowAtIndexPath:, then you can get the width from the tableView itself:
UITextField *textName = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width-50, 24)];
The iPad cell is resized when it's added to the table, after your function returns. If you want the text field to resize with the cell, you can do something like textName.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight.
You should add custom views to contentView (i.e. [cell.contentView addSubview:textName]). The content view automatically shrinks to handle editing mode, among other things.
Subclassing UITableViewCell is a bit overkill if you just want to tweak layout — it's my impression that auto-resizing is faster than manual sizing using layoutSubviews.

UITableView headers on the left side of sections (like Spotlight)

Been searching for this for quite a while, and I still haven't found a way to do it.
I'd like to reproduce the section headers of the iPhone's Spotlight into a UITableView.
"Regular" table view headers stay visible at the top of a section when you scroll, as we all know. But there is one kind of header that I've never seen elsewhere than in the Spotlight page of Springboard: there, the headers span the whole height of the section and are not stuck on the top of the section, but on the left side.
How the heck is that achieved?
Good question. I made a little experiment. It almost looks like the view from spotlight. But it's lacking one import feature. The lower "image" doesn't push the upper image to the top if they collide.
I doubt that there is a built in solution without the use of private frameworks.
I achieved this:
As you can see the two header images at the top overlap. They don't push each other like normal headers to. And I had to deactivate the cell separators. If I would use them they would appear at the whole cell. So you have to draw them yourself. Not a big deal.
But I have no idea how I could fix the overlapping.
Here is the code that made this happen:
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 1;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *contentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.bounds.size.width, 44)];
contentView.backgroundColor = [UIColor lightGrayColor];
UIImageView *imageView = [[[UIImageView alloc] initWithFrame:CGRectMake(5, 5, 34, 34)] autorelease];
imageView.image = [UIImage imageNamed:[NSString stringWithFormat:#"%d", section]];;
[contentView addSubview:imageView];
return [contentView autorelease];
}
Okay I have done something similar to what the music app and spotlight search does.
I have not subclassed UITableView, I have just tracked the sections through it's scrollViewDidScroll method, and added the header views to the left of the tableView (so you will have to put the tableview to the right in your viewController's view, which means you can't use UITableViewController).
this method should be called in the scrollViewDidScroll, ViewDidLoad, and in didRotateFromInterfaceOrientation: (if you support rotation)
keep in mind that you will have to make space in the left equal to the size of the headers in any interface orientation that you support.
-(void)updateHeadersLocation
{
for (int sectionNumber = 0; sectionNumber != [self numberOfSectionsInTableView:self.tableView]; sectionNumber++)
{
// get the rect of the section from the tableview, and convert it to it's superview's coordinates
CGRect rect = [self.tableView convertRect:[self.tableView rectForSection:sectionNumber] toView:[self.tableView superview]];
// get the intersection between the section's rect and the view's rect, this will help in knowing what portion of the section is showing
CGRect intersection = CGRectIntersection(rect, self.tableView.frame);
CGRect viewFrame = CGRectZero; // we will start off with zero
viewFrame.size = [self headerSize]; // let's set the size
viewFrame.origin.x = [self headerXOrigin];
/*
three cases:
1. the section's origin is still showing -> header view will follow the origin
2. the section's origin isn't showing but some part of the section still shows -> header view will stick to the top
3. the part of the section that's showing is not sufficient for the view's height -> will move the header view up
*/
if (rect.origin.y >= self.tableView.frame.origin.y)
{
// case 1
viewFrame.origin.y = rect.origin.y;
}
else
{
if (intersection.size.height >= viewFrame.size.height)
{
// case 2
viewFrame.origin.y = self.tableView.frame.origin.y;
}
else
{
// case 3
viewFrame.origin.y = self.tableView.frame.origin.y + intersection.size.height - viewFrame.size.height;
}
}
UIView* view = [self.headerViewsDictionary objectForKey:[NSString stringWithFormat:#"%i", sectionNumber]];
// check if the header view is needed
if (intersection.size.height == 0)
{
// not needed, remove it
if (view)
{
[view removeFromSuperview];
[self.headerViewsDictionary removeObjectForKey:[NSString stringWithFormat:#"%i", sectionNumber]];
view = nil;
}
}
else if(!view)
{
// needed, but not available, create it and add it as a subview
view = [self headerViewForSection:sectionNumber];
if (!self.headerViewsDictionary && view)
self.headerViewsDictionary = [NSMutableDictionary dictionary];
if (view)
{
[self.headerViewsDictionary setValue:view forKey:[NSString stringWithFormat:#"%i", sectionNumber]];
[self.view addSubview:view];
}
}
[view setFrame:viewFrame];
}
}
also we need to declare a property that would keep the views that are visible:
#property (nonatomic, strong) NSMutableDictionary* headerViewsDictionary;
these methods return the size and X axis offset of the header views:
-(CGSize)headerSize
{
return CGSizeMake(44.0f, 44.0f);
}
-(CGFloat)headerXOrigin
{
return 10.0f;
}
I have Built the code so that any header view that's not needed gets removed, so we need a method that would return the view whenever needed:
-(UIView*)headerViewForSection:(NSInteger)index
{
UIImageView* view = [[UIImageView alloc] init];
if (index % 2)
{
[view setImage:[UIImage imageNamed:#"call"]];
}
else
{
[view setImage:[UIImage imageNamed:#"mail"]];
}
return view;
}
here's how it will look :
How it will look in lanscape, I have used contraints to give 44px in the left of the tableView
hope this helps :).
Good news: See answer of How to achieve an advanced table view header
result http://i.minus.com/jyea3I5qbUdoQ.png

How can a create a automatically resizing table cell for entering texts like in the iPhone's "mail" app?

I'm try to emulated something just like the "new message" page in Apple's mail app on the iphone. I've implemented it with a tableview and I've successfully gotten the "To", "CC", and "Subject" rows to behave correctly, but I'm not sure how to implement the actual message portion of the page.
There are several issues that I'm having. I'm currently trying to implement it by placing a UITextView in the cell (I turn off the scroll bars on the text view). I have the text view resize itself when it is changed, by modifying its frame to the new height of the content. The first problem is that I also need to do this for the cell height itself. Since heightForRowAtIndexPath seems to only get called when the row is first loaded, I can't modify the height there. I suppose I could call reload data on the table but this seems like it would be really inefficient to do on the whole table every time text is entered. What is the best way to get the table cell to autoresize as the user types? I've found lots of examples on how to do it on lone table views and how to resize table cells at initialization but I can't find any that let you do both at the same time.
Finally, I would like the bottom border of the table cell to be invisible. If you look at the mail app, you'll notice there is no line at the bottom of the message space, implying that you can just keep typing. I always have one in my table view (even when I add a footer) and I can't figure out how to get rid of it. (Perhaps should I make my message body be the footer itself?)
I would recommend using a UIScrollView yourself instead of a UITableView. UITableView isn't really built to support such a thing.
Mail.app doesn't seem to use UITableView.
It looks like there custom items (labels and text fields) with UITextView on bottom.
You could try my answer to a question similar to this...the key is to use
[self.tableView beginUpdates];
[self.tableView endUpdates];
To do this without reloading the data.
First off, of course, you're going to want to create your UITextView and add it to your cell's contentView. I created an instance variable of UITextView called "cellTextView" Here is the code that I used:
- (UITableViewCell *)tableView:(UITableView *)tableView fileNameCellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
if (!cellTextView) {
cellTextView = [[UITextView alloc] initWithFrame:CGRectMake(5.0, 5.0, cell.bounds.size.width - 30.0, cell.bounds.size.height - 10.0)]; // I use these x and y values plus the height value for padding purposes.
}
[cellTextView setBackgroundColor:[UIColor clearColor]];
[cellTextView setScrollEnabled:FALSE];
[cellTextView setFont:[UIFont boldSystemFontOfSize:13.0]];
[cellTextView setDelegate:self];
[cellTextView setTextColor:[UIColor blackColor]];
[cellTextView setContentInset:UIEdgeInsetsZero];
[cell.contentView addSubview:cellTextView];
return cell;
}
Then, create an int variable called numberOfLines and set the variable to 1 in your init method. Afterwards, in your textViewDelegate's textViewDidChange method, use this code:
- (void)textViewDidChange:(UITextView *)textView
{
numberOfLines = (textView.contentSize.height / textView.font.lineHeight) - 1;
float height = 44.0;
height += (textView.font.lineHeight * (numberOfLines - 1));
CGRect textViewFrame = [textView frame];
textViewFrame.size.height = height - 10.0; //The 10 value is to retrieve the same height padding I inputed earlier when I initialized the UITextView
[textView setFrame:textViewFrame];
[self.tableView beginUpdates];
[self.tableView endUpdates];
[cellTextView setContentInset:UIEdgeInsetsZero];
}
Finally, paste this code into your heightForRowAtIndexPath method:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
float height = 44.0;
if (cellTextView) {
height += (cellTextView.font.lineHeight * (numberOfLines - 1));
}
return height;
}