How to remove extra whitespace above a UITableView? - ios

I'm have been trying to get the header of the table scrolling along with the UITableView. It's finally working, however, now there's a whitespace showing up right under the map view (see screenshot). I had difficulty getting the map in the table header section to scroll with the table and also to get the UIButton to trigger within the table header with a user touch (the UIButton simply expands the map to full screen.).
I asked a question related to this yesterday regarding the scrolling and button touch. Those are working now - I'm sure the coding could be done better, but this is what I have at the moment and have to get this done asap. If I can resolve this whitespace issue I can refactor and optimize the code later.
thanks for any help with this.
notice the whitespace under the map and above the table view in the screenshot - I want to bring the table view so it's close to the map.
in my viewDidLoad: method
// mapview
self.topMapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 320, 140)];
self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0,0,self.view.frame.size.height,self.view.frame.size.height)];
self.tableView.dataSource = self;
self.tableView.delegate = self;
self.tableView.backgroundColor = [UIColor whiteColor];
[self.view addSubview:self.tableView];
then in the viewForHeaderInSection: method (It was suggested that this be done in the viewDidLoad: method and I tried that but it gave me more problems
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0,0, 320, 140)];
UIButton *showMapButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
showMapButton.frame = CGRectMake(0.0, 0, 320.0, 140.0);
[showMapButton setTitle:#"show map" forState:UIControlStateNormal];
[showMapButton addTarget:self
action:#selector(mapDetailViewDisplay:)
forControlEvents:UIControlEventTouchDown];
[headerView addSubview:self.topMapView];
[headerView showMapButton];
self.tableView.tableHeaderView = headerView;
return headerView;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 140;
}

Just add this in you ViewDidLoad method
self.automaticallyAdjustsScrollViewInsets = NO;

[UITableView tableHeaderView] is something different than viewForHeaderInSection but you are setting the same object to both of them.
You should rather set self.tableView.tableHeaderView in viewDidLoad: or return a headerView through viewForHeaderInSection delegate method depending on what kind of behaviour you are trying to achieve.

try to move all code in - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section leaving only return headerView
in viewDidLoad
and change
UIView *headerView = [[UIView alloc] init];
instead of
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0,0, 320, 140)];

Related

How to show a footer view with custom text at the end of the UItableview

I have a UITableView to display search results. The user loads more results by scrolling to the end. When server has no more results, I want to show a text at the end of the tableview, that says "No more search results". I tried following code, but it is not working. Any suggestions on what is happening will be greatly appreciated.
UILabel *endLabel = [[UILabel alloc] init];
endLabel.text = #"No more results to display";
[endLabel sizeToFit];
self.tableView.tableFooterView = endLabel;
[self.tableView reloadData];
Following code may help you to solve out problem.
You can write this code to your viewDidLoad.
UIView *footer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 100)];
[footer addSubview:yourlabel];
[footer bringSubviewToFront:yourlabel];
yourlabel.text = #"whatever you want to write";
yourlabel.frame = CGRectMake(self.view.frame.size.width/2 - yourlabel.frame.size.width/2 , 30, yourlabel.frame.size.width, yourlabel.frame.size.height);
tbl_view.tableFooterView = footer;
However you need to increase the size of footer view of table.
I. Create a separate view in the xib of your viewController. By separate view I mean do not drag the view in the viewController's view as a subview, instead just drag it into the whitespace in your Interface Builder.
II. Now design the view i.e put a label in it that says no more data.
III. Now create an outlet of that view in your viewController.
#property(nonatomic, strong) IBOutlet UIView * tableFooterView;
IV. When there is no more data just write
self.tableView.tableFooterView = self.tableFooterView;
V. Set the width & height of the footer in viewDidLoad
self.tableFooterView.frame = CGRectMake(0, 0, self.tableView.bounds.size.width, 40);
VI. And when you do have data and don't want to show the no more data thing then
self.tableView.tableFooterView = nil;
//custom header for footer
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
UILabel *endLabel = [[UILabel alloc] init];
endLabel.text = #"No more results to display";
UIView *footerView = [[UIView alloc] initWithFrame:CGRectMake(0, 50, self.tblView.frame.size.width, 40)];
[footerView addSubview:endLabel];
return footerView;
}
//Method To Get Height For Header and Footer
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 40.0;// your view height
}

customize UITableView Header Section at run time

