How does an NSView subclass communicate with the controller?

前端 未结 3 1579
野的像风
野的像风 2021-02-06 04:11

I am brand spanking new to Cocoa programming, and am still kind of confused about how things wire together.

I need a pretty simple application that will fire off a singl

相关标签:
3条回答
  • 2021-02-06 04:27

    First, your view needs a reference to the controller. This can be a simple iVar set at runtime or an outlet (designated by IBOutlet) connected at design time.

    Second, NSControl is a subclass of NSView, which provides the target/action mechanism machinery for free. Use that for target/action style controls. This provides a simple way of setting the reference to your controller (the target) and the method to call when fired (the action). Even if you don't use a cell, you can still use target/action easily (NSControl usually just forwards this stuff along to its instance of an NSCell subclass but doesn't have to).

    0 讨论(0)
  • 2021-02-06 04:36

    You could either add it as an IBOutlet like Joshua said, or you could use the delegate pattern.

    You would create a Protocol that describes your delegate's methods like

    @protocol MyViewDelegate
        - (void)doStuff:(NSEvent *)event;
    @end
    

    then you'd make your view controller conform to the MyViewDelegate protocol

    @interface MyViewController: NSViewController <MyViewDelegate> {
        // your other ivars etc would go here 
    }
    @end
    

    Then you need to provide the implementation of the doStuff: in the implementation of MyViewController:

    - (void)doStuff:(NSEvent *)event
    {
        NSLog(@"Do stuff delegate was called");
    }
    

    then in your view you'd add a weak property for the delegate. The delegate should be weak, so that a retain loop doesn't form.

    @interface MyView: NSView
    
    @property (readwrite, weak) id<MyViewDelegate> delegate;
    
    @end
    

    and then in your view you'd have something like this

    - (void)mouseDown:(NSEvent *)event
    {
        // Do whatever you need to do
    
        // Check that the delegate has been set, and this it implements the doStuff: message
        if (delegate && [delegate respondsToSelector:@selector(doStuff:)]) {
            [delegate doStuff:event];
        }
     }
    

    and finally :) whenever your view controller creates the view, you need to set the delegate

     ...
     MyView *view = [viewController view];
     [view setDelegate:viewController];
     ...
    

    Now whenever your view is clicked, the delegate in your view controller should be called.

    0 讨论(0)
  • 2021-02-06 04:44

    you can also use a selector calling method, define two properties in custom class:

    @property id parent;
    @property SEL selector;
    

    set them in view controller:

    graph.selector=@selector(onCalcRate:);
    graph.parent=self;
    

    and call as:

    -(void)mouseDown:(NSEvent *)theEvent {
        [super mouseDown:theEvent];
        [_parent performSelector:_selector withObject:self];
    }
    
    0 讨论(0)
提交回复
热议问题