Proper way to implement a footer in UITableView - iphone

So I read here that I can simply drag a UITableViewCell to the bottom of my UITableViewController in storyboard and have it act like a footer. This footer row has an activity indicator in it that's it. It's width is 320 and height 55 with the indicator centered in the row. Note that it's a UIView rather than a UITableViewCell because I can only get it to work with the former.
First, The UITableView doesn't stop at the footer. One can see the footer if he extends his scrolling beyond the bottom of the UITableView. As soon as the user releases his finger, the footer disappears from site as the UITableView returns its scrolling back to the last element. I am trying to do what Instagram is doing - if you scroll to the bottom you can see their custom activity indicator at the bottom and the UITable will remain its scrolling position at that indicator. How can I achieve this?
Second, I have some custom scrolling performed by certain user actions. Right now, I have the following code:
if (row + 1 < [self.tableView numberOfRowsInSection:0]) {
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForItem:row+1 inSection:0]
atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
} else {
// TODO scroll a little down so the user can see the activityIndicator
}
How can I tell my tableView to scroll programmatically to the footer and have it stop there?
Third During the very beginning, my UITableView has to fetch things from my server before it can populate the tableView. Unfortunately i can't get the footer view to maximize the space of the UITableView so that the activityIndicator will appear in the center. Right now this is how it looks:
I think I have the structs set correctly:
I suspect that having a UIView within a UITableView might prevent the view from maximizing.
Summary
Any recommendations on the above issues? I apologize for the length of this question, but I feel that they are all related to the same problem mentioned above.

I finally figured it out.
With regards to #zing and #Lithu answers, that worked. However, returning a footerView from this method forces the footerView to "stick" to the bottom of the TableView. By this I mean that the footerview will always be shown (which is not something I want)
I finally used self.tableView.footerView = MyView. I disabled ALL the spring and struct settings on my UIView and it fits perfectly. (I've previously set it to maximize hoping to have it maximize when there is nothing in the table)
Regarding centering the activity indicator: I ended up setting the footer view to hidden if there's nothing in the UITableView (by checking in numberOfRows). I programmatically added the ActivityIndicator in the center if this occurs.
Thanks for all the answers!!

Did you try to do it in the proper delegate for UITableview Footer
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section

Use This code to add any view in the footer.
e.g.
- (UIView*)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
UIView *footerView = [[UIView alloc] initWithFrame:CGRectMake(0, 50, self.tblView.frame.size.width, 49)];
return footerView;
}

Related

UITableView scrolling to last cell only displays half of the cell

I want to scroll to the bottom of my tableview that contains custom cells.
Here is the code I am using to scroll:
NSIndexPath *lastMessage = [NSIndexPath indexPathForRow:[self.conversation.messages count]-1 inSection:0];
[self.messageTable scrollToRowAtIndexPath:lastMessage atScrollPosition:UITableViewScrollPositionTop animated:YES];
This scrolls the view; however only the very top of the last cell is visible with ~3/4 of the cell still below the fold that I have to manually scroll down to. Any ideas on how to fix this?
Turned out to be a timing issue. The tableview hadn't fully rendered yet when I called that method from viewdidload (contentsize of 0). Calling this method in viewDidAppear works brilliantly though.
It seems like the UITableView is confused about how big your cells are. Set the rowHeight property on the UITableView to the height of your custom cell.

setting an ImageView as a background for sections in a grouped uitableview

