Calling an instance method from another class - objective-c

Consider this view setup :
I have a view controller which switches between a set of sub views. Each sub view is a UIView subclass with custom code. To switch views I use a switch statement which allocs the new view as the currentview. This works very well.
I'm now in a position where I have a view (MainMenu) with a sub view (PopUp) that contains a UITableView. The PopUp view is shown and hidden via instance methods of the MainMenu.h class. Lets call the methods showPopUp and hidePopUp.
When a user selects an item from the UITableView they then have to manually close the containing (PopUp) view by clicking the close button, which is bound to the hidePopUp method.
What should happen when a user selects an item in the UITableView is that the hidePopUp method should be triggered automatically.
How do I trigger the hidePopUp instance method via the didSelectRowAtIndexPath of the UITAbleView? Is this a job for an app delegate, or perhaps NSNotificationCenter? I've tried such things as calling
[[[UIApplication sharedApplication] delegate] closePopUp];
from the didSelectRowAtIndexPath to no avail...
Thanks in advance, it's probably something simple I'm missing. Programming with a flu is difficult!

There are a few ways to accomplish this, such as notifications or working through a singleton like the app delegate (although the use of the singleton [anti]pattern is not without controversy). Personally, I'd use delegation.
Something like:
#protocol PopUpDelegate
#optional
- (void)Popup:(YourPopUpClass *)popUp didEndWithData:(NSData *)blah;
#end
You could then implement this protocol in your MainMenu, assign it as Popup's delegate, have the Popup call the delegate's method when the close button is pushed, and close the popup from there.
Here's a great post on how to implement delegates if you choose to go this route: How do I create delegates in Objective-C?

Related

initialise nsviewcontroller which is implicitly called by nswindowcontroller

In a cocoa application i have created a storyboard with one nswindowcontroller to control window and onew nsviewcontroller to control view. That view contain several buttons. The implicit call flow of these methods is like:
instantiating nswindowcontroller from calling method
implicit call to init method of nswindowcontroller
implicit call to init method of nsviewcontroller
Now what i required to display some buttons from those several buttons on behalf of some parameters which is needed to send to the nsviewcontrollerclass. Can anyone please help me to achieve this.
You will need to keep outlets to these buttons in your view controller. And depending on your business logic, you need to ensure, which button should be shown/hidden.
You can write a setUpButtons() function in the view controller. And the view controller can have an attribute or attributes to hold the parameter/s. Whenever you set these parameters, you need to call the setUpButtons() method to do the required showing/hiding of buttons.

Get Tab Selection Event from UITabBar in a ViewController

The structure of my MainStoryboard is:
->Tab Bar Controller -> Navigation Controller -> View Controller (Search)
The behaviour I want to have is that when the user re-selects the Search tab, the UIScrollView on it scrolls to the top. I am unsure how to get the event from the TabBarController, however.
I've been looking at a lot of stuff about UITabBarDelegate, particularly:
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
I have, not quite managed to get this to work properly though. I am very unsure about how to go about setting the delegate (assuming that is the way it's done). I've tried hooking it up in IB, but it wouldn't let me. I also tried to get the UITabBar from the AppDelegate (after looking at some seemingly-related answers).
Any pointers will be greatly appreciated (unless they're null).
UITabBar *aTabBar = [UITabBarItem alloc] init];
....Any other modifications you want to make to aTabBar....
[aTabBar setDelegate:self]
Don't forget to add "<UITabBarDelegate>" to the "#interface" part of whatever object you're trying to designate as the delegate.
For my own code, I usually use some object that isn't the application delegate (as the app delegate is usually meant for application level events like "application is suspending" or "application is coming back into foreground"). If you add "<UITabBarDelegate>" to your Search view controller, make sure that whatever you do with the "didSelectItem" method is applicable only to the Search view controller. Otherwise instantiate some different object if you want to do actions on various view controllers based on which tab bar item is being displayed.

Cocoa Touch Subclass UIScrollView and Custom Delegate Still Receive Parent Delegate Messages

I have subclassed UIScrollView and added my own custom delegate (currently called delegate). I want to add functionality such as notifying a user when an image is tapped and perform loading like the table view.
However, If I define my own custom delegate, I can not set the parent delegate for responding to events such as scrollViewDidScroll (I want the subclass to receive these events). Should I rename the delegate in my subclass? Should I be using super.delegate in some form? Does a standard exist for doing this? Thanks!
Does your custom delegate just extend the methods of UIScrollViewDelegate? If it does, just override the methods -scrollViewDidScroll etc and forward the messages onto your own delegate.
Maybe I've misunderstood your question, so I apologize if I have.

Cocoa Touch UITabBar action on tab switch

I have a UITabBar with a number of UITabBarItems. I've assigned a different view controller to each of these.
I want to load some data etc., when each button is clicked. Therefore I will like to know where to put that code? I tried implementing viewWillAppear and viewDidLoad in the view controller but those didn't get called.
I know that when you assign a delegate to a UINavigationController, the component UIViewController delegate methods are not called. It seems likely that the same is true of UITabBarController.
I would try implementing the UITabBarControllerDelegate protocol and implementing the tabBar:didSelectViewController: method.
Are you sure your custom controllers inherit from UIViewController?
Don't forget the signature for the viewWillAppear is viewWillAppear:animated:
I'm working off the beta 5 right now, and it works just fine (I'm also using a TabBar).
Write your code in viewdidappear function.but i didn't try

