I've currently got two view controllers A and B, A uses a segue to push B and this works back and forth nicely, however based on some button presses in view controller B i want to change the text within a UITextView in controller A.
I've had a look at previous posts but i'm a novice at present and was confused by the way in which i should go about doing this.
I'd love to be able to get my head around how interactions are best done between various parts of the app. Also i was wondering if there is a way i can tap into a segue returning to trigger some other code.
Thanks
Edit:
OK perhaps i was a little bit limited with my information, from what i can gather reading other posts they are manually creating a variable for the viewcontroller (A) in viewcontroller (B) then accessing it in the second view controller (B) and setting a variable (property and synthesize) to edit that way, however i have the viewcontrollers embedded in a navigation controller and using a push setup in the storyboard (GUI system). I'm not sure if i have to create a variable to do this or if because they exist in the storyboard there is another way, if someone could just point me in the direction of a post that helps to explain this (i am looking at the moment too) i'd be very grateful.
OK well here's how i got it to work but i imagine there are:
A: Better ways to do it.
B: Changes depending on your setup.
I had my two view controllers embedded in a navigation controller, and used a segue push to access the second view controller each had a different class (all setup in the storyboard thing).
To get it working for me i did the following:
I have a singleton (a class that stores all my data but is global to the app so the variables can be accessed from anywhere in the app) this allows me to have variables that i can access from any view controller. A great tutorial on this can be found here
I then created an NSString variable (passedNote) and updated the value of this variable from the ViewController B, when my button was pressed.
Next when viewController A is loaded (in the viewWillAppear: (BOOL)animated method) i append or replace the value of the textview (dependent on some logic) I have with the global variable (passedNote).
Hope this helps anyone who had the problem.
Related
A little confused on how to implement this into my main view controller. The example project shows it as a navigation controller, but I wasn't able to add an existing class on a fresh navigation controller or my current UIViewController. I could just be implementing it wrong though. Much appreciation if I can gain some traction on how to work with these.
If you could share some code that would be great.
How things work:
Navigation Controllers
There are currently 4 different Navigation Controllers that each offer their own features. The controllers can be used individually, or together.
SideNavigationViewController
The SideNavigationViewController offers 3 bodies to display content: mainViewController, leftViewController, and rightViewController.
MainViewController
The mainViewController must always exist, and has a facility for transitioning between view controllers using the transitionFromMainViewController method. Using this method is as easy as passing a UIViewController in its first parameter.
sideNavigationViewController?.transitionFromMainViewController(InboxViewController())
There are further parameters that allow for animations, completions, etc... to be set when transitioning between view controllers.
LeftViewController and RightViewController
The leftViewController and rightViewController can be set only once. To make them dynamic, you would need to use another Navigation Controller as its view controller.
NavigationBarViewController
The NavigationBarViewController offers a NavigationBarView along side the ability to manage two UIViewControllers, the mainViewController and the floatingViewController.
MainViewController
The mainViewController is like the SideNavigationViewController's mainViewController, and has a transitionFromMainViewController method that transitions from view controller to view controller in the body portion of the NavigationBarViewController.
FloatingViewController
The floatingViewController is a modalViewController and when set, it pops over MainViewController and NavigationBarView. Setting that value is like so:
navigationBarViewController?.floatingViewController = InboxViewController()
To close and hide the floatingViewController set it to nil, like so.
navigationBarViewController?.floatingViewController = nil
SearchBarViewController
The SearchBarViewController offers a single transitioning mainViewController, as well, has a SearchBarView at the top. Transitioning the mainViewController is like so:
sideNavigationBarViewController?.transitionFromMainViewController(InboxViewController())
MenuViewController
The MenuViewController is another controller that has a mainViewController, which takes the entire screen. Floating above it, is a MenuView that is used to transition between mainViewControllers.
menuViewController?.transitionFromMainViewController(InboxViewController())
Final Notes
These Navigation Controllers can be used in any combination and any amount of times creating a robust and intricate stack of controllers that act like one.
I hope this helps :)
I am trying to pass a simple core data objects info from a tabBarController to its subviews so that they each reference a different attribute of that object. As a newbie, I'm not sure even where to start. It doesn't seem to be as simple as passing the data from one tableView to another...
Thank you for any help.
If you are sharing the same object between (most of the) the view controllers of your tab bar controller, maybe the best architecture for this would be to have one central data object.
A typical pattern is a singleton, some kind of data manager that provides the object, but maybe that is overkill. Another is to keep references to all view controllers and update them one by one when something changes - also not very elegant.
What you really want is something like a global variable. You could (ab)use your app delegate (just give it a property that points to the object) or if you prefer even your tab bar controller (make a subclass, give it a property). In the latter case, every view controller could then get the object like this:
NSManagedObject *object = [(MyCustomTabBarController*)self.tabBarController object];
For example, you can check for changes and refresh your views in viewWillAppear.
A UITabBarController should be handling other view controllers, not handling data objects. How does the tab bar controller get the object reference in the first place? And what is the object you're sharing?
Let each of your subordinate VC's keep a pointer to the object, and then they can each follow the appropriate keypath to get to the entities they're designed to handle.
Tim Roadley's book Learning Core Data for iOS, in chapters 5 and 6, shows how to pass an object from one view controller (a table view) to a detail view. It doesn't sound like that's what you're asking, but just in case...
In response to comment:
I'm looking at a tableview, tap a cell, and then a tab bar controller slides in? That's not the usual visual metaphor for a tab bar; it's meant for changing modes for the entire program. See the Music app for a typical example: songs, playlists, artists.
But if you really need to do it that way, try this (I'm assuming you're using storyboards):
In prepareForSegue: in your tableview controller, tell the destination (tab bar controller) what object it's working with.
In the tab bar controller's -viewWillAppear, tell each of its tabs about the attribute: self.frobisherViewController.frobisher = self.myWidget.frobisher.
You could instead tell each of the component tabs about the top level object: self.frobisherViewController.widget = self.myWidget. But I like the first approach better because there is less linkage. The frobisherViewController now would need to know about both widgets and frobishers.
This ended up being very simple. I was trying to call the object in the child views initWithNibName which doesn't work. I ended up creating a setObject function and calling the properties I wanted in viewWillAppear.
Hope this helps someone.
Getting started with xCode 4.6.3 and I'm running into a hiccup.
I've built a simple app using the UIWebView to display a local HTML file and it's contents. I used that to debug any issues with the HTML and/or image displays and I'm all set.
Now I need to recreate that within a larger project I've built with storyboards for all my navigations between multiple view controllers. My issue comes when I'm trying to control-click drag from the WebView into the ViewController.h code below the #interface like many tutorials show, and that worked fine within my smaller single view controller app. It won't do it. I know I'm missing something obvious here. Am I going to have the set up these screens (I have multiple ones to do this same way) as separate xib files and add them into my main project?
Thanks for any help and clarification.
-Chris
You can create a class called for example myWebViewController and in Interface builder add a UIWebView to it. The control+drag to the header file will work.
Every time you want a UIViewController that has a browser in it, define its class as myWebViewController in Interface Builder.
Try not to repeat code. If you see UIViewControllers or any other UIView...that do the same thing, you can group them into a class that you use over and over.
Using the Reflection API to auto generate a UI.
How can I dismiss the keyboard when the user selects a new field, or if they choose a field which generates a new view to pick from. In the later case, when the user returns to the first screen, the old keyboard is still there.
UIView.EndEditing(bool force);
The above will hide the keyboard for you without needing to know who the first responder is. I haven't done much with the reflection API but you should be able to call that on the view when an element is selected.
Apple Docs -- endEditing:
Clarification for those initially struggling with the MonoDialog portion of the question:
The EndEditing method is not available on DialogViewControllers objects directly (who inherit from UITableViewControllers). You should be calling EndEditing(bool) on the View of a DialogViewController and not trying to call EndEditing(bool) on the actual DialogViewController itself.
For clarification:
DialogViewController dc;
dc.View.EndEditing(true);
Note:
UIView objects include the EndEditing(bool) method, but UITableViewControllers do not inherit from UIView so the EndEditing method is not available on the controller itself. UITableViewControllers contain a view object, call EndEditing on that view object.
Check the ResignFirstResponder method. This one should help you I guess.
my question is about view controllers, delegates and all that in general. I feel perfectly comfortable with UIView, UIViewController, Delegates and Sources, like UITableView does for instance. It all makes sense.
Now I have implemented my first real custom view. No XIBs involved. It is an autocomplete address picker very much like in the Mail application. It creates those blue buttons whenever a recipient is added and has all the keyboard support like the original.
It subclasses UIView. There is no controller, no delegate, no source. I wonder if I should have either one of those? Or all, to make it a clean implementation.
I just cannot put my finger on the sense a view controller would make in my case. My custom view acts much like a control and a UIButton doesn't have a controller either.
What would it control in my view's case?
Some of my thoughts:
For the source: currently the view has a property "PossibleAutocompleteRecipients" which contains the addresses it autocompletes. I guess this would be a candidate for a "source" implementation. But is that really worth it? I would rather pass the controller to the view and put the property into the controller.
The selected recipients can be retrieved using a "SelectedRecipients" property. But views should not store values, I learned. Where would that go? Into the controller?
What about all the properties like "AllowSelectionFromAddressBook"? Again, if I compare with UIButton, these properties are similar to the button's "Secure" property. So they are allowed to be in the view.
The delegate could have methods like "WillAddRecipient", "WillRemoveRecipient" and so on and the user could return TRUE/FALSE to prevent the action from happening. Correct?
Should I maybe inherit from UIControl in the first place and not from UIView?
And last but not least: my custom view rotates perfectly if the device is rotated. Why don't all views? Why do some need a controller which implements ShouldAutoRotateToDeviceOrientation()?
Does it make sense what I wrote above? In the end I will provide the source on my website because it took me some time to implement it and I would like to share it as I have not found a similar implementaion of the Mail-App-like autocomplete control in MonoTouch.
I just want to learn and understand as much as possible and include it in the source.
René
I can answer part of your question.
I just cannot put my finger on the
sense a view controller would make in
my case
The ViewController is responsible for handling the View's state transitions (load, appear, rotate, etc) These transitions are used mainly when you use a navigation component (UINavigationViewController, UITabBarController). These components needs to received a ViewController that will handles the view's transitions.
For exemple, when you push a ViewController on a UINavigationViewController, it will cause the ViewDidLoad, ViewWillAppear, ViewDidAppear. It will also cause the ViewWillDisappear, ViewDidDisappear of the current ViewController.
So, if your application has only one portrait view, you don't need a ViewController. You can add your custom view as a subview of the main window.