Will touchesBegan method called without UIView or UIViewController in iPhone? - iphone

I created an app in where i have appdelegate class only. I dont create a UIView or a view controller. I just added textFields, labels and buttons in my window.
I want to hide the keyboard when the user taps out of the text boxes. This is normally achieved by the method touchesBegan. For implementing this method, two things we need to do.
One is add in the header file(.h)
Another one is set the textField's delegate. Thats is, textField.delegate=self;
I did those two things. But still the touchesBegan method did not called.
Why? Should i have a UIView or UIViewController class for it?
Thanks in Advance

UIWindow is a subclass of UIView, so you could just hook into those. But this is a seriously bad design pattern. Consider modifying your application so it uses a single view controller, rather than doing everything in the app delegate. Otherwise you're jury-rigging the app delegate to be something it was never designed to do.

touchesBegan is a UIView method. if you want to do it in your setup you should create a UIView subclass, put all your controls in that one and implement touchesBegan in the UIView subclass.

Related

Do I need to create a controller for a UITextField?

Just starting out with an iPhone application using xcode 4.2.
I understand that it is good practice to use a subclass of UIViewController for each view in my application, and I am able to write some basic code in these to test buttons etc on the associated view.
Now I want to perform some action on a text field in one of these views, let's say I will use the Value Changed event to log the textfield's contents on each keystroke.
Should I be creating some kind of UITextField controller subclass? Or do I deal with this kind of thing in the existing ViewController subclass that houses the textfield?
If the latter, how do I refer to the textfield in the view controller subclass, and make the connections?
You'll probably want your UIViewController to implement UITextFieldDelegate. Connections can be made via the Interface Builder and outlets or just setting the delegate on the text field and using the reference you get from the delegate callbacks.
You would use the existing ViewController subclass that houses the textfield. A good rule of thumb is one ViewController per screen of views (not including UINavigationController, Modal screens, uisplitviewcontroller, and popovers).
To refer to it, you would make a property in the .h of your custom UIViewController:
#property (nonatomic,weak) IBOutlet UITextField * myTextField;
Note the IBOutlet keyword. This will allow you to connect it in InterfaceBuilder (or your storyboard). To learn how to connect that I would recommend you watch a video about IBOutlets since its more of a visual thing.

iPhone: viewWillAppear is not called for UIView

I have created an UIView in my iPhone app. I want to handle something when user closes or opens when UIView is present as current screen. I thought, i can do this under viewWillAppear:. But, viewWillAppear: is not called in UIView. Does it work only on UIViewController? How can i handle viewWillAppear: or viewDidAppear: for an UIView?
Update: UIView what I created everything through program, not in .xib.
Please advise.
Thanks!
From your message I infer that you wrote your viewWillAppear: method on the UIView class. As you suspect, that method is part of [UIViewController]1, not [UIView]2 therefore it only gets called on the UIViewController.
You should connect the property view of the UIViewController to the UIView object in the interface builder and then implement that method in the UIViewController.
If your view is created in response to an user action,
Update for your update:
You should tag the views either in code (view.tag=1) or IB.
Then you can do if (self.window.rootViewController.view.tag == 1) { ... } from your delegate (assuming you are looking for the view of the controller who is the rootController, otherwise post more details).
It's even better if you define constants on one place instead writing 1 as a literal.
These delegate methods are called every time the superview is presented to the screen and should be implemented in the UIViewControllers.
The gotcha is that these methods aren't called when subviews are presented on the screen, so your superview-view-controller will have to respond to these events accordingly.
You can find more information in this post here.
If you study the documentation for UIView and UIViewController what you will find is -(void)viewWillAppear:animated: is a method of UIViewController and not of UIView, so in order to use it, it must be implemented by subclassing UIViewController. Generally for best practice if you want to follow MVC, any functionality that does not pertain to the view itself should be delegated to the view controller and not be in the body of your UIView subclass.
Create a new view controller with xib file, and then link your custom view class to the view in your xib file.

Is there ever a time when the touchesBegan, touchesMoved, and touchesEnded methods would be handled inside a UIViewController vs. UIView?

