I have a viewController. That viewController have a containerView that contain another controller. List and map.
I want users to be able to switch between list and map via a button.
So that means the parent view controller (or somebody) need to be able to refer to both the mapViewController and ListViewController.
How can I achieve that?
One way to do so is by using instantiateViewControllerWithIdentifier. However, I do not like identifier. Identifier is prone to mistyping and conflicts. I like Outlet
I read that one possible way to do so is to set a storyboardid. What about if I like the good old outlet?
As I understand it, you have to sub view controllers. What I would do is create a master controller class, which imports all of the other view controllers (think of it as the super class of the entire project) which will then control a empty view, less a button. The background of the empty view will be fed by an "active" view, which will be supplied by either listViewController.h or mapViewController.h This will let the users use both the list/map VC's, and be able to switch between the two.
Related
In my interface I need to provide two NSTableViews in the same window that are structurally the same, but present different data to the user. I'm using storyboards and to do this, I've placed two Container Views in the view controller of the window. I then added a single view controller to the storyboard (outside of the window's view controller) and into that controller placed an NSTableView.
A couple of storyboard screenshots to illustrate:
The NSTableView is inside the Lineup View Controller, which has its own interface and implementation. The two Lineup View Controllers are binded to the container views within viewDidLoad of the Game Board View Controller like so (showing the code for only one of the attachments):
homeLineupView = [self.storyboard instantiateControllerWithIdentifier:#"Lineup View"];
[self addChildViewController: homeLineupView];
[HomeLineupContainerView addSubview:homeLineupView.view];
I'm able to successfully populate the two table views using notifications to provide the data that is unique to each table. The table views are functioning independently, as expected, with no problems.
Where I'm kind of stuck is how I now go about talking to the two table views from the view controller that manages everything else in the window (Game Board View Controller in the second figure). For example, how would I go about telling the table view inside Home Lineup Container View to select row 3? I have references to the Lineup View Controllers, but not the NSTableViews — unless there is a straightforward way to get those so I can call the methods directly. Or... do I need to set up notifications (or some other mechanism) for doing things like selecting a row, detecting a double click, etc?
Thanks!!
Adding a little more information about where I am confused
When I step through my code in the debugger I can "see" the table view inside the NSViewController that references the enclosing container view (see below).
You can also see my very incorrect attempt at using tableView directly to selectRowIndexes. 'visitorLineupView' is defined like so:
#interface GameBoardViewController : NSViewController <NSOpenSavePanelDelegate> {
:
:
NSViewController *visitorLineupView;
NSViewController *homeLineupView;
:
:
}
And the tableview itself is defined like so:
#interface LineupViewController : NSViewController <NSTableViewDataSource> {
:
:
IBOutlet NSTableView *tableView;
:
:
}
So, the procedural C programmer in me sees all this and wants to grab that 'tableView' pointer and use it directly to send it 'selectRowIndexes' message. But I know that conceptual rules of MVC are throwing up roadblocks I'm having a difficult time scaling.
Sometimes IB simply doesn't allow you to add a view as a subview to a UIViewController as illustrated here
If I drag a UIViewController from the object library and try to embed it within Mailbox View Controller.. it doesn't highlight, however it would work fine if I try to add it to the generic View Controller at the bottom (can the fact that Mailbox View Controller have a Customer Class MailboxViewController have anything to do with it?)
I'm pretty sure I can do this programmatically (which is what I'll try next) but I was wondering if there was a reason for this (and if there was a way around it).
update:
this is what i'm trying to accomplish: I was following the steps here to implement a segmented view controller below search bar like in the iphone mail app.. however I kept on getting an error saying that a view can only belong to one view controller at a time.. So what I'm trying to do is basically create a separate viewcontroller, reference it from MailboxViewController as an outlet, make the containing view of my search area the view of this new view controller (this is where i'm getting stuck) and finally make the searchContentsController property of UISearchDisplayController refer to the view of this new view controller. (if this sounds confusing, which I know it does, please refer to this answer)
From your screenshot, the view property of your mailbox view controller is a table view.
A table view in interface builder won't support the dropping of arbitrary views onto it as subviews - where would it put them at runtime? In IB the table has no content, it just has that visual representation of cells to let you know what it is.
You haven't said what you are trying to set up so I can't offer any additional help. Adding a subview programmatically to a table view probably won't give you the effect you're after either - a table view is a UIScrollView subclass, so your new view will either move off screen or get covered up by the table view adding cells.
Assume you do not have a UIController to do the job. From inside the UIView .. how would you replace self with another UIView?
It's not very clear what you are trying to do from your question. UIController is not a class, for instance.
Ideally your app should be structured something like this:
UIViewController subclass
Controls a set of objects that are all on screen at one time. For example, any number of UITextFields, UIButtons, UIViews and UILabels.
has methods (IBActions and other delegate methods) which are triggered by user interaction with the controls and inputs.
has IBOutlets which allow it to manipulate what the user sees on screen. For instance an IBOutlet attached to a UILabel allows changing the text when a user presses a button.
UIView is only generally subclassed if you need custom drawing code, or some kind of custom control. Don't put application logic here if you can help it, and you can usually help it.
You can have multiple UIViewControllers but they usually function very independently. Often View Controllers don't maintain references for other view controllers. If they do it's loose couplings like the delegate pattern.
Bottom line: if you have two views controllers that need to communicate with each-other, you need to have a reference to one from the other. This usually occurs in the form of a property on one or both of the view controllers, and is connected either by interface builder or at run time when you create them.
You can add another subview using self.addSubview: you may also want to check self.bringSubviewToFront:
For more information, check the docs:
http://developer.apple.com/library/ios/#documentation/uikit/reference/uiview_class/uiview/uiview.html
The issue i am facing deals with multiple views, each needing to communicate with one another. I chose to use the File Owner for this, but can't seem to be able to access the already loaded instance of it from inside of views.
Each rectangle represents its own view
Activity will happen on "Some View", where user's event will cause Labels in top view to be updated
Event will not be triggers by a button click of anything like that. No outputs are set up to establish relationships between the views
No outlets are set up between the views
Outlets are setup however between top Views (with Labels) and File Owner (UIViewController).
Ultimately, i'd like to update label in view 1 from view 2.
Then the bar moves, I want labels to change
At this time, i believe a reasonable solution would be to ask the File Owner to make a change for Labels. From the "Some View", i'd like to call the File Owner and make a request.
From the stand point of the any view residing as part of the nib, how can i know who the "File Owner" of this nib is?
In the Interface Builder, File Owner maintains the IBOutlet to UILabels of the view.
You need to define a delegate (or whatever you like to call it) outlet in your Puzzle1 class and link this to File's owner in the nib. This will give you a pointer to the instance of the view controller that currently owns your view. If you set the type of the delegate to your viewcontroller subclass, then its methods and properties will be available to you from within the view.
This sounds potentially horrendously messy and is probably better solved by using NSNotifications.
But anyways, did you know there's a UINib class? Perhaps you could subclass that and keep track of the owners (which get passed in it's instantiateWithOwner: options: method) as things are loaded.
http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UINib_Ref/Reference/Reference.html
I've created a window that contains an NSSplitView in which case the right custom view has a view that I swap into at runtime. The custom view swapped in contains a NSTableView with data inside it. I have a search box in the main window of the application that I want to be able to constrain the rows of the table view with.
I have the code to do this and I know it works, but the code I have was tested with a search text box and table view that were on the same window scope. With the text search box now being in the main window and the table view being in a different custom view, I'm not sure how to get the text search box to call the relevant methods from the custom view's controller class, because I don't have direct access to these method anymore.
I'm sure this is a very beginner question, but any help would be appreciated. Thanks.
Have your main window controller pass the search query or filter predicate to a property of the content view controller.
You can give the main window controller a weak-referencing (assign) property that holds the current content view controller. Implement a custom setter that not only assigns to the backing instance variable, but also does the swap. That, any time it's time to do a swap, you simply say self.currentContentViewController = viewControllerToSwapIn, and when it's time to change the query/predicate, you pass it to self.currentContentViewController.searchQuery (having implemented the searchQuery property in the MainContentViewController class and made all your actual content-view controllers inherit from that class).