Basically, I want to create a button underneath a grouped table view, like contacts.app has to delete contacts.
I can create the button fine, I'm just a bit puzzled as to how to decide where to put it.
I thought I could just do:
CGRect bounds = [[self tableView] bounds];
Then place the button based on that.
However, when accessing the size.height of bounds I get zero! Is there a dynamic way to retrieve the tableView's height that I could be missing?
Any help is greatly appreciated.
Rich
You can create the size of your button like
CGRect buttonFrame = CGRectMake(0, 0, width, height);
Create the button with that frame, and then set the button as the tableView's footer
myTableView.tableFooterView = myButton;
You could try making a custom footer view with those buttons placed in that view by implementing these methods:
- (CGFloat) tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
- (UIView *) tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
That should let you put any number of buttons on your table underneath the section you want.
You can get the tablewViews heigh by looking at its frame
CGRect bounds= [[self tableView] frame];
float heigh= frame.size.height;
Related
So this is how my app currently looks like http://gyazo.com/f26ecd3a9d173ab76ee86946cd7a152c , when I click on More... (UIButton) the scrollView becomes slightly longer but the TableView still keeps the same size http://gyazo.com/f9f36c5b308f209d81d5a75b430eeb03 , and when I start scrolling again everything goes back to normal like the first picture showed (the scrollView goes to it's original size).
- (IBAction)moreInfo:(id)sender {
[UIView animateWithDuration:1 animations:^{
scrollView.frame = CGRectMake(0, 100, 320, 184);
}];
[sender setTitle:#"Less..." forState:UIControlStateNormal];
}
Any ideas of how I could make the scrollView become bigger and stay big even though you scroll in the tableView.
Also you need to adjust the height of cell in UITableView DataSource.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
Because you reuse the cell inside tableview
I am using a Storyboard to create all my tables but I need to move the tables down the page to insert a UIView above each table. This was trivial using a nib and Interface builder or in code but I can't seem to do it via interface build and story boards. OK so then I try to do it code and no luck there either:
In viewDidLoad:
CGRect frame = self.view.frame;
self.view.frame = CGRectMake(frame.origin.x, frame.origin.y + 44.0f, frame.size.width,
frame.size.height - 44.0f);
If I check both self.view.frame and self.tableView.frame they have been re-sized, yet when the table displays nothing happen.
I have searched around but haven't found a solution so any help would be greatly appreciated.
Add your UIView in table header tableHeaderView.
Also, set custom height to the table header - sectionHeaderHeight:
http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableView_Class/Reference/Reference.html
Use this:
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
return 50.0;
}
Stuck on something and i'm not sure if it's even possible. Is there a way to set the background of a UITableView as a custom image, but NOT let that background apply to the tableHeaderView. I have a header on my table that needs to remain transparent, because I have a parallax type effect (like the path 2 app) implemented with an image behind the transparent table header & the top 1/3rd of the tableview... but i need to get a custom image behind the rest of the table.
I can successfully get close to the background style im looking for that fills in behind each cell, with:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
However, this is not quite what Im looking for because I would like a radial gradient background view behind the entire tableview on the screen, minus the transparent header... not just the same image for each cell. Also, this approach really hits my tableview's scrolling performance loading a new BG image with each cell.
I know you can use:
UIImageView *tempImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image.png"]];
[tempImageView setFrame:self.tableView.frame];
self.tableView.backgroundView = tempImageView;
to set the BG image for the tableview, and it is really close to what I'm trying to do, but I neeeeeed that header transparent. Is there any way to use this, but also tell the tableHeaderView to ignore it and be transparent?
Thanks everyone, & happy Halloween!
Yes, you can. I implemented a solution for the parallax effect for a grouped UITableView. You could use the same approach except instead of a black background (example below) you could use your image. Essentially, you have two views behind the tableview (which is clear, header view background clear as well as the table view background itself). These two views you move based on scrolling (UIScrollViewDelegate). Your tableview background image you'll "scroll" 1 for 1 with the table, while your parallax image will "scroll" at a different rate of course. In the below example i think my "_secondParaView" would be your background image for the table.
Firstly, in viewDidLoad, create a view to partially hide your image for the parallax effect, should be the same color as the background you want the tableview to be, in my case blackColor. I placed the view at a fixed offset based on the size of my image, you want the top of this view to line up with the top of the end of 'section 0' header view. It will then "scroll" just as the tableview scrolls. Insert this view below the tableview.
_secondParaView = [[UIView alloc] initWithFrame: CGRectMake(0.0, kTableViewOffset, self.view.frame.size.width, 200.0)];
_secondParaView.backgroundColor = [UIColor colorWithRed: 0.0 green: 0.0 blue: 0.0 alpha: 1.0];
[self.view insertSubview: _secondParaView belowSubview: _tableView];
_headerImageYOffset = -40.0;
_headerImageView = [[UIImageView alloc] initWithImage: [UIImage imageNamed: #"SpaceRedPlanet640x480.png"]];
CGRect headerImageFrame = _headerImageView.frame;
headerImageFrame.origin.y = _headerImageYOffset;
_headerImageView.frame = headerImageFrame;
[self.view insertSubview: _headerImageView belowSubview: _secondParaView];
_tableView.backgroundColor = [UIColor clearColor];
Then implement the two grouped tableview methods for the header view / header view size:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
if (section == 0) {
UIView * tableHeaderView = [[UIView alloc] initWithFrame: CGRectMake(0.0, 0.0, self.view.frame.size.width, kTableViewOffset)];
tableHeaderView.backgroundColor = [UIColor clearColor];
return tableHeaderView;
} else
return nil;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
if (section == 0) {
return kTableViewOffset;
} else
return 2;
}
Just like in the "normal" tableview parallax implementation, make your VC a UIScrollViewDelegate and implement this scrollViewDidScroll like so:
#pragma mark -
#pragma mark UIScrollViewDelegate methods
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat scrollOffset = scrollView.contentOffset.y;
CGRect headerImageFrame = _headerImageView.frame;
CGRect underParaFrame = _secondParaView.frame;
if (scrollOffset < 0) {
// Adjust top image proportionally
headerImageFrame.origin.y = _headerImageYOffset - ((scrollOffset / 3));
} else {
// We're scrolling up, return to normal behavior
headerImageFrame.origin.y = _headerImageYOffset - scrollOffset;
}
underParaFrame.origin.y = kTableViewOffset - scrollOffset;
_headerImageView.frame = headerImageFrame;
_secondParaView.frame = underParaFrame;
}
Hope this helps, or at the very least helps someone implement the parallax effect for a grouped tableview. I could find no solution for it.
Is there a reason why you cannot have the tableHeaderView be a container for the image you wish to have the parallax-type effect?
Create a UIView and stick it as the tableHeaderView of the UITableView, and then add your UIImageView (or whatever) to that tableHeaderView. With UIScrollView's delegate methods, you will be able to reposition this UIView however you please within it's parent view in reaction to user scrolling.
See this open source project for a Path inspired parallax UITableView: RBParallaxTableViewController
Using storyboard, I made this UITableViewController:
Ok, when I start search, in searchBarShouldBeginEditing: I will hide navigation bar and show the scope bar:
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
[self.mySearchBar setShowsScopeBar:YES];
[self.mySearchBar sizeToFit];
[self.mySearchBar setShowsCancelButton:YES animated:YES];
[self.navigationController setNavigationBarHidden:YES animated:YES];
return YES;
}
But the first cell of table is hidden behind the scope bar. I think I need increase the table header, but how I do this? Or have some other way to fix it?
UITableViewDelegate has a method that does this:
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
//return height as a float here
}
Implement that in your delegate with the appropriate height.
Alternatively, if the bar is hiding the top of the cell, you may need to move the table view down on the screen by changing its frame like so:
CGRect newFrame = tableView.frame;
newFrame.origin.y += 45; //or whatever number of pixels you want to move it down by
tableView.frame = newFrame;
Answering my own question, looking a little further I found a solution that seems most correct, which is using UISearchDisplayController. Here is the tutorial I followed: https://developer.apple.com/library/ios/#samplecode/TableSearch/Introduction/Intro.html
Using this way, he hides the navigation bar and displays the scope without the need for additional codes and without the problem of the first cell being hidden.
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;
}