Class Design for delegate, outlets, and mouse events

Here's a simplification:
I have an application with several buttons. If it is the first time the application is launching, I want to do some special things. In my AppController class, which is a delegate of NSApp, I use the delegate method -applicationDidFinishLaunching: to perform the test. After I've detected that it is the first time, I first want to access some IBOutlets. Then, I'd like to be able to get mouse events for each button, so that I can do other things.
I can't figure out want to do with the classes. I'd like to make a new class (FirstLaunch) for the first launch, but I'm not sure what to call from AppDelegate. Also, to get mouse events, shouldn't I be a sublass of the buttons, and considering that I have multiple buttons, I'm confused. I could probably tackle these issues one-by-one, but taken all together, they're confusing me.
Broken down, I need to access & manipulate IBOutlets I have set in IB, determine when buttons are clicked (and which button was clicked). I'd like to be able to do this from another class so as to not clutter up the AppDelegate.
Thanks for the help!
To be more clear, what I'm actually trying to do is to use Matt Gemmel's MAAttachedWindow to put up a help bubble by a button. When the button is clicked clicked, the bubble disappears and another one is put somewhere else. The bubbles will be attached to controls in the main window.
I'm guessing you want to show some additional user interface on the first launch? If it's a separate window, I'd advise creating a subclass of NSWindowController. Add a new NIB file for the first-run user interface to your project and change the class of the File's Owner object to FirstLaunch. Control-drag a wire from the File's Owner delegate onto the window to connect it with the window outlet.
You create IBOutlets by adding an instance variable to the class. If your app will only run on Leopard or higher, it's better to declare your outlets like this:
#interface FirstLaunch : NSWindowController {
NSTextField *myTextField;
}
#property (nonatomic, retain) IBOutlet NSTextField *myTextField;
#end
In Interface Builder, you'll control-drag a wire from the File's Owner onto the control to associate it with that outlet. Make sure that you release your reference to each IBOutlet in your class's dealloc method (if you're not using garbage collection) or else your app will leak memory.
Buttons send action messages when they're clicked, so you'll need to provide an action method for the button to call. You do that by declaring a method with a signature like this:
- (IBAction)myButtonClicked:(id)sender;
In Interface Builder, you'll control-drag a wire from the button onto your window controller and choose the myButtonClicked: method.
To make all this work, you'll need to create an instance of the window controller and tell it to load the NIB file at runtime. So, in your AppDelegate class, when you've determined that this is the first launch, you'll do this:
FirstLaunch *firstLaunchController = [[FirstLaunch alloc] initWithWindowNibName:#"nameOfNibFile"];
[firstLaunchController show:self];
You'll probably want to keep the reference to the window controller in an instance variable instead of a local variable like I've done here. And, depending on your application, it may make more sense to show this as a sheet. But once you've made it this far, you'll be able to figure out how to do that on your own.
Then, I'd like to be able to get mouse events for each button, so that I can do other things.
Don't worry about the mouse. There may not even be a mouse (think of the ever-popular tablet-Mac rumor).
I'd like to make a new class (FirstLaunch) for the first launch, but I'm not sure what to call from AppDelegate.
You make your own methods here. You'll probably make it a singleton*; then, you'll implement a method named something like runFirstLaunchPanel:, which will be an action method (more on those in a moment):
- (IBAction) runFirstLaunchPanel:(id)sender;
Instantiate the object in the nib, then, from your app delegate, call the action method with nil as the sender.
The reason to put the object in your nib and make the method an action method is that this makes it easy to hook up a menu item to it, so that the user can re-run the first-launch panel at a later time. (For example, if it's a Starting Points window, you might connect the New menu item to this action instead of the default one.)
*Yes, I've seen the articles about singletons, and I agree with them. In a case like this, it's OK.
Also, to get mouse events,
This is the wrong way of thinking about it. What you need to do is set your button up to send a message to your controller to make the controller (probably AppDelegate) do something. The message you want the button to send is an action message.
Implement an action method in the object that owns the nib containing the window with the buttons. Declare this method in the class's header, then connect the button to it in IB by right-clicking on your controller and dragging from the correct action method's circle to the button.
This is called the target-action paradigm, and it insulates controller responsibilities (doing things) from the views that ordered them. Because each action method does only one thing, you can have a button, a menu item, and even another controller (your app delegate, above) send the same action message, and the receiving controller won't have to care which control is sending the action, because it already knows what it has to do.
shouldn't I be a sublass of the buttons,
No. You very rarely create subclasses of anything other than NSObject (or, for model objects in Core Data, NSManagedObject) in Cocoa.
Note that I said “rarely”, not “never”. You will have to make the occasional subclass, especially if you want to create custom or customized views and cells (and, maybe, customized windows). However, subclassing is not necessary in Cocoa to the degree that (I hear) it is in some other frameworks on other platforms.
and considering that I have multiple buttons, I'm confused.
The target-action paradigm means you don't have to create one button subclass per button. One controller class implements all the actions, and the stock buttons, because you've hooked them up in IB, simply tell the controller “do this”.
Broken down, I need to access & manipulate IBOutlets I have set in IB,
Probably not. At least, not as much as you think you do.
determine when buttons are clicked (and which button was clicked).
Nope. The buttons will worry about being clicked; you just worry about setting them up to send, and then responding to, their action messages.