I have set header back ground using the code below but I want to change the color of header back again on run time when I click on the button that is added as a subview on the header.
please provide me code, thanks in advance :)
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
header = [[UIView alloc]initWithFrame:CGRectMake(0, 0, _tableView.bounds.size.width, 50)];
header.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"homeCellHeaderBackGround.png"]];
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(10, 10, 100, 30)];
label.text = _array[section][#"name"];
label.textColor = [UIColor whiteColor];
[header addSubview:label];
UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(230, 10, 70, 35)];
[button addTarget:self action:#selector(onExpandButton:) forControlEvents:UIControlEventTouchUpInside];
//[button setTitle:#"Expand" forState:UIControlStateNormal];
[button setTag:section];
[header addSubview:button];
return header;
}
You can modify it in run time by:
first:
you can declare a global variable/propery like:
#property (nonatomic) UIView *tableHeader;
and set it under -(void)viewDidLoad
like
self.tableView.tableHeaderView = self.tableHeader;
or using the delagate:
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
return self.tableHeader;
}
and modify it anywhere you like, but dont forget to reload you table section header, probably [tableView reloadSections:NSIndexSet withRowAnimation:UITableViewRowAnimation]; will do.
But
In your case you can retreive/get the tableHeader made inside the delegate:
-(UIView *)tableView:tableView viewForHeaderInSection:section
by
UIView *tableHeaderView = [self tableView:yourTableView viewForHeaderInSection:yourSection];
then modify tableHeaderView..
or simply reassign tableHeader by:
yourTableView.tableHeaderView = tableHeaderView;
your by using header alone, since as i can see it's a global variable..
change/update it directly like:
header.backgroundColor = [UIColor yourNewColor];
hope i've helped you.. happy coding, cheers..
You can change the background color of the section header by following code:
- (IBAction)onExpandButton:(id)sender {
UIView *header = ((UIButton *)sender).superView;
header.backgroundColor = <Whatever UIColor you like>;
...
}
-(IBAction)onExpandButton:(UIButton *)sender
{
UIView *tmpView = [self.YourTableViewName headerViewForSection:sender.tag];
tmpView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"homeCellHeaderBackGround.png"]];
}
-You got the view from your table view header for section method. After you can set your image view on view.

UITableView modify only one header section after delegate methods

I'm creating a UITableView with more section "closed". When I tap on a section, with a workaround, I make the section explode showing the rows for that section. The problem that I have is that I have to animate the header to collapse it to an half of its width.
This is the code I'm using
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
Sport *sport = [self.sportList objectAtIndex:section];
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, tableView.frame.size.width, SECTION_HEIGHT)];
headerView.backgroundColor = [UIColor colorWithRed:31.0/255.0 green:59.0/255.0 blue:143.0/255.0 alpha:1.0];
UILabel *sportTitle = [[UILabel alloc] initWithFrame:CGRectMake(10.0, 2.0, tableView.frame.size.width, SECTION_HEIGHT-4)];
sportTitle.textColor = [UIColor whiteColor];
[headerView addSubview:sportTitle];
UIButton *sportButton = [[UIButton alloc] initWithFrame:headerView.frame];
[sportButton addTarget:self action:#selector(didSelectedButton:) forControlEvents:UIControlEventTouchUpInside];
[sportButton setTitle:#"" forState:UIControlStateNormal];
[sportButton setBackgroundColor:[UIColor clearColor]];
sportButton.tag = section;
[headerView addSubview:sportButton];
return headerView;
}
This is the selector:
-(void)didSelectedButton:(UIButton *)_button
{
if (self.delegate && [self.delegate respondsToSelector:#selector(didSelectedSport:)])
{
[self.delegate didSelectedSport:sport];
}
}
The delegate updates only the dataSource and calls the reloadData, making possible the explosion/collapse of the sections. But now I want to animate the changes to the width of the header for that section, is it possible? Thanks
EDIT: I can modify the header using the property superview of the UIButton in the selector, but I have to do it after the controller drew it
Try using the function below. Set your superview of uibutton as the from view in the method.
Create another view with your needed width and set it as to view in the method. Give a animation of choice in options.
[UIView transitionFromView:from
toView:to
duration:.5
options:UIViewAnimationOptionTransitionFlipFromBottom
completion:^(BOOL finished) {
}];

Can't Interact With Controls In Table View Header

I've decided to use a table header view in my app to hold a search bar and a UISegmentedControl. Here is the viewDidLoad of the view controller:
- (void)viewDidLoad
{
[super viewDidLoad];
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 65, 320, 44)];
[self.searchBar sizeToFit];
[self.searchBar setUserInteractionEnabled:YES];
[self setSearchController:[[UISearchDisplayController alloc] initWithSearchBar:self.searchBar contentsController:self]];
self.mainSegment = [[UISegmentedControl alloc] initWithItems:#[#"YouTube", #"iTunes"]];
[self.mainSegment setFrame:CGRectMake(8, 109, 305, 29)];
[self.mainSegment setSelectedIndex:0];
[self.mainSegment addTarget:self action:#selector(searchTypeChanged:) forControlEvents:UIControlEventValueChanged];
[self.mainSegment setUserInteractionEnabled:YES];
UIView* headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 65)];
[headerView setBackgroundColor:[UIColor clearColor]];
[headerView addSubview:self.searchBar];
[headerView addSubview:self.mainSegment];
[headerView bringSubviewToFront:self.searchBar];
[headerView bringSubviewToFront:self.mainSegment];
[headerView setUserInteractionEnabled:YES];
self.tableView.tableHeaderView = headerView;
self.tableView.userInteractionEnabled = YES;
}
This produces a good result:
However, I can't interact with the search bar or the segmented control. I tried setting userInteractionEnabled to YES as shown above, but the problem still remains. Any ideas?
The height of your header view is 65 points. You're inserting your searchbar at Y=65 so it's beyond the bounds of the header rect. Move your searchbar to Y=0 and your segmented control below it, and it's going to work just fine.
Have a nice day :)
USe delegate methods to set up the headerview.Create and return your headerview in this method.
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
Dont forget to set up the table header height.
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
and the <UITableviewDatasource> in header file to indicate the class is actually having your datasource methods to that table
A must read doc

