Search code examples
objective-ccocoainterface-builderswiftiboutlet

Swift/Objective-C: How to call a view-controller-method from another class


Lets say I have a class called FooController. It will at some point in time call the method bar(str: String) owend by the second class BarController. BarController is a subclass of NSViewController and has an IBOutlet. This outlet is connected to a NSButton.

bar simply changes the text of the button to some string like "Example".

My first approach was to create a new instance of BarController and then calling the method.

var bc = BarController()
bc.bar("Example")

My problem is, that the new instance is not connectet to the interface and so the IBOutlet becomes nil.

func bar(str: String) {
    myButton.title = str // myButton is nil
}

Solution

  • 1) Connect the button to a property in a class that is instantiated at your application launch, for example your AppDelegate. Let us say you create a property called aButton. ---> Therefore you keep a track of your object

    AppDelegate.h
    
    @interface AppDelegate
    @property(weak) IBOutlet NSButton *aButton;
    @end
    
    AppDelegate.m
    @implementation AppDelegate
    -(void)applicationDidFinishLaunching:(NSNotification*)notification
    {
         BarController* controller = [BarController controllerForButton:aButton];
    }
    @end
    

    2) When you create your BarController object, create a class method that would set a property _button to aButton. --> Therefore your objects knows the adress of your button.

    BarController.h
    @interface BarController
    {
        NSButton *_button;
    }
    @end
    
    BarController.m
    @implementation BarController
    
    +(BarController*)controllerForButton:(NSButton*)button{
        return[[BarController alloc] initWithButton:button];
    }
    
    -(void)initWithButton:(NSButton*)button{
        self = [super init];
        if (self)
        {
            _button = button;
        }
    }