Is there ever a time when the touchesBegan, touchesMoved, and touchesEnded methods would be handled inside a UIViewController vs. UIView?
I understand that they are typically used in a custom UIView but I am curious about this situation.
Thanks
I would say the most likely time that you would want to put this stuff into the controller is when you are not subclassing UIView. I tend to put this in the controller to avoid subclassing just to add the touches methods.
Also, depending on what you are doing in the methods, it may be better MVC to put it in the controller. I guess you should consider if your code is "View" or "Controller" code and place it appropriately.
Yes, they can be used in a view controller, and I have used this method multiple times. All you have to do is define these methods in the view controller and they will be called as it moves up the responder chain.

Create a UIView Subclass that calls a delegate function whenever it's parent viewController appears?

EDIT 2: I now think the best soluton is to create ListeningView.h that just includes a ListeningView protocol, instead of subclassing ListeningView (since we can't do multiple inheritance in Obj-C). Then, you still need ListeningViewController as well.
EDIT: Ok, I figured out what the approved idiom is here. I should subclass UIViewController to create ResponderViewController, which will loop through its subviews for ResponderViews when it appears/disappears. Then, any viewController that has responderViews should inherit from ResponderViewController.
=======
UIViewControllers have viewWillAppear, viewDidDisappear, etc. delegate methods.
I would like to create a UIView subclass that can be added to a viewController's view, and when that UIViewController apears or disappears, a delegate function is called.
I could easily do this by putting function calls in the UIViewController viewWillAppear/viewWillDisappear delegate functions, but how can I encapsulate this behavior in the UIView?
I wouldn't do that if I were you. All that sort of behavior should not be controlled by a view; that's just was controllers are for.

MVC: Where to load views?

I have a relatively simple app. I have a fullscreen UIView subclass (musicGridView) that the user interacts with, and a UIScrollView subclass (scrollView) that loads this class in, as well as a ViewController and mainWindow.xib.
Right now, I have a viewController instance loaded in the nib, which is of type myViewController. The nib also has instance of myUIView, which the myViewController is pointed to.
In AppDelegate, I do this:
[window addSubview:scrollView];
[scrollView addSubview: viewController.view];
scrollView.musicGridView = (MusicGridView*) viewController.view;
which I think is wrong. Ideally, the appDelegate doesn't have an instance of scrollView.
In scrollView's AwakeFromNib class, I do the initialization on the scrollView.
The way I think it should go, is load the [window addSubview:viewController.view] in appDelegate, and then point the viewController to an instance of scrollView instead of musicGridView. Then, in scrollView awakeFromNib add a subview of musicGridView.
Eventually, I want to create another view owned by scrollView that is actually a side TabBar (which isn't possible with the given API's) that the user can scroll to the left to reach.
So I guess amongst other MVC stuff, the question is, should the viewController point to the scrollView, which contains all other content UIView subclasses, including musicGridView?
It sounds like you are not using Interface Builder to design your UI. Since this is a new project, I would suggest doing that. You should not have to write any code like this at all. You will however need to describe your outlets and actions.
The two most important things you need to know when dealing with IB are the IBOutlet and IBAction keywords.
Sample class header:
#interface MyClass : NSObject {
IBOutlet UIScrollView* myScrollView;
}
- (IBAction) doWork;
#end
Now you can wire these two things up using Interface Builder by dragging sources to destinations with your mouse. YouTube has lots of tutorial videos on IB if you need a better description of how to do this.
I'm someone who doesn't use Interface Builder for UI design; in my experience, you need to go either all-IB, or all-programmatic. To solve your particular problem, I think you need your musicGridView to be an instance or extension of UIScrollView.
This can be done in your custom viewController's loadView method - simply initialize it to a UIScrollView (and add things to it), instead of a plain old UIView.
However, as described above, this approach isn't compatible with an IB-centric approach, as is confirmed in the UIViewController Class Reference
All subclasses of UIViewController
should implement the loadView method
to set the view property unless you
load your view from a nib file.