adding Multiple subviews efficiently on a scroll view - ios

If we need to add multiple views say - a tableview, a mapview and 2 or 3 more views on a single scrollable screen, then what would be most efficient way to do it ?
And will it be suitable for an app from the point of memory management?
Please share your thoughts.

Here's how you can do it programmatically: just add them in your viewDidLoad (or possibly your viewWillAppear) methods.
- (void) viewWillLoad
{
self.myScrollView = [[UIScollView alloc] init];
//Configure scrollview here (frame, contentsize, contentoffset...etc)
UITableView *table = [[UITableView alloc] init];
//Configure table here (frame...etc)
[self.myScrollView addSubview:tableView];
//Continue adding other subviews here
}
Or you can do it visually using storyboards. Just drag the views that you want onto your storyboard and then cntrl drag to your .m or .h files.
And yes, iOS is designed for displaying multiple views at once. It is suitable.

Related

UITableView as subview of UITextView not properly displayed

I'm trying to implement an autocomplete UITextView. The auto-suggestion is working fine. But the UITableView is getting clipped off. Please look at the image below.
The greybox is the actual UITableView. This UITableView is defined in another .xib file and is being called from another ViewController.
autocompleteTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 30, 320, 35) style:UITableViewStylePlain];
autocompleteTableView.delegate = self;
autocompleteTableView.dataSource = self;
autocompleteTableView.scrollEnabled = YES;
[self.textViewCell addSubview:autocompleteTableView];
here autocompleteTableView is the UITableView and textViewCell is the UITextView. And this is getting called from another ViewController which makes the autocomplete box to constrict to UITextView size.
What i want to achieve is something like this :
Your problem would appear to be because of the view you are adding the table view as a subview of. Even if the table view was visible it most likely wouldn't respond to touches because of the frame of the superview (taps outside the frame aren't handled).
You should consider doing something like adding a new view higher up the view hierarchy which replaces (overlays) the text field and adds the table view. This needs to be added high enough up the hierarchy that the host view is big enough to fully contain the new view (so, the view controllers view).
It should work if you handle the text field as you currently are but add just the table view at the top level of the view hierarchy.

Right way to do implement customView with map

I want to create UITableView with map in beginning. Like in Foursquare app:
The trick is after scroll map should disappear like that:
How to do it? I'm thinking about using scrollview under the TableView, but maybe is a better solution. This can be done in interface builder?
Set your map view as UITableViews tableHeaderView. It will then scroll with tables content like in your screenshot
Short basic example code:
CGFloat mapHeight = 100.0f;
MKMapView *mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, mapHeight)];
// Do additional configurations of map view
self.tableView.tableHeaderView = mapView;
This code added to -(void)viewDidLoad will add 100pts in heightMKMapView to the top of UITableViewControllers table view

Using static cells without a UITableViewController [duplicate]

I'm using XCode 4.2 and have built my UI using Storyboards. I need to create a view that has content above and below a UITableView and I can achieve this by using a UIViewController. A UITableViewController does not let you add content above or below the table. You can use the table header/footer but that doesn't work for what I would like to achieve.
I now have a UIViewController with a UITableView embedded in it. I can adjust the height and width of the UITableView accordingly which provides me the UI layout that I am looking for.
I can customize the static cells in the UITableView but when I try to build I get the following error:
Illegal Configuration: Static table views are only valid when embedded in UITableViewController instances
My question is how are others getting around this? Creating a tableview with static cells and laying them out visually is very nice but apparently that is not allowed for some reason that I cannot understand. I can't switch to a UITableViewController because of my visual layout requirements.
Any assistance would be greatly appreciated.
You can achieve this in Xcode 4.5 and later versions, assuming your app is targeted at iOS 6+.
In the Storyboard simply create a UIViewController with a View Container inside it's main view. Then hook up that View Container to a UITableViewController that contains static cells.
Just like this:
You don't need a single line of code. Just control click, drag and select embed. The view controller containment is handled for you.
You are right. In storyboard, you cannot have a tableView with static cells embedded in a viewController. One way around it (I have not tried it myself, though, so I am not sure if it works) can be that you create an instance of UITableViewController in storyboard with static cells. Add an instance of UIView to your viewController, and then programmatically load the tableView of the UITableViewController into the UIView of your viewController.
pmd's answer works but in the event that backward compatibility with iOS 5 is required as well, you can do the embedding programatically using the View Containment API.
In the viewDidLoad method of your parent UIViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
MyTableViewController* vc =[storyboard instantiateViewControllerWithIdentifier:#"MyTableVC"];
[self addChildViewController:vc];
[self.view addSubview:vc.view];
// ensure embedded view is aligned to top
CGRect frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
vc.view.frame = frame;
[vc didMoveToParentViewController:self];
}
Don't forget to specify a storyboard ID for your UITableViewController with the static cells.
I know this is an old question but I have a scrappy solution to this issue.
I needed 3 static cells on a UIViewController so this is what I did:
Drag in some Table View Cells into your interface (not into UITableView) - add text and whatever else you need.
Make IBOutlet properties for your cells and synthesise them.
Drag a button and make it cover the entire cell. Set the button to type 'Custom' so it appears invisible - repeat for all cells
Add numeric tags to your buttons
Implement the following functions. buttonDown is connected to the buttons 'Touch Down' event. buttonUp is connected to 'Touch Up Inside' AND 'Touch Up Outside'
-(IBAction)buttonDown:(id)sender {
if ([sender tag] == 1) {
myFirstCell.selected = YES;
}
else if ([sender tag] == 2) {
mySecondCell.selected = YES;
}
else if ([sender tag] == 3) {
myThirdCell.selected = YES;
}
}
-(IBAction)buttonUp:(id)sender {
myFirstCell.selected = NO;
mySecondCell.selected = NO;
myThirdCell.selected = NO;
}
You can do whatever else you like in the buttonDown event and use the button to go directly to a new view. I find this pretty useful.
I am not sure what you mean by static cells, but if you are trying to build the cells in IB, and then want to use it in your tableView, what you could do is in your cellForRowAtIndex you can call loadNibNamed passing the name of the .nib file you created for the cells as the parameter. Make sure that you have an outlet in your viewController which maps to the cell's .nib. Try exploring in these directions if that's what you are trying to achieve
You can make it dynamic and then switch of scrolling:
[yourTableName setScrollEnabled:NO];

