How to move an entire UITableView down programmatically - iphone

I have a tableview that I need to push down and resize smaller. I cannot use the content inset for this as its not the content I need to push down. I need to actually move the entire tableview down 44px.
What I have tried:
CGRect tableViewFrame = self.tableView.frame;
tableViewFrame.origin.y = 44;
self.tableView.frame = tableViewFrame;
Thank you in advance!

You need to change your UITableViewController to a regular UIViewController and then add the table as a subview. Then, just manually implement the UITableViewDelegate and UITableViewDataSource protocols in that view controller. After doing this, you can move the table view with your above code like any other subview.
Have a look at this answer for an example.

Convert your UITableviewController to a UIViewController and then add the tableview as subview in your nib. Also don't just change the y coordinate of tableview. instead define a new frame for your tableview e.g. self.tableView.frame = CGRectMake(x,y,width,height)

you can not move UITableviewController down, instead of this you can do like this
Create a file having UIViewController subclass with XIB.(create a seperate view controller)
Add UITableView as subview
Then wired up the UITableview , delegate and datasource.
Implement delegate protocols for tableview
use your code as it is ..
it works fine.. :)

Related

Add Subview to UITableView's Parent view

I'm trying to add a subview to the parent view of a UITableView in order to have a subview that does not move when the UITableView is scrolled.
When I add the subview to the UITableView it moves with the table on user scrolling action.
So far, my scenario is that I have 3 UINavigationControllers on a UITabBarController.
Each has a UITableViewController.
I would like to add a subview to the screen of the individual controllers. However, I don't want the new subview to be added to the entire application like this:
[[[UIApplication sharedApplication] keyWindow] addSubview:newView];
When I push a new controller to the stack or pop one, I would like the subview to move and disappear with the UITableView it's on top of. Keeping the fact that when the user scrolls the UITableView, the new subview sits at its position without moving.
So that the UITableView and the new subview are on the same level.
Thanks
A couple of approaches:
First, to add a view to a table view that stays when the user scrolls, if your table only has one section, you can add a header for that section. For example, this adds a plain blue UIView as a header to the tableview:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, self.view.bounds.size.width, 50)];
view.backgroundColor = [UIColor blueColor];
return view;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 50;
}
Second, if you have more than one section, though, that trick doesn't work, and you'll want to use a UIViewController instead of a UITableViewController, add you header to the top of that controller's view and add a tableview to the bottom of that view. You'll want to make sure you set up (a) an IBOutlet for the tableview (generally to a property called tableView, to avoid confusion); and (b) specify the view controller as this tableview's data source and delegate.
Third, if you want this header to appear on every scene in your app, another approach (in iOS5+ apps) is to use view controller containment, create a container view that has your header, and then add your app's first scene as a child view of that view container. It's not hard, but if you're a new developer, I might discourage you from trying that. I've done it and it works well, but it's not for all people.
Fourth, if your app is using a navigation controller, you could customize the navigation bar to render your custom look and feel. It all depends upon what you're trying to accomplish with the header.
Add your subview to the tableview..
Implement the delegate method scrollViewDidScroll.
On scrollViewDidScroll, just set the required center of the subview you want.

Make self.view a UIScrollView?

I'm experimenting with a TabBarController and the default project creates the UITabBarController and also gives you two view controllers.
I want the view of one of these view controllers to be a UIScrollView, i.e. when calling self.view on FirstViewController I want to get back a UIScrollView * and not just a UIView *.
The view controller gets initialised with initWithNibName: but I can't see anything assigning the view property in there.
If this all sounds a bit weird, maybe I'm doing this wrong? I realise I can drop a UIScrollView onto the view that's already created with me, but it just seemed a bit pointless to have a parent view in this case.
Thanks in advance.
Ok, just realised how to do this.
I can do a cast in my code to make UIView a UIScrollView. Like so...
UIScrollView *tempScrollView = (UIScrollView *)self.view;
tempScrollView.contentSize = self.view.bounds.size;
Then, in Interface Builder, you can use the inspector to set a custom class for your UIView. I set the class as UIScrollView in here and all seems to work!
If you want to use interface builder. Just load up your nib, delete the view on the left panel, and drag a UIScrollView into the area.
Next link from Files Owner to the new UIScrollView as the view property.
The only downside to doing it this way is in your code, whenever you want specific UIScrollView functions you will have to typecast the view property (using (UIScrollView *)self.view ), or put it in a variable like so
UIScrollView *sview = self.view;
//Then use sview for your changes
The best way would be to do it in code however.

UITableViewController and sub views

I have a screen where I want to display the details of some product. I'm using storyboards.
I have done this using a tableview with static cells, but static cells can only be done within a tableview of UITableViewController. And the problematic point is that I also want to have a Imageview within this controller. this is not possible as the tableview of a UITableViewController take all the screen size.
So I'm doing the Imageview as a subview of the tableview.
I'm wondering if it is the right way to do it, there are similar issues on stackoverflow but none is corresponding to my use case (storyboard + tableviewcontroller + staticcell + sub view)
Without writing any custom code, you could either:
Put a UIImageView in the table view's header or footer view.
Create a static cell and put the UIImageView in that. Table cells don't have to be uniform length, you could make it taller than the other cells if needed.
You can have your subclass of UITableViewController. After you initialize it take its view (tableView) and add it as subview to some other view controller. This way you can set the frame of tableView to occupy the bottom of the (top containing) view controller. To the same view controller you can add additional subviews like UIImageView and position it on the top. The only problems you will encounter might be related to missing notifications to your UITableViewController subclass (viewWillDisappear, viewDidDissappear, viewWillAppear, viewDidAppear, ...). But you can forward them to from your top view controller. Or you could use methods from iOS 5 to add subclass of UITableViewController as a child view controller and position it as you wish. But this is useful if you plan on supporting devices with iOS 5.0+.
See documentation of method in UIViewController:
- (void)addChildViewController:(UIViewController *)childController __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_5_0);
Use a UITableView as a property of the viewController and add it to vc.view, rather than subclass a UITableViewController, then set its frame as you like
Add the imageView to vc. If you need to put it on top of the UITableView, for example, add it as the TableView's header.

