Hiding buttons in a UIViewController from a UIView

2019-09-06 12:38发布

问题:

I have a UIView class that is loaded in to a UIViewController as a subview, to capture touches and draw them to the screen (a simple drawing app). I want to hide some buttons in the UIViewController when drawing begins. In the UIViewController (DrawingController.m) viewDidLoad method:

//init the draw screen
drawScreen=[[MyLineDrawingView alloc]initWithFrame:self.view.bounds];
[drawScreen setBackgroundColor:[UIColor clearColor]];
[self.view addSubview:drawScreen];

I have a method in the UIViewController (DrawingController.m) that is hiding my colour picker, brush size buttons etc that are present within the UIViewController. The hide method works fine when called from the same class (DrawingController.m). Basically when the -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event method is called within the UIView class (MyLineDrawingView.m) I am hoping to hide the buttons:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

    DrawingController *drawController = [[DrawingController alloc] init];
    [drawController hideDrawIcons];

}

I've added some logging to the hideDrawIcons method within the UIViewController and it is getting called, but all of my hiding code is not working:

self.undoBtn.hidden = YES;

I suspect this is because I am making a new instance of the UIViewController class with DrawingController *drawController = [[DrawingController alloc] init]; - but I'm not sure how to do things differently?

I have of course exposed the correct method in the DrawingController.h header file, to be able to call it from the UIView class (MyLineDrawingView.m):

-(void)hideDrawIcons;

Hopefully all of that makes sense, thanks in advance!

回答1:

You are right. You do not need to make create new instance of DrawingController. All you need yo have pointer of your DrawingController in your View class. If you want to know more about this technology you can read about Delegate pattern. If not, here is simple steps.

Add protocol in your MyLineDrawingView.h file ( or you can create separated file for it )

@protocol MyLineDrawingProtocol <NSObject>

-(void)hideDrawIcons;

@end

In your DrawingController.h

@interface DrawingController <MyLineDrawingProtocol>
{
    // members ....
}

@end

In your MyLineDrawingView.h

@interface MyLineDrawingView
{
    // members ....
}
@property (nonatomic,weak) id <MyLineDrawingProtocol> delegate;

@end

Set delegate for your view

//init the draw screen
drawScreen=[[MyLineDrawingView alloc]initWithFrame:self.view.bounds];
drawScreen.delegate = self;// self is a pointer of DrawingController
[drawScreen setBackgroundColor:[UIColor clearColor]];
[self.view addSubview:drawScreen];

And last change. Call hideDrawIcons method for delegate ( DrawingController )

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    if ( [self.delegate respondsToSelector:@selector(hideDrawIcons)] )
        [self.delegate hideDrawIcons];

}


回答2:

Yes, you're creating a new copy of the view controller in your view, which is wrong. What you want is to have a reference to the actual view controller. Here's how you can do it:

In MyLineDrawingView, declare a property:

@property (nonatomic, weak) DrawingController *drawingController;

Note that it is declared as weak, which prevents a retain cycle.

When instantiating the view:

drawScreen=[[MyLineDrawingView alloc]initWithFrame:self.view.bounds];
drawScreen.drawingController = self; // pass the actual view controller instance to the drawScreen object.

Finally, in MyLineDrawingView:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
     [self.drawingController hideDrawIcons];
}