is there any possible way to set a UIImageView as a background for a section (let's say section #3) in a grouped UITableView?
I'm not asking about viewForHeaderInSection 'coz I tried it but didn't work as expected.
thanks so much in advance ...
My guess is that if you were to think very creatively, you could come up with a way to essentially swap the UITableView's backgroundView property as different sections are visible. This doesn't strike me as particularly elegant given that multiple sections might occupy the visible screen at one time, but perhaps I don't understand the question clearly.
The short answer is that there is not a defined/simple way to achieve this. The composition of a section is far removed from the background of a UITableView, and essentially the architecture isn't setup for what you want. I wouldn't assume to know the details of your implementation, but I would also urge caution: The visual and architectural characteristics of UITableView's are pretty well-considered. My personal opinion (again, I haven't seen what you're working on), is that different section backgrounds might overwhelm the user experience in many cases. I can also see cases where it may be a nice UI touch if executed properly.
In this case, if you still want to do it, here is the approach I'd take:
Essentially you're going to watch the position of your tableview's cells. You could do this in scrollViewDidScroll, or tableViewWillDisplay cell - or other places, I'm sure. But you need to know which cells are scroll on and off the screen, and you then need to be able to ask the upper-most-visible cell what it's section is. Once you've established which section it is you should currently be displaying, you can use that to scroll your own set of views representing each section's background.
Essentially, you're going to create each of your dynamic section background views in code, just UIView's, each with it's backgroundProperty set to a repeating pattern (obviously, heights will be dynamic). Add all your section background subviews (or preferably do it lazily) to your UITableView's backgroundView.
Now, as your scroll view scrolls, you're going to observe which rows and sections are coming in and out of the table's view. As rows in sections are scrolled, calculate the height of the section background (multiply the quantity of rows in the section by their heights) and adjust it's Y axis, which is sitting in but clipped by your tableView's backgroundView. As sections scroll on, you'll update the Y offset of the relevant section's background view. Phew!
Another idea might be to toss all your section background views, laid out vertically, in a UIScrollView, user interaction disabled. Place that scroll view in your table view's backgroundView, and then figure out the math to essentially "forward" scroll events from the tableview's scrolling view to your background scrolling view.
This will probably take a bit of work to find an implementation that keeps your animations all smooth and in sync, but, it's an approach that I think could be made to work.
Use myTable.tableHeaderView = customHeaderView if your table has only one section.
viewForHeaderInSection might not have worked if you didn't return an object of type UIView or a subclass in your method. Add some code from your viewForHeaderInSection method to your question for a more precise answer.
EDIT- If by viewForHeaderInSection didn't work as expected, you mean that the header was clipped, then it might be because you have not have implemented the following method:
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
If not implemented, each section's height is set to an iOS default value.
create a custom headerView that looks something like this.
.h
#interface CustomViewForHeader: UIView
#end
.m
#import "CustomViewForHeader.h"
#implementation CustomViewForHeader
-(id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self != nil) {
UIImageView *bgImage = [[UIImageView alloc]initWithFrame:self.frame];
bgImage.image = [UIImage imageNamed:#"bill_headerBg.png"];
[self addSubview:bgImage];
}
return self;
}
#end
use it like:
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 50.0;
}
-(UIView*)tableView:(UITableView*)tableView viewForHeaderInSection:(NSInteger)section {
CustomViewForHeader *customView = [[CustomView alloc]initWithFrame:CGRectMake(0,0,320,50)]
return customView;
}
I recall something about methods to find the rectangles of each section. Having those, you could appropriate sized images to the scroll view underlying the table view.
Aside from that, you could put the background image into the background of the cells themselves. When the tableview calls for a cell in a given section, you can pick the appropriate image or image tile.

How to draw a button over a last visible uitableview cell?

I need to display search button at the edge of last visible cell in uiTableView. Something like this:
I don't know how to get the right CGRect to draw this button (view) and how to redraw this, when the user scrolls the tableview.
Tnx.
The UITableView method
- (CGRect)rectForRowAtIndexPath:(NSIndexPath *)indexPath
should help you.
You may need to offset this by the tableview.frame.origin if you are drawing it in the parent view.
Hope this helps!
Another way would be to have the button attached to the View (rather than cell), On tapping the button you could find the NSIndexPath for last cell by iterating through visibleCells.

How to make tableView Scroll Automatically to top/bottom?

This is just a test, which i might add it to the app. Well.... I have a tableView.
If click button1, I want the tableView to scroll up automatically to the top.
If I click button2 I want the tableView to scroll down automatically to the bottom.
How can this be done ? What about Scroll Speed ?
You can also look at the scroll view's setContentOffset:animated: method.
Going to the top would mean,
[self.tableView setContentOffset:CGPointZero animated:YES];
and the bottom would be,
CGFloat height = self.tableView.contentSize.height - self.tableView.bounds.size.height;
[self.tableView setContentOffset:CGPointMake(0, height) animated:YES];
You won't have control over the animation duration.
The only problem with scrollToRowAtIndexPath:atScrollPosition:animated: is that it might not be helpful when section and table headers are set.
scrollToRowAtIndexPath:atScrollPosition:animated:
Scrolls the receiver until a row identified by index path is at a particular location on the screen.
- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated

Displaying dynamic subview in tableviewcell

After the user taps a tableview cell, I'd like to slide open a small view just below the cell . The first screenshot of these two apps show this:
Tweetie 2: http://itunes.apple.com/us/app/tweetie-2/id333903271?mt=8
Pastebot: http://itunes.apple.com/us/app/id344614116?mt=8
I know how to dynamically increase the height of a cell but that is a different effect than the above. The slide out view affect doesn't seem to increase the cell's height. Also, the new view isn't as wide. Any suggestions on how to go about designing that?
You could create and insert, with animation, a new custom cell under it. Check out insertRowsAtIndexPaths:withRowAnimation:.
UPDATE
I also really like your idea of using a "slideout" view, but I agree with TechZen that this should be added as a subview of the cell.
If you want to increase the height of the cell, you need to return the correct heights for all the cells from the delegate method tableView:heightForRowAtIndexPath:. You will need to return the same height (standard is 44) for all rows except the one with the extra view which will be increased by the height of the new view.
I don't think they're sliding a view beneath the cell view, I think they're inserting the view into the cell itself and modifying the graphics to create the illusion of an overlying view.
I don't really know how they did that, but in the last minutes I tried some experiments and... the easiest solution is definitely:
NSIndexPath *myIndexPath = [NSIndexPath indexPathForRow:[selectedCell intValue]+1 inSection:0];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:myIndexPath] withRowAnimation:UITableViewRowAnimationTop];
Insert some custom graphics (cellForRowAtIndexPath) and it looks quite the same.
Those two apps are doing things that are quite different. Tweetie is overlaying a new cell on top of an existing one, while PasteBot is creating a new one underneath, and animating the expansion of the table view. Mooch! does the same thing as PasteBot, and it's a really cool effect that I'd like to duplicate.