Question

So I am using a simple delegate to access a function from a main view controller when a button is pressed on a subview that is generated as an overlay on top of the main view. For some reason the function that is defined in the source view controller isn't being executed. I have done this 100 times and feel like I am just missing something stupid. Here is the code how come this isn't working?

Source ViewController's.h:

#import <UIKit/UIKit.h>
#import "ProfileSettingsViewController.h"
#import "ImageViewer.h"

@interface ProfileViewController : UIViewController <UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate, subViewDelegate>

Source viewController.m:

#import <Parse/Parse.h>
#import <QuartzCore/QuartzCore.h>
#import "ImageViewer.h"
#import "ProfileViewController.h"

@interface ProfileViewController () <UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate, subViewDelegate>

@end

//where the ImageViewer object is defined    
@implementation ProfileViewController
{
    NSMutableArray *dataArray;
    ImageViewer *loadImageViewer;
}

//where the UIView is initialized
- (void) handleImageTap:(UIGestureRecognizer *)gestureRecognizer
{
    if ([gestureRecognizer view] == _profilePic)
    {
        loadImageViewer = [ImageViewer alloc];
        [loadImageViewer loadImageIntoViewer:self imageToLoad:_profilePic.image];
    }
    else if ([gestureRecognizer view] == _coverPhoto)
    {

    }
}

Destination View's.h

#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>

@protocol subViewDelegate
-(void)photoFromSubview:(id)sender;
@end

@interface ImageViewer : UIView

@property (nonatomic, assign) id <subViewDelegate> delegate;
@property (nonatomic, copy) UIImage *mainImage;
@property (nonatomic, copy) UIViewController *parentView;

- (void)fromCameraRoll;
- (void)takePhoto;
- (void)removeImageViewer;
- (void)captureImage:(id)sender;
- (void)uploadPhoto:(id)sender;
- (UIImage *)addBackground;
- (ImageViewer *)loadImageIntoViewer:(UIViewController *)superView imageToLoad:(UIImage *)imageToLoad;

@end

Destination View's.m

#import "ImageViewer.h"

@implementation ImageViewer : UIView

//synthesize properties
@synthesize mainImage = _mainImage;
@synthesize parentView = _parentView;

//initialize the image viewer
- (ImageViewer *)loadImageIntoViewer:(UIViewController *)superView imageToLoad:(UIImage *)imageToLoad
{
    //create a new view with the same frame size as the superView
    ImageViewer *imageViewer = [[ImageViewer alloc] initWithFrame:superView.view.bounds];
    _mainImage = imageToLoad;
    _parentView = superView;

    //if something's gone wrong, abort!
    if(!imageViewer)
    {
        return nil;
    }

    //add all components and functionalities to the program
    UIImageView *background = [[UIImageView alloc] initWithImage:[imageViewer addBackground]];
    background.alpha = 0.85;
    [imageViewer addSubview:background];
    [imageViewer addSubview:[imageViewer addImageToView:_mainImage superView:superView.view]];
    [imageViewer addSubview:[imageViewer addButtonToView:(superView.view.bounds.origin.x + 10.0) yPos:(superView.view.bounds.origin.x + 10.0) buttonAction:@selector(back:) buttonTitle:@"Back"]];
    [imageViewer addSubview:[imageViewer addButtonToView:(superView.view.bounds.origin.x + 10.0) yPos:((superView.view.center.y/2) + 270.0) buttonAction:@selector(captureImage:) buttonTitle:@"Camera"]];
    [imageViewer addSubview:[imageViewer addButtonToView:(superView.view.bounds.origin.x + 105.0) yPos:((superView.view.center.y/2) + 270.0) buttonAction:@selector(uploadPhoto:) buttonTitle:@"Upload"]];
    [imageViewer addSubview:[imageViewer addButtonToView:(superView.view.bounds.origin.x + 200.0) yPos:((superView.view.center.y/2) + 270.0) buttonAction:@selector(rotatePhoto:) buttonTitle:@"Rotate"]];
    [superView.view addSubview:imageViewer];

    return imageViewer;
}

//call delegate method
- (void)captureImage:(id)sender
{
    [self.delegate photoFromSubview:self];
}

I have screwed something up haven't I?

Was it helpful?

Solution

The best way to debug this is to use breakpoints and see what gets invoked, and what doesn't (and check if your delegate is properly set). Of the top of my head, I would say you either forgot the set the delegate or possibly an outlet if you're using IB.

Edit: Ok, It seems to me now that your delegate property is in the wrong class. That property should be in your subview, and when creating that subview from your superview, you should set the delegate properly, something like this:

mySubview.delegate = self;

OTHER TIPS

It looks like in your ProfileViewController.h you are missing a declaration of ImageViewer

@property (nonatomic, weak)  ImageViewer *imageViewer;

And in your ProfileViewController.m you need to set the delegate.

self.imageViewer.delegate = self;

You need to set the destination delegate to self.

ImageViewer *imageViewer = [[ImageViewer alloc] initWithFrame:superView.view.bounds];
imageViewer.delegate = self;

When you have a UIView that loads its self after you hace initialized the object and called the load method you set the delegate by using.

imageViewer.delegate = superView;

Where imageView is the newly initialized view not to be confused with the object self (self.delegate = superView isn't the same) and where superView is the is the parent view creating the UIView.

Now my last question would be is there a better way to do what I have done? I feel like I have over complicated the situation.

I am having the exact same problem in exactly same scenario. After doing some brain storming i found the issue and resolved successfully.

The problem is scope of UIView object. So to resolve this create a global object of view in .h file and use it as your target object.

@interface profilePageViewController : parentViewController<PhotoUploadViewDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate,ConnectionsDelegate>
{
    PhotoUploadView *photoUploadView;

And it will work very sure, You can also try to by printing the object to and you will find two different objects.One at time of init and other in delegate call.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top