How can I add a ViewController to scrollview - iphone

I have a scrollview I'm trying to add ViewControllers to from a nib file.
ViewController *controller=[[ViewController alloc] initWithNibName:#"ViewController" bundle:[NSBundle mainBundle]];
[scrollview addSubview:controller];
Scrollview is defined elsewhere.
Whenever I add other items like UIViews with simple colored backgrounds, that works fine. When I add the ViewController from the nib, the Viewdidload gets hit, the images load from the nib, but then the controller code stops there (No viewWillAppear etc). So I don't get any of the controller's processing.
This same controller works fine when pushed as a nav or tab controller. I'm sure I'm missing something in my educational process, but was hoping someone could help out so I can move on.
BTW: The ViewController above is a simple UIViewController.

I think your issue is that addSubview is expecting a UIView not a UIViewController - you probably get a warning when compiling ('may not respond to selector' or similar?). If so, don't just ignore those - in my experience, usually they are a problem in your code :-)
You could try something like
[scrollview addSubview:controller.view];
But this still won't get you the viewcontroller's processing ...you need to do that processing in the view controller that has the scrollview AFAIK. I would suggest trying to get a basic view with a scrollview working in IB first.

OK, seems a little off, but I added viewWillAppear to viewDidLoad, and that worked, but this doesn't seem the right way to do it, correct?

Related

UISearchDisplayController's table view separator lines glitch when loading inside a modal view, how do I fix it?

I'm trying to load a basic search view overlaying my navigation controller (that is, not pushed on the navigation stack). To achieve this I'm using [self presentModalViewController:vc animated:NO].
Full modal view presentation code:
- (void)searchButtonPressed
{
TMSearchViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"Search"];
[self presentModalViewController:vc animated:NO];
vc.searchDisplayController.searchBar.delegate = self;
}
After the modal view is presented on the screen, the following code—inside the search view's controller—is run:
- (void)viewDidAppear:(BOOL)animated
{
[self.searchDisplayController.searchBar becomeFirstResponder];
[self.searchDisplayController setActive:YES animated:NO];
}
The problem is that when the search view renders, it does the normal thing where it blacks out the table view with a transparent black view, but it doesn't appear to cover the table view's separators, which looks like this:
I really have no idea how to fix it. My best guess is that it is something to do with the modal controller's process of loading a view that I'm not understanding properly. I've tried moving the becomeFirstResponder to the viewDidLoad method. I've also tried reordering the setActive method and the becomeFirstResponder method whilst changing the setActive method to animated:NO and YES.
So far, no avail, I'm clearly not understanding something here and I'm guessing I'm using something in a way that is unintended. Please help, Thanks :)
edit: interestingly enough, when I click the blacked out table view to resignFirstResponder the searchbar, and then click inside the searchbar again to activate becomeFirstResponder it loads fine, without the glitch, how it's meant to.
Did you try self.searchDisplayController.searchResultsTableView.separatorStyle=UITableViewCellSeparatorStyleNone; ??
Okay so after hours of messing around in the code, trying to understand what I'd done wrong, I've finally found the answer, or at least a fix. (I'm still mystified as to what was actually going wrong)
I simply deleted the searchbar from the interface builder in storyboard. And replaced it with another one—which involved reconnecting the searchbar to be the searchDisplayController's searchbar property, of course.
My best guess is that Xcode for whatever reason didn't like the order in which I dragged in and connected the UI elements to interface builder/storyboard.
Hope this helps someone.

iOS: confused about removeFromSuperview and switching views

New to iPhone development, but I've been given a big project as a first go and I'm a bit stuck.
Basically the app will start with a settings screen, then you click a button to go to a dashboard with multiple option buttons. Each button will lead to a different Navigation View with tables.
The way I've approached this is to start with a UIViewController with a button, which I've got wired up but when you hit the button and I do:
[self.view removeFromSuperview];
UIViewController *newView = [[UIViewController alloc] initWithNibName:#"Dashboard" bundle:nil];
[self.view addSubview:newView.view];
the second view isn't loading. I just get a blank screen. Do I need to make a reference in the first controller to the second?
Also, am I approaching this in the right way? As long as I removeFromSuperview will I be able to load the navigation controllers on the press of a button?
Sorry if this isn't too clear, I've been through books and lots of websites but don't seem to be able to get my head around this.
Thanks
There is nothing here with the new view, rather the problem is with current view. You have removed the self.view from super view.
[self.view removeFromSuperview];
So anything added to self.view will not be shown, as self.view itself is removed.
When presenting child controller/view from a parent controller, you should consider using presentViewController. Eventually, use dismissViewControllerAnimated when you want child to disappear and parent to reappear.
In parent view controller:
ChildViewController * child = [[ChildViewController alloc] init];
[self presentViewController:child animation:YES completion:Nil];
In child view controller, ie. in some action handler:
-(IBAction)close:(id)sender
{
[self dismissViewControllerAnimated:YES completion:Nil];
}
IMHO you should also get in the habit of naming instance variables to what they are instantiated from. In your example you name the instance newView, when it should be something like newViewController. That way you make sure you don't mix up views with view controllers.
[self.view removeFromSuperview];
You've removed the view from the superview
[self.view addSubview:newView.view];
But you're adding the new view to the same view that you have just removed from the superview. It's not displaying anywhere.
Your third line adds newView as a subview of self.view, but you just removed self.view from it's superview.
I'd suggest reading more about view controllers. You'll want to have one view controller per "screen", so one for your settings screen, one for your dashboard, one for each table, and so on. Then, manage which one is visible by pushing and popping these view controllers from the nav controller's stack.
This removes self.view, which will most likely destroy the object since there will be no other references to it:
[self.view removeFromSuperview];
Here you are creating an UIViewController, and adding it's view to self.view, which is probably not what you want:
UIViewController *newView = [[UIViewController alloc] initWithNibName:#"Dashboard" bundle:nil];
[self.view addSubview:newView.view];
Look into UINavigationController so that you can easily swap screens in and out with some built in animations. Here's a bit more about them. Here's a tutorial.
The UIViewController's view should not be removed from or added to a view hierarchy outside the control of the view controller. While you might be able to get that manipulation to work now it won't in the future.
Read up on view controllers here.
The basic idea is that you present the view controller then it will take care of manipulating the view hierarchy for you.
So a better approach to get started would be to do something like this;
[viewController1 presentModalViewController:viewController2 animated:YES];
This line of code will present viewController2 with the default modal animation (slide in from the bottom). If you'd like a different animation you can change the modalPresentationStyle to one of the constants in the UIModalPresentationStyle enum on viewController1 (note thats a viewController1, not viewController2).
If you want something more like the Clock app look into the tab bar controller. If you want something more like the Mail app look into the navigation controller.

Trying to remove Super ViewController but stuck in View?

I have 3 ViewControllers 1.Main 2.Gallery 3.Text. What my problem is that i have the GalleryViewController using an External UIView with the name GalleryItemView. So once the view controller calls this inside the UIView i have a button that changes the subview so what i do is use the [super addSubView:newView]; eveything works out great but when i return to the GalleryViewController my app crashes so im guessing im doing this wrong. also what i notice is that once i change Views from pressing the button inside the GalleryViewController takes me to the menu and when i do a swipe gesture it scrolls horizontal and i do have a scrollview in the GalleryViewController Class so maybe what im doing is adding a subview to the ScrollView anyone know how i can fix this?
For starters:
[super addSubView:newView];
is pretty much incorrect.
Adding a view to a viewcontroller, you want to do
[self.view addSubview:galleryItemView];
[self.view bringSubviewToFront:galleryItemView];
If you believe you have added it properly, you could do the following to verify it:
if ([galleryItemView.superview isKindOfClass:[UIScrollView class]]){
NSLog(#"galleryItemView's parent is a scrollview");
}
Please post the crash if you still have problems.

superview and parentviewcontroller nil after adding a subview

I think I'm missing something fundamental and so I want to ask the community for some help. I'm building an app based around a basic iPhone Utility Application. My MainView and FlipsideView share some elements so I have created separate ViewControllers and nib files for those pieces. In order to do this I have done the following:
1. Created a viewcontroller called searchDateViewController which is the file's owner of searchDateView.xib
2. searchDateView.xib is basically a UIView with a UILabel inside, the view is wired up correctly
3. Inside both MainViewController.m and FlipsideViewController.m I add a subview as folllows:
- (void)loadView{
[super loadView];
searchDateViewController = [[SearchDateViewController alloc] initWithNibName:#"SearchDateView" bundle:nil];
[[searchDateViewController view] setFrame:[searchDateView frame]];
[[self view] addSubview:[searchDateViewController view]];
...
}
Everything displays and works just fine. Basically depending on actions that happen in each of the main and flipside views the UILabel of the nib is changed. However, I wanted to do something slightly different if the searchDateViewController is loaded from the MainView or the FlipsideView. However, I can't seem to figure out which ViewController is adding the searchDateViewController subview.
In searchDateViewController I tried:
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"superview %#", self.view.superview);
NSLog(#"parentviewcontroller %#", self.parentViewController);
}
In both cases I get nil.
So my question is - can I find out which ViewController is adding searchDateViewController a a subview? If so how? Or if my logic here is completely messed up, how should I be doing this?
Thanks!
viewDidLoad is invoked when the view controller has loaded its view. In your case, that happends in this line:
[[searchDateViewController view] setFrame:[searchDateView frame]];
At that moment, you haven't yet called addSubview: so it is no wonder the view's superview is nil.
To solve your problem, you should define a property inside SearchDateViewController to distinguish between the different cases. This property would then be set accordingly by the parent controller that creates the SearchDateViewController instance.
Generally, I do not think it is a good idea to use a UIViewController subclass as a controller for a view that is used as a subview of one or several fullscreen views rather than be used as a fullscreen view itself. Much of UIViewController's logic works on the assumption that it is used to manage a fullscreen view. For instance, with your design, I think it's possible that SearchDateViewController will modify the view's frame when the device orientation changes etc. Since you don't need all this functionality for a non-fullscreen subview, I suggest you subclass your SearchDateViewController directly from NSObject.
ViewController and views are completely separate.
In most cases, when you add a subview to a parent view you don't add its controller to the parent's viewController. The exception to this rule is the navigation controller which adds the controller instead of the view to maintain a hierarchy of view controllers.
Your SearchDate viewController can't find a parent controller because you never assigned one and the system does not do it automatically. You can just assign a parent controller when you evoke the view from another controller.
searchDateViewController.parentController=self;

adding multiple views to view controller inside a tab controller

I have a tabview controller to which I added a UIViewController to each tab. I want to have multiple UIViews inside the UIViewController.
So in the implementation of the UIViewController class I added [self.view addSubView:uiview1] and [self.view addSubView:uiview2]. The problem is that when I run the app, it crahes on load.
However, if I only used a single UIView and did: self.view = UIView1 that would work fine.
Does anyone know what is causing the problem? Or if I'm doing something fundamentally wrong?
Assuming you are doing this programmatically, you're supposed to create the view in the view controller's loadView method. So you must do this:
self.view = [[[UIView alloc] initWithFrame:someFrame] autorelease];
before you do this:
[self.view addSubview:uiview1];
[self.view addSubview:uiview2];
Otherwise, self.view would be nil.
There's no reason you can't have multiple views within your UIViewController's main view member variable. However, there are quite a few items left unanswered in your question:
How are you obtaining view1 and view2?
Are they outlets in your XIB file (are you using a XIB file, or creating everything in code), or are you creating them in code?
Where in your UIViewController subclass are you adding them to your view member variable?
What's the message printed to the console when it crashes?