Add tableview as subview (if you have to inherit from UITableVC)

What I want is a tableview with an ad view on top for admob and pull to refresh. Right now i'm using the tableheaderview, but that scrolls and I need the ad to persist. viewforheader doesn't scroll, but gets rid of the standard headers that i need for the section headers. if im inheriting from a tableVC, is there anyway to override loadview to build a static view to hold an ad and then have the tableview below that? i've tried writing loadview and can get the ad, but when trying the tableview, i get "unable to restore selected frame" in the console. i'm using culver's pull to refresh technique as its very simple to implement. i know a tableVC assumes the root view is a tableview so how can i get around that? every solution on the net says use a standard uiviewcontroller, but im stuck cause of the pull to refresh
this is in my loadview:
self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 60, 320, 400) style:UITableViewStylePlain];
self.tableView.dataSource = self;
self.tableView.delegate = self;
[self.view addSubview:self.tableView];
Make your view controller inherit from UIViewController, but continue to implement <UITableViewDataSource, UITableViewDelegate>. Add your TableView as a sub-view of the UIViewController's built-in view, pointing to File's Owner for data source and delegate. Make the table view less than 100% of the height, and have the ad as another view within the main view that makes it appear below/above the table.
source: I do this in my apps, and they are on the store.
There are lots of things you could try.
You could stop inheriting from UITableViewController, like everyone says. If you're using Culver's PullRefreshTableViewController, adapt it to just subclass UIViewController. You'll need to add back the tableView property, and adopt the UITableViewDataSource and UITableViewDelegate protocols if you do.
You could set the contentInset of the table view to leave room at the top, and define scrollViewDidScroll: in your controller to reposition the ad view appropriately on each scroll. (UITableView subclasses UIScrollView, so it will call the UIScrollViewDelegate methods if you define them.)

How do I reduce the height of a TableView when it is constructed in IB?

I wanted to add a view to the bottom of my screen. The controller is a UITableViewController, how do I shrink the tableView and add a extra view at the bottom of the tableview?
I've tried setting the frame of self.tableView in different places (viewDidLoad, viewWillAppear etc) but nothing happens. The tableView is created by IB and not programtically.
I've tried added a footer to my table view but that's not what I want, because the footer actually scrolls up, I want a static non moving View at the bottom of the screen.
I'm not saying you can't do it otherwise, but you may not want a UITableViewController for this situation. You can still have your view controller implement UITableViewDelegate and UITableViewDataSource, but place a vanilla UIView in your nib, into which you place a UITableView. Then just make sure to set the view outlet to the UIView containing your table. This has the effect of allowing you to create your additional view within IB. I just tried this and it appeared to work.
I'm guessing you're using a UINavigationController. When you push a controller onto your navigation stack, UINavigationController resizes its view to full screen, ignoring the geometry and autoresizing behavior you've defined in IB.
This resizing seems to happen after viewWillAppear:. In the past I've had some success resizing a table view and adding a sibling view in viewDidAppear:, after calling [super viewDidAppear:]. This is a bit risky though, since Apple could break it by changing how UINavigationController works behind the scenes.
A safer option is to push a view controller onto your navigation stack that controls a wrapper view. Then add your UITableView and its sibling as subviews of that wrapper view. The annoying thing about this option is that you'll probably want to use a nested UITableViewController to manage your non-full screen table view, but the documentation for UIViewController says it's designed to manage full screen views only. If you decide to ignore this admonition and nest your view controllers anyway, you'll find that viewWill/DidAppear/Disappear don't get called on the nested controller, so you'll have to manually delegate those methods from your wrapper view controller. This lack of support for nested controllers is one of my biggest pet peeves about UIKit, and I've gone to great lengths to engineer around it.
If you want to toe the line and use view controllers only for full screen views, you can push a normal view controller that controls your full screen wrapper view, manually implement all the UITableViewDataSource and UITableViewDelegate methods in your view controller, and set it as the delegate for your table view.
you want to change the -loadView method. Not viewDidLoad or viewWillAppear. This will allow you to make additional configurations with your tableview even if it is created in IB.
- (void)loadView {
[super loadView];
CGRect titleRect = CGRectMake(0, 0, 300, 40);
UILabel *tableTitle = [[UILabel alloc] initWithFrame:titleRect];
tableTitle.textColor = [UIColor blueColor];
tableTitle.backgroundColor = [self.tableView backgroundColor];
tableTitle.opaque = YES;
tableTitle.font = [UIFont boldSystemFontOfSize:18];
tableTitle.text = [curTrail objectForKey:#"Name"];
self.tableView.tableHeaderView = tableTitle;
[self.tableView reloadData];
[tableTitle release];
}
I don't know how to do it in IB but the way to do it in code is with this:
- (void) loadView
{
UITableView *tv = [[UITableView alloc] initWithFrame: rect
style: UITableViewStyleGrouped];
// finishg configuring table view
self.view = tv;
[tv release];
}
Trying to do it in two stages -- style first and then frame or frame first and then style -- neither of them works.