View added to superview disappearing when navigating tableview

I have a tableView that navigates to a detail view when the user selects one of the tableView cells. This main TableView is created in a UITableViewController class. (MasterViewController)
I used StoryBoard to create the master-detail tableviews.
Within MasterViewController, I lay a tableView over top of the main tableView when the user selects the To button. This second tableView allows the user to select multiple values from this list.
In order to prevent this second tableView from scrolling on the screen when the first (main) tableView scrolls, I have added this second tableView to the superView of the MasterViewController view. ([self.view.superview addSubview:_toView];)
So, in MasterViewController, I add a TableViewController (_toController). I instantiate a UIView (_toView), add a background image to it (_toViewBG) and then add a TableView to it (_toTableView). I then add _toView (which contains this second tableView) to the superview of the MasterViewController view.
_toController = [[ToTableViewController alloc] init];
_toView = [[UIView alloc] initWithFrame:CGRectMake(10,10,263,247)];
_toViewBG = [[UIImageView alloc] initWithFrame:CGRectMake(10,10,257,232)];
_toViewBG.image = [UIImage imageNamed:#"toViewBackground.png"];
[_toView addSubview:_toViewBG];
_toTableView = [[UITableView alloc] initWithFrame:CGRectMake(20,30,220,180) style:UITableViewStylePlain];
[_toTableView setDelegate:_toController];
[_toTableView setDataSource:_toController];
[_toView addSubview:_toTableView];
[self.view.superview addSubview:_toView];
[_toTableView reloadData];
This approach keeps the second tableView from scrolling when I scroll the main tableView. The second tableView stays on top and in place as the main tableView scrolls.
If I select a cell in the main TableView, I navigate to a detailed view. When I return to the main TableView, I am unable to get the second TableView (_toView) to be displayed.
I am not sure how to tell the _toView to come to the front. I realize it is added to the superview of the MasterViewController view. From some experimentation, this superview appears to be a CALayer.
Can anyone suggest how I would get this _toView to display in front of the MasterViewController view?
Thanks in advance for any assistance.
Solved
I ended up just adding the second tableview as a subview of the MasterViewController view.
[self.view addSubview:_toView];
I then disabled scrolling on the main tableview while my second tableview is visible.
Self.tableView.scrollEnabled = No;
Seems to be working fine.
Tim
It may be possible to make this work by calling [self.view.superview bringSubviewToFront:_toView], but my advice would be to make MasterViewController a subclass of UIViewController rather than UITableViewController, and then add both of your UITableView objects as subviews of the root view, (rather than referring to superview).

Add clickable and fixed subview to UITableViewController?

I'd like to place an ADBannerView object onto my UITableView screen statically, what means that I want it to always stay above my toolbar (self.navigationController.toolbar), even when the user is scrolling the tableview. I've solved this by adding by ADBannerView as a subview to my toolbar and given it negative values for the frames origin:
[self setBannerViewSize];
[self.navigationController.toolbar addSubview:bannerView];
The only problem is: I can't click and open the iAd this way - I can see the banner but nothing happens when I tap on it.
Since I'm also using a refreshControl, the option to use a UIViewController instead of UITableViewController and add a tableView manually wouldn't work for me. Is there any other way I can get my ADBannerView statically showing in my table view controller AND still being tappable?
Thank you in advice!
Yay!! After all I succeeded in solving this (really annoying) problem by myself (and a lot of reading around)!
First, I found this really world-changing post. Basically this post handles with the topic that a UITableViewController uses self.view for its tableView property, so overriding the tableView property (or synthesizing it manually) plus giving self.view a new view (from application) and adding tableView as its subview would make it possible to reach the real superview of tableView.
But this still didn't solve my problem, although I was sure it would, because it all made sense. My bannerView appeared in the right place (and was fixed) but it still didn't do anything when clicked. But there was a second minor thing I didn't know about:
As I read in this post the superview of a subview doesn't only have to be userInteractionEnabled but also have a non-transparent backgroundColor. Because my superviews background color was set to [UIColor clearColor] it all didn't work - but setting its backGroundColor to e.g. blackColor solved the whole problem: the bannerView got finally tappable! :)
So, my code is now looking like this:
#synthesize tableView;
- (void)viewDidLoad
{
[super viewDidLoad];
if (!tableView && [self.view isKindOfClass:[UITableView class]]) {
tableView = (UITableView *)self.view;
}
self.view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
self.tableView.frame = self.view.bounds;
[self.view addSubview:self.tableView];
[self resizeTableToFitBanner];
self.view.backgroundColor = [UIColor whiteColor];
[self.view addSubview:bannerView];
// some other code
}
BannerViewController in Apple's iAdSuite sample code solves this problem very elegantly:
https://developer.apple.com/library/ios/samplecode/iAdSuite/Introduction/Intro.html
I think you should use a container view, and set things up in IB. You can add a tool bar and ADBannerView to the bottom of the view of your navigation controller's root view controller. Fill the rest of the space with a container view - this will give you an embedded view controller automatically. You should delete this one and then drag in a tableViewController and control drag from the container view to the tableViewController to hook up the embed segue.

Resources