UIButton is not working in the header of my UITableView

I can't figure out why this UIButton is not working in the header of my UITableView. It's appearing there but the touch is not working.
The NSLog statement isn't triggering either. It's almost like it's beneath another view or something so that you can see it but the press action doesn't work.
thanks for any help with this
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *sectionHeader = [[UILabel alloc] initWithFrame:CGRectNull];
sectionHeader.backgroundColor = [UIColor clearColor];
[sectionHeader addSubview:self.topMapView];
// add map launch button
mapLaunchButton = [UIButton buttonWithType:UIButtonTypeCustom];
[mapLaunchButton addTarget:self
action:#selector(mapButtonTouch:)
forControlEvents:UIControlEventTouchDown];
[mapLaunchButton setTitle:#"ggggggg" forState:UIControlStateNormal];
mapLaunchButton.frame = CGRectMake(0, 0, 300, 90);
mapLaunchButton.backgroundColor = [UIColor redColor];
[sectionHeader addSubview:mapLaunchButton];
// [sectionHeader bringSubviewToFront:mapLaunchButton];
self.tableView.tableHeaderView = sectionHeader;
return sectionHeader;
}
- (void)mapButtonTouch:(id)sender {
NSLog(#"map button was touched");
}
I can see more than one mistake -
If your table has only one section (to verify this check for numberOfSectionsInTableView delegate) then remove this line -
self.tableView.tableHeaderView = sectionHeader;
Set sectionHeader.frame to something appropriate (not CGRectNull). The benefit of setting section header (versus table header view) is that when user will scroll the table rows then the section header will stick on top (float) and will not go away. (Plain style table)
Still the problem is not resolved, then please verify his method -
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 50; // depending upon the height of the sectionHeader
}
As pointed out by other poster, to capture touch event on UIButton UIControlEventTouchUpInside is preferred event.
EDIT - (as table header view implementation)
If you want to scroll it up then make it as table header (not section header). So remove all this from viewForHeaderInSection and put it inside viewDidLoad of your view controller class. Keep this line (don't remove it in this case) -
self.tableView.tableHeaderView = sectionHeader;
However, above points 2 and 4 still holds true.
If you change UIControlEventTouchDown to UIControlEventTouchUpInside?
One thing is the section header, and another is the table header. You are assigning the same view as both. I'm not sure this is the cause of your problem, but it's something to get you started.
Instead of implementing that method, on your viewDidLoad, create that view and assign it as the self.tableView.tableHeaderView
Additionally, the most common user experience is associated with the UIControlEventTouchUpInside (the action will not execute until the finger is lifted and still inside the button). However this likely has nothing to do with your issue. It's just a matter of when the action is called.
If this doesn't fix your issue let me know and I'll try to check if there's something else I've missed
Cheers!
If you add a view
self.tableView.tableHeaderView = ({
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 184.0f)];
you can add new components: UIImageView, UIlabel...
Its works for me!
I tested.
The final code:
self.tableView.tableHeaderView = ({
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 184.0f)];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 40, 100, 100)];
imageView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
imageView.image = [UIImage imageNamed:#"avatar.jpg"];
imageView.layer.masksToBounds = YES;
imageView.layer.cornerRadius = 50.0;
imageView.layer.borderColor = [UIColor whiteColor].CGColor;
imageView.layer.borderWidth = 3.0f;
imageView.layer.rasterizationScale = [UIScreen mainScreen].scale;
imageView.layer.shouldRasterize = YES;
imageView.clipsToBounds = YES;
UIButton *mapLaunchButton = [UIButton buttonWithType:UIButtonTypeCustom];
[mapLaunchButton addTarget:self action:#selector(mapButtonTouch:) forControlEvents:UIControlEventTouchDown];
[mapLaunchButton setTitle:#"ggggggg" forState:UIControlStateNormal];
mapLaunchButton.frame = CGRectMake(0, 0, 300, 90);
mapLaunchButton.backgroundColor = [UIColor redColor];
[view addSubview:imageView];
[view addSubview:mapLaunchButton];
view;
});
I had the same problem. Changing UIXXXXX from UILabel to UIView in the following line worked for me:
UIView *sectionHeader = [[UIXXXXX alloc] initWithFrame:CGRectNull];
and I didn't use:
self.tableView.tableHeaderView = sectionHeader;

Resources