I'm trying to add a custom subview to a UITableViewController that doesn't move when the user scrolls.
Is it possible to add such a view?
I'm using a UITableViewController. I would switch to a UIViewController and add a UITableView, but the code relies on the UITableViewController's refreshControl. Adding a container view and having two controllers seems a bit much for such a simple task!
I've also tried adding the content to the UINavigationController view, but unfortunately it doesn't animate smoothly when the view controller appears and disappears.
Is there any way to add a fixed subview to a UITableView?
Edit:
Adding a container view and having two controllers (with an embed segue) is difficult for this project, since I'm updating an older code base and there is a lot of legacy code that depends on the main controller being a UITableViewController. Is there any way to achieve this without an embed segue / two view controllers?
Unfortunately creating a container view for a UITableViewController inside of a UIViewController isn't feasible in this case. That is a great solution if you're early enough in development to arrange things properly.
The best solution I've found, is to transform the floating view's y position on scrollViewDidScroll as per this answer:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
self.header.transform = CGAffineTransformMakeTranslation(0, self.tableView.contentOffset.y);
}
I have seen other answers which modify the floating view's frame, but I think transforming is probably more appropriate.
As an interesting aside, I was able to create a floating view that 'dismisses' when the user scrolls down, but 'floats' when the user pulls to refresh by checking the table view offset before applying the transform.
Related
I would like to implement a tableview within a stack view in Xcode (Swift).
I have no problem putting it all together in the Storyboard. I am using an UIViewController to control the various stack views but I just can't figure out how to hook-up the tableview.
Possibly its best to abandon the stack view concept. Prefer not to because it does a neat job of certain display issues.
For hooking it up, it makes no difference whether your table view is in a stack view or not. You need to set the table view's delegate and data source, probably to your view controller(that's the quick and dirty place to hook it up). You should be able to do that in interface builder(make sure your VC conforms to UITableViewDelegate and UITableViewDataSource) Now table views have no intrinsic size, so if it runs but you can't see it, you might have to give it a size to get it to appear correctly(subclass UITableView and give it an intrinsic content size, or, probably simpler, add constraints on its height/width)
(I have read other questions and answers on this topic, but most are very old and do not relate to iOS 9 or 10.)
The app design calls for the top half of the display to always contain the same content. (An image being edited by the user.)
The bottom half of the display needs a UITableView. When a UITableViewCell is tapped, the bottom section needs to transition to a new UIViewController with slide-on animation, similar to how UINavigationController push segues work.
Problem: only the bottom view needs to transition to the new view controller(s), and back again. The upper half of the view hierarchy needs to remain unaffected. For this reason, I can't place everything inside a UINavigationController, and I can't have a UINavigationBar at the top of the screen.
Question: what approach should I take in such a situation, where I need only one UIView hierarchy to transition in push-segue fashion, but not anything else? Thanks.
Edited with Solution
Solution follows, for those following along at home.
Yes, you can actually use a UINavigationController for the bottom half.
If you are using Storyboards, the easiest way to do this is to use a container view for each part of the screen which you then can embed a UIViewController in for the top part and a UINavigationController in for the bottom part. If you are doing this programmatically, just add the view controllers as child view controllers to your app's initial view controller (see this answer for more info) which is essentially what the Storyboard will do for you automatically when using a container view.
As a child view controller, the UINavigationController will act independently from the top UIViewController and should behave as expected.
I recommend the programatic approach for the following reasons:
It helps you understand the inner workings of child/parent view controllers much better which will likely save you a significant amount of debugging time down the line.
It makes adding/removing/swapping child view controllers as simple as a few lines of code. Trying to do this with Storyboards is notoriously hacky and cumbersome.
It's much easier to keep track of changes using GIT (most mid-size/larger companies actually prohibit Storyboards for this very reason)
If you want change in part of the screen you can use container view. For details refer Swift - How to link two view controllers into one container view and switch between them using segmented control?
You can use multiple view in one view controller and can give animation like push or pop to show or hide it.
Second approach is you can use Container View which will give exact effect like navigation stack.
I'm trying to change the size of a tableView I have in interface builder and can't seem to. When I first started the app I could drag it around and stretch the sides but all of a sudden I can't adjust it. I tried to delete my tableView and add a new one but the same thing happened. Thanks in advance. Here's what I see when I try to change the size:
if your using a UIViewController you can drag and drop a tableView and can place in a custom position you want. but if your using a UITableViewController you cant move the tableView to your custom position. if you want to do it in UITableViewController you can do like below
if you want your tableView content should show from a point, that you want you can do this way,
[self.tableView setContentInset:UIEdgeInsetsMake(100,0,0,0)];
else if you want set your tableView to a frame in UITableViewController you do this way,
- (void) viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
self.tableView.frame = CGRectMake(0,100,320,300);
}
hope this will help you.
What kind of view controller are you using to manage your table view? Since you show "prototype cells", I'm guessing it's a UITableViewController. Those are built to fill the entire screen with a single table view (which has always annoyed me.)
Starting with iOS 6, though, you can create a "container" view in another view controler, and then drag an embed segue from your container view onto the table view controller. That does all the housekeeping to make the table view controller a child view controller of the other one, and then you can make it whatever size you want.
If you don't want to use a UITableViewController as a child of another view controller, you can use a regular view controller and wire up the data source and delegate methods yourself. However, things like static table views and prototype cells don't work then.
Hopefully this helps someone still coming across this problem. What I did was make sure the UIViewController had a UIView as its direct child, then dragged the UITableView as a child of the UIView, this allowed me to resize the UITableView.
I have a screen with a table view managed by a controller based on UITableViewController. I would now like to affix a button to the bottom of the screen so that it does not scroll along with the table view cells.
Replacing the UITableViewController with a plain UIViewController is not an option, as I want to include a UIRefreshControl. From what I have read, using a UIRefreshControl without a UITableViewController is currently not possible without resorting to any hacks / relying on undocumented behaviour.
I tried using a UIToolbar provided by the navigation controller which my table view controller is contained in, but there are two problems with that approach:
I only want the toolbar with the button to be present in the top level table view. However, I have not found an elegant way to only show the toolbar for the top level table view. I want the toolbar to animate out of the screen to the left together with the table view when I drill down.
I have not found a way to increase the height of the toolbar. Would I have to put the button in a dummy UIView?
This is approximately what I am aiming for:
http://pic.rockmynews.com/img/free-iphone-app.png
Another idea is using a container view controller containing the button at the bottom and the table view controller above it as its child view controller. But that seems a lot of work for something this simple.
So what is the best way to do this? Any recommendations?
Create the UIView container view. But also create a UIViewController subclass to manage the container. Then, add your existing table view controller as a child view controller and add the table view as a subview. Now you can control all of the subviews and positions while still having automatic refresh control operation.
Just use
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
and return a UIView for the desired button. and
tableView:heightForFooterInSection
and return the footer height
If you aren't willing to use a container view controller, you could use a third-party pull to refresh control like https://github.com/samvermette/SVPullToRefresh instead. This has the added benefit of being backwards compatible with iOS 5, if you want to support it.
You can use a UITableViewController. Just override viewDidLoad and then resize the tableView to make room for your extra view and then add your view programmatically. Make sure to set the right resizing mask so that things look correct on different screen sizes. (Easily tested in the Simulator by trying it out on the iPhone4 and iPhone5)
In my view I am using a UITableView that is controlled by a UITableViewController on the top half of the screen. The remaining screen is used for a UIScrollView that contains a view that is controlled by the main UIViewController.
When I perform a pull down to refresh in the UITableViewController, (for some reason if the number of table entries is less than or greater than the initial load value, the UIScrollView in the main UIViewController's frame gets changed to the screensize...
Essentially it breaks my paging unless I reset the scrollview back to the intialized size...
I have no idea why this happens as the UIScrollView is not used in the UITableViewController. The only scrollview that is used in the UITableViewController is the UITableView's to handle pull down to refresh...
Does anyone know why the main UIScrollView's contentSize gets changed randomly when it shouldn't even been accessible from the UITableViewController class?
Thanks
Just tried it here, and I can't duplicate your experience. I'm guessing you have an unexpected or inconsistent view/controller hierarchy? Look at the controller of the table and scroll views' common superview. Anything fishy there? Remember: view controllers manage sets of views. Container view controllers manage other view controllers and have special rules (see: The View Controller Programming Guide, esp. -addChildViewController:, etc.).
I'd suggest opening a blank project and trying to recreate the problem in its simplest possible form. If it's magically fixed, what's different? If it's still giving you trouble, send us a link so we can see the details of how you have things wired.