I have a UItableview for which i had the section header & footer programatically.
Initially i had problems with the sectio header overlapping on scroll which i solved using the scrollViewDidScroll delegate as
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
heightForHeader = 40.0;
if (scrollView.contentOffset.y<=heightForHeader&&scrollView.contentOffset.y>=0) {
scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
} else if (scrollView.contentOffset.y>=heightForHeader) {
scrollView.contentInset = UIEdgeInsetsMake(-heightForHeader, 0, 0, 0);
}
}
now the next issue is with the section footer that is overlapping while scrolling.
Can you help me with this?
Do you set your custom heights for header and footer?
Your table view delegate should implement this methods:
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
which should return appropriate values.
If you return smaller values then your header and footer views have, then they may overlap.
You are looking for this: I have tested it and it works
CGFloat sectionFooterHeight = 40;
CGFloat tableViewHeight = self.tableView.frame.size.height;
if (scrollView.contentOffset.y=tableViewHeight) {
scrollView.contentInset = UIEdgeInsetsMake(0, 0,-scrollView.contentOffset.y, 0);
} else if (scrollView.contentOffset.y>=sectionFooterHeight+self.tableView.frame.size.height) {
scrollView.contentInset = UIEdgeInsetsMake(0, 0,-sectionFooterHeight, 0);
}
I ran into the same kind of issue today for small screen iphone. May be it will be helpful for someone who deals with tableview with less number of cells in section with big header/Footer views.
First of all, the Headers and footers wont scroll along the cell unless you don't have any more cell to view while scrolling. So, if you got just two or three cells and a big Footer view then it will definitely over lap. One way to tackle this is adding the footer view as last cell of the section. This is just my work around.
Related
I'm building my settings screen and using a grouped table view.
When trying to set the headers I see spacing above my header view.
I double checked and I do pass the correct view height in -(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section.
Here is a screenshot of this behavior:
You can see my view with the title (VIBRATE, SILENT MODE) in it and it's darker bg color and the brighter space above it.
After much searching, I have finally found a fix for this. The tableview's delegate needs to implement heightForFooterInSection and return a very small number. Returning 0 defaults to the same spacing that was causing the extra spaces.
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return CGFLOAT_MIN;
}
Try this:
- (void)viewWillAppear:(BOOL)animated{
CGRect frame = self.tableView.tableHeaderView.frame;
frame.size.height = 1;
UIView *headerView = [[UIView alloc] initWithFrame:frame];
[self.tableView setTableHeaderView:headerView];
}
This is pretty much the same as Casey's response, however, it is a bit cleaner as it doesn't require implementing a delegate method. When you are setting up your table view, simply set the property sectionFooterHeight to 0. It accomplishes the same thing with less code (and no DBL_MIN oddness).
tableView.sectionFooterHeight = 0.0;
Pretty sure it is just a simple hack. But an easy way to do it is to write this function:
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 48.0f; // header height
}
to customize its height.
Pretty sure there are other ways to do it, that I don't know of.
It seems that Apple made a conscious design decision to make grouped table views have extra space on top. Try adjusting the contentInset of the UITableView. See my answer here
Swift 2.2 version:
func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return CGFloat.min
}
I have a UITableView which I am able to add a header view to fairly easily. Many apps (like Facebook, for viewing events) have a headerView that when you pull down, the header view stays put but the rest of the table (the UITableViewCell's) are bouncing. When scrolling up the header disappears. How can I achieve this functionality?
Right now when I pull down the UITableView, even the headerView bounces as well
You can achieve this effect quite easily by adding a subview to the header view and adjusting its frame or transform when the table view is scrolled beyond the top, i.e. the y component of its contentOffset becomes negative.
Example (in a UITableViewController subclass):
- (void)viewDidLoad
{
[super viewDidLoad];
CGFloat headerHeight = 64.0f;
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, headerHeight)];
UIView *headerContentView = [[UIView alloc] initWithFrame:headerView.bounds];
headerContentView.backgroundColor = [UIColor greenColor];
headerContentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[headerView addSubview:headerContentView];
self.tableView.tableHeaderView = headerView;
}
//Note: UITableView is a subclass of UIScrollView, so we
// can use UIScrollViewDelegate methods.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat offsetY = scrollView.contentOffset.y;
UIView *headerContentView = self.tableView.tableHeaderView.subviews[0];
headerContentView.transform = CGAffineTransformMakeTranslation(0, MIN(offsetY, 0));
}
(to keep it simple, I've just used the first subview of the actual header view in scrollViewDidScroll:, you may want to use a property for that instead.)
Your UITableView is most likely working properly. Section headers are sticky by default in Plain style tables. Meaning as you scroll down the header stays at the top of the UITableView's frame until the next section header pushes it out of the way. The opposite occurs when you scroll up. Conversely you get the sticky behavior on section footers at the bottom of the UITableView's frame.
EDIT Misunderstood the original question:
I would suggest using a section header rather than the table view header to get the sticky behavior you're looking for.
Include a section in your data with no rows and put your table header's view in that section header view.
you can use this line in view did load: (swift 5.6)
tableView.bounces = false
There is 2 ways you can set the table header:
Using the .tableHeaderView property directly (this header scrolls with the table)
Overriding the - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section function (this header stays static with the section)
By the sounds of it you should use the 2nd method instead of using the .tableHeaderView property
How do you implement headers in a UICollectionView? I know you can put in supplementary views, but I don't know how to make them "float" above a section like headers in a UITableView do.
Here's my situation: I have a collectionView with the cells laid out in a grid format. You can scroll horizontally and vertically. I want to have a header on top so that when you scroll horizontally it scrolls horizontally with it, but it doesn't scroll vertically. I also want the same sort of thing on the left side where it scrolls vertically with the collectionView but not horizontally. Is implementing this with supplementary views the right approach?
The final functionality I am looking for is similar to that of the Numbers spreadsheet app on iOS.
Thanks in advance for your help!
Update for iOS9:
let flow = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
flow.sectionHeadersPinToVisibleBounds = true
Pass it along.
EDIT: As mentioned in the comments, this answer is valid, but not for multiple sections. See this blog for a better solution: http://blog.radi.ws/post/32905838158/sticky-headers-for-uicollectionview-using#notes
You need to specify that behaviour in your layout:
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSMutableArray* attributesArray = [[super layoutAttributesForElementsInRect:rect] mutableCopy];
BOOL headerVisible = NO;
for (UICollectionViewLayoutAttributes *attributes in attributesArray) {
if ([attributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]) {
headerVisible = YES;
attributes.frame = CGRectMake(self.collectionView.contentOffset.x, 0, self.headerReferenceSize.width, self.headerReferenceSize.height);
attributes.alpha = HEADER_ALPHA;
attributes.zIndex = 2;
}
}
if (!headerVisible) {
UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader
atIndexPath:[NSIndexPath
indexPathForItem:0
inSection:0]];
[attributesArray addObject:attributes];
}
return attributesArray;
}
Is it possible to not float the section headers for a UITableView with style UITableViewStylePlain?
I'm building AcaniChat, an open-source version of iPhone's native Messages app, and I want to make the timestamps section headers, but they shouldn't float.
I know that section headers don't float for table views of style UITableViewStyleGrouped, but that style looks less like what I'm going for. Should I just use that style and restyle the table view to make it look how I want?
I might do that if I can figure out how to make https://stackoverflow.com/questions/6564712/nsfetchedresultscontroller-nsdate-section-headers.
The interesting thing about UITableViewStyleGrouped is that the tableView adds the style to the cells and not to the TableView.
The style is added as backgroundView to the cells as a class called UIGroupTableViewCellBackground which handles drawing different background according to the position of the cell in the section.
So a very simple solution will be to use UITableViewStyleGrouped, set the backgroundColor of the table to clearColor, and simply replace the backgroundView of the cell in cellForRow:
cell.backgroundView = [[[UIView alloc] initWithFrame:cell.bounds] autorelease];
I guess either you will have to use two kinds of custom tableCells or skip the tableview entirely and work on a plain scrollview to achieve this kind of style.
This can now be done in two quick and easy steps (iOS 6 only):
Change your UITableView style to UITableViewStyleGrouped. (You can do this from Storyboard/NIB, or via code.)
Next, set your tableview's background view to a empty view like so [in either a method such as viewDidAppear or even in the cellForRow method (though I would prefer the former)].
yourTableView.backgroundView = [[UIView alloc] initWithFrame:listTableView.bounds];
Voila, now you have your table view - but without the floating section headers. Your section headers now scroll along with the cells and your messy UI problems are solved!
This works because UITableViewStyleGrouped seems to now work by adding a background view to a plain UITableView, but without the floating section headers.
[N.B. Earlier to iOS 6, individual background images were added to UITableViewCell's.]
Do try this out and let me know how it goes.
Happy coding :)
EDIT: for iOS 7, simply change the table view style to 'UITableViewStyleGrouped' and change the view's tint color to 'clear color'.
You can achieve this by putting the headers into their own sections. First double your number of sections. Then for the even-numbered sections, return your header as the header and zero as the number of rows. For the odd-numbered sections, return nil for the header.
Assuming you're using an NSFetchedResultsController, it would look something like this:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return self.fetchedResultsController.sections.count * 2;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if ((section % 2) == 0)
{
section /= 2;
id<NSFetchedResultsSectionInfo> sectionInfo = self.fetchedResults.sections[section];
return sectionInfo.name;
}
else
{
return nil;
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if ((section % 2) == 0)
{
return 0;
}
else
{
section /= 2;
id<NSFetchedResultsSectionInfo> sectionInfo = self.fetchedResults.sections[section];
return sectionInfo.numberOfObjects;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ((indexPath.section % 2) == 0)
{
return nil;
}
else
{
indexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section/2];
id object = [self.fetchedResultsController objectAtIndexPath:indexPath];
// configure your cell here.
}
}
I am right now working with one application where i need to take one uitableview with uilable and textfield in each cell.I am able to scroll the table manually once the user starts writing, but what i want is that when i click on the textfield,the table should scroll upward so that the user is able to see what he has entered in the textfield.Same thing i saw once i logged in the iphone facebook.
this is the code for manually scrolling the table :
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
return 250;
}
-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
CGRect viewRect = CGRectMake(0, 0, 320, 160);
UIView *footerView = [[UIView alloc] initWithFrame:viewRect];
return footerView;
}
Is there any way around?
Thanks in advance.
This post describes what you want to achieve.
Also see this tutorial which nicely describes how to solve this problem.
Happy coding & happy new year
Actually, table view should scroll up when keyboard appears automatically (when text field is placed on table view, and when table is controlled by tableViewController).