I have a TabBar Application with 2 tabs saving/fetching data to and from CoreData. The problem that I am having is that when the form has been filled and the user has touched the save button the view is not re-loaded or re-initialised. All I want is for the view to be ready for the user to repeat the process with the next set of information. I am probably not thinking about this in the correct way so a pointer in the right direction would be very much appreciated...
Do I need to manually set everything including the managedObjectContext etc. to nil? Or is there something that I can do with methods like viewWillDisappear that will elegantly help me to "re-initialise" that specific tab?
I ave read up the Apple docs on view hierarchies, and life cycles but I just seem to have confused myself...
Thanks in advance for any suggestions, referrals to code or even recommendations on relevant reading material.
It sounds like what you want to do is reload any data to their default states when the user taps a button. Unfortunately, you'll have to do this manually, setting each IBOutlet's value to a meaningful default (probably the empty string).
There are two ways I can think of that would help make this more elegant:
Use an IBOutletCollection and fast enumeration to loop over all the IBOutlets and not have a bunch of code to do each one individually.
If you're switching tabs in between these events, you can something neat and use your app delegate as your UITabBarControllerDelegate for the tabBarController:didSelectViewController: to call the clearing-out method for you instead of relying on viewDidAppear.
Related
I wan't to creata a "CatchNames" class which I can import into a view Controller that shows a text which asks for text input. I would like to be able to add an instance of CatchNames to my view, have it ask the user for three names in a row and return them in an array.
[self.view addSubview:[catchNames view]];
NSArray *myNamesArray = [catchNames namesArray];
The best way would be to have the application freeze kind of the way it does when you are prompted to enter a password in iOS and continue when the user entered 3 names so I can immediately catch the array in the next line.
While this might not be the best description I still hope you understand my problem.
How can I approach this?
Thank you in advance
I guess you appear to be looking to implement a simple form which gets the user input, retrieves and stores it in an array? Hopefully I haven't misunderstood the question, but this seems to be a simple task you can accomplish with one or more UITextField's and a UIButton as a 'Add' or 'Done' call to action.
Are you looking for some general UI coding level help regarding implementing such a view? If so, I would encourage taking a look at the XCode documentations of UITextField (for capturing text), UIButton (for handling actions) and UIView (for view hierarchy and animation implementation).
Some quick notes;
Looks like 3 names are compulsory, so, you may verify whether a UITextField is empty at the button's click action.
Have the array declared in the view controller, not the view
The 'freezing' you require should take care of itself as long as the view offers no other way out for the user other than clicking the button.
Do excuse me if I am oversimplifying the problem. Let me know if you need me to drill down into anything further.
Cheers!
I've been working on this problem for two days now. I'm working on an iPhone app that, at the moment, has "dual layer" view (see picture.) The semi-transparent orange panel covering the left third of the screen was created by simply resizing the sub-view (in IB) to take up less than half the screen so that, when that view loads, the original view is still exposed on the right. This would allow the left view to be a "menu view" allowing a user to select what he or she would like to appear in the main view window (which is actually a UIWebView...see screen shot.)
----- Click Here For Screen Shot-----
If I'm going to keep this setup (assuming it's not a structural sin), the left-view clearly needs a way to communicate with the main view. Can I invoke methods in the main-wiew ".m" file (WebViewController.m) like viewDidLoad and others from the "ETG" button on the orange subview? Or is this just a really bad idea? And if this isn't a bad idea or a sin against iPhone structure, how would you implement it? I'll thank you in advance for any helpful thoughts or suggestions you might have. Thanks!
If you're following the model-view-controller pattern, which you generally should, then your view should send messages to the controller or modify the model, not another view. Although it really depends on what you're doing. In your case you are using the panel as a control, so you should implement in a fashion that makes it independent of other views.
Usually the only time you have views directly manipulate other views is in layout, and that is normally in a top-down fashion.
Again, these are general rules and there are always exceptions.
What you are describing doesn't seem insane, but they way you go about talking to the main view might need a little work.
It seems like what you want to do is have the overlay view have a delegate that it can send messages to. Does that seem like it would work for you?
Umm, is the web view the main view?
Either way, I'd do this:
One view controller that contains two main areas. One is your UIWebView, and another is your layover. If you do this in Interface Builder, put the Layover on top of the UIWebView.
All you have to do is animate it in and out based on certain input. A bad idea is to say "hide menu" and make the UIWebView take up all the space, so you can't get it back.
Then use use one view controller for both.
The recommended method of communicating between view controllers, if that's subviewed, is to create properties in the view controller that you can pass. Eg: the web view needs to tell the main view what site it's on. So put an NSString in your main controller as a property, then pass it the string on viewWillDisappear or whatever that name is.
(Or, use viewWillAppear on the top level and have it grab that property from the 2nd view).
Essentially it's just a branching tree, and you have to pass data up one node to reach the others.
You "can" use the application's delegate itself/(the application) and from anywhere, call [UIApplication sharedApplication].property (after creating a property), and use it as a global, but that's not considered reusable code. Since you're used to basic, it might work for you.
Finally, C++ globals do work, and there are many examples on the web for using globals in an iPhone program with externs. (even less recommended).
Now, it sounds like you need to read the Views Programming Guide, even though it has severe grammar issues in areas (they may have corrected the homonyms in the 3rd paragraph of the intro by now, but other areas are totally confusing because of that), to get an understanding of how views respond to input, and what happens when input is ignored and bubbles up the tree. (that's basically what it does, lol... but layers and views have intricacies and it's good to understand them and how they function together).
No, it's not a bad idea. But without understanding layers, view animation, and design maybe it is, until you do.
NazCode
If I understand what you're trying to do, one approach is to use notifications. This way none of the objects involved need to have references to one another. Before I learned this approach, I had several awkward cases where I seemed to be working much too hard just to get two objects to talk to one another.
In your case, your orange layer can post notifications and the controller for the UIWebView can listen for them.
So when you tap the button in the orange layer, do something like this:
[[NSNotificationCenter defaultCenter] postNotificationName:#"etgTapped" object:self];
And in controller that looks after the webview add something like this to your viewDidLoad method:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(etgTapped:) name: #"etgTappe" object:nil];
And then create an etgTapped: (NSNotifaction*) notification method in that class.
Finally, in viewDidUnload de-register with the notification centre:
[[NSNotificationCenter defaultCenter] removeObserver:self];
k, I'm new to this so apologies all around, generally.
I'm trying to access the UISwitch value (on or off) from a different view and class and can't make it work.
It's a simple 2 view app. Main view and the second is a preference menu.
trying to write an if/else method to play sound when the switch (on the other view) is on and not when its off.
I cant seem to make it work. Any thoughts or some syntax examples would really help me out.
Thanks.
As Matt Wilding said "it's not good form to access UI components of one view controller from another...".
Instead of accessing the view object, when the switch state is changed by the user you save the status into NSUserDefaults as preference value. Whenever you want, you can access the switch status value through the preferences.
I'm going to take what I think you're trying to accomplish here and suggest an alternative approach. You want to have a preference in your app (assumed from "preferences menu") that allows the user to set something like whether or not you app plays background music. (May not be exact, this is just for clarification).
Typically, in a well designed app, the flow is driven by the data, with the UI reflecting the state of the data model and the controllers coordinating the two layers. What you are suggesting is to have your application play music based on the state of the UI, which is not backed by any data model. This cuts out the model level, and as you noticed, can lead to awkward attempts at communicating between the UI of different controllers for information.
Things like application preferences are typically stored in a nifty .plist file that is managed through the NSUserDefaults class. This would be a great place for the data level tracking of your preference. In this situation, the UISwitch would represent the state of the flag in the settings file, and changing the value of the switch would change the value in the file. Anywhere else in your application that you need to know if the play-sound-flag is set, you reference the data model info instead of the UI. This decouples the view controllers from each other, which is a good thing.
For this purpose add selector for swith and make NSInteger property in app delegate.Like the followed
[
yourSwitch addTarget:self action:#selector(switched:) forControlEvents:UIControlEventValueChanged];
-(IBAction) switched: (id)sender
{
int state=0;
if(yourSwitch.on)
state=1;
else
state=0;
objAppDelegate.switchState=state;
}
then you need to access this appDelegate property in second view where you are playing sound
then according to this value you can do what you want and for making object of appDelegate class you need this line
YourAppDelegateClass *objAppDelegate=(YourAppDelegateClass *)[[UIApplication sharedApplication] delegate];
ok if you have any other doubt then you can ask.
I have been using Objective-C for a while and pretty much understand most of its features. However, the concept of delegates eludes me. Can someone please give a succinct and easy to comprehend explanation of what delegates are, how they are used in the iPhone SDK, and how I can best make use of them in my own code?
Thank you!
There are a couple main reasons to use delegates in Objective-C, which are subtly different:
Enhancing the base functionality of a framework class. For example, a UITableView is pretty boring on its own, so you can give it a delegate to handle the interesting bits (creating table cells, adding text to section headers, what have you). This way, UITableView never changes, but different table views can look and act very differently.
Communicating to parent objects in your dependency hierarchy. For example, you may have a view with a button that the user may push to do something that affects other views. The view will have to send a message to its parent view, or perhaps the view controller, so that it can create or destroy or modify other views. To do this you'd pass the parent object into your view, most likely through a protocol, as a weak reference (in Objective-C, an assign property). The view could then send any message declared in the protocol to the parent, or delegate, object.
This approach need not involve views. For example NSURLConnection passes event back to its delegate, which may be the object that created it, using this mechanism.
Essentially, all a delegate is, is an object that accepts feedback from another object. Put simply, when stuff happens to an object, it tells its delegate (assuming it has one).
For instance, lets say I have a UIViewController with a UITextView placed in the middle of the view. I set up my UIViewController to be the delegate of the UITextView. Then, when certain actions are performed on the text view (begin editing, text changes, end editing, etc), it tells it's delegate so it can do whatever logic it needs to do, like spell checking every time characters change, or dismissing the keyboard when it receives a return key press.
Delegate methods perform a similar function to callback functions in C.
Hope that makes sense :)
Best and simple concept I got from a Lynda.com Tutorial was: When you set a Delegate it means you have been given work to do. So, if you want to use methods that are written in a protocol method, you must implement them by searching in the Delegate Class Reference and using them. I hope it helped.
By the way, Delegates are excellents. They are your friends. They have been made to make your life as a programmer much easier.
Hey all, I'm completely stumped with this iPhone problem.
This is my first time building a view programmatically, without a nib. I can get the view displaying things just fine, but the darn ViewController isn't responding to touches the way it used to in programs where I used a nib. I should add that in the past, I started with the View-Based Application template, and this time I used the Window-Based Application template.
My thinking is that the View-Based template does something magical to let the iPhone know where to send the touch events, but I can't figure out what that would be even after several hours of bumbling around Google. Or I could be looking in an entirely wrong place and my troubles are related to something else entirely. Any thoughts?
There's nothing magical in the view-based template. The most likely reasons for failure to respond to touches are:
You've messed with touchesBegan:withEvent:, userInteractionEnabled, exclusiveTouch or something else, thinking you need to mess with these (generally you don't; the defaults are generally correct)
You created a second UIWindow
You put something over the view (even if it's transparent)
Simplify your code down to just creating a view programatically that responds to a touch and nothing else. It should be just a few lines of code. If you can't get that working, post the code and we'll look at what's going on.
Problem solved. touchesEnded != touchedEnded.
That'll teach me to program without my glasses on.
Another possible scenario for failure in response to touches is when your VC frame is not predefined and its boundaries are actually exceeding the window placeholder. It happens a lot when you just forget to define the frame property for the VC.
Once you define it correctly - User interaction returns to normal.
Good luck !