0

I'm working on this project where I have a User class, my main view controller, and my SetUp control viewer (second control viewer). The User class has all the User properties, the main view controller creates the username/password then calls the SetUp view controller, and the SetUp view controller allows the user to enter additional information. I created a protocol in my SetUp view controller that calls a delegate method in my main view controller, after the user enters the additional information in the second view controller. The delegate methods returns a User object, but this is where I get lost. Where is the User object being returned? Its definitely not going where I want it to.

/**Main View Controller Implementation**/
#import "BWViewController.h"
#import "User.h"

@interface BWViewController ()

@end

@implementation BWViewController

@synthesize holdPassword,holdUserName,holdZone,holdArea;

-(IBAction)signUpButton
{

    firstUser = [[User alloc] init];
    firstUser.userName = userNameField.text;
    firstUser.password = passwordField.text;

    SetUp *setUpView = [[SetUp alloc] initWithNibName:Nil bundle:Nil];
    setUpView.delegate = self;

    User * bufferUser;

    bufferUser = [self presentViewController:setUpView animated:YES completion:^{ }];   /**This is where I want the User object from the delegate method return to**/


}

/**Delegate method in Main view controller**/

-(User*) sendUserInfoBack: (SetUp *) SetUpController didFinishWithZoneInfo:(NSString*)zoneInfo didFinishWithAreaInfo:(NSString*) areaInfo
{

    User*holdUser;
    holdZone = zoneInfo;
    holdArea = areaInfo;

    holdUser.userZone = holdZone;
    holdUser.userArea = holdArea;

    return holdUser;  /**return this to bufferUser object in method above**/
}

/**Second View controller Interface**/
#Import "User.h"
@class SetUp;

@protocol SetUpControllerDelegate <NSObject>

-(User*) sendUserInfoBack: (SetUp *) SetUpController didFinishWithZoneInfo:(NSString*)zoneInfo didFinishWithAreaInfo:(NSString*) areaInfo;

@property (weak,nonatomic) id<SetUpControllerDelegate>delegate;

@end


/**Second View controller implementation**/
-(IBAction)goToMainView:(id)sender
{
    NSString * neededZoneStore = Zone.text;
    NSString * areaStore = Area.text;

    User * user = [[User alloc] init];

    user.userZone = neededZoneStore;
    user.userArea = neededAreaStore;

    [self.delegate sendUserInfoBack:self didFinishWithZoneInfo:neededZoneStore didFinishWithAreaInfo:neededAreaStore];

    [self dismissViewControllerAnimated:YES completion:NULL];
}
2
  • Can you try to clarify exactly what you're trying to do as simply as possible? Commented Dec 10, 2013 at 3:27
  • @protocol SetUpControllerDelegate <NSObject> Sure. I'm trying to return a User object with the variables obtained in the SetUp view controller into the bufferUser object in my main view controller. Commented Dec 10, 2013 at 3:31

1 Answer 1

2
[self.delegate sendUserInfoBack:self didFinishWithZoneInfo:neededZoneStore 
    didFinishWithAreaInfo:neededAreaStore];

So, you probably never need to send self back to the delegate. The delegate already knows about self since the delegate instantiated an object.

You need to change your protocol to this:

-(void)sendUserInfoBack:(User*)user;

Then when you're ready to send this info back, you just call it like this:

[self.delegate sendUserInfoBack:user];

Now in the delegate class, you need to implement the method from the protocol:

-(void)sendUserInfoBack:(User*)user {
    //do stuff with user
}

For example, you have a holdZone and holdArea property, so you might write the method to look like this:

-(void)sendUserInfoBack:(User*)user {
    self.holdZone = user.userZone;
    self.holdArea = user.userArea;
    //then perhaps perform a segue, or whatever.
}

As I spend some time looking at your question, I think the problem is becoming clearer.

This line:

bufferUser = [self presentViewController:setUpView animated:YES completion:^{ }];

is wrong. You get your information back from the other class in the delegate method, sendUserInfoBack. And you shouldn't be calling this method except from the other class.

Your -(IBAction)signUpButton method should launch the view, and then that should be the end of the method. Now this view controller is just kind of in standby while the other view (which the first view controller is delegating) waits for its response.

When the newly launched view is finished, it closes itself out, and calls sendUserInfoBack on the original view. That's how you know that modal view is cleared and the original view can carry on performing functions.

So, anything you want to do after the other view is finished, that code should be placed in the sendUserInfoBack method.


It's important to keep in mind that although the delegate implements the delegate methods, the delegate is not the one calling the methods and can not do anything with the return values. A return value on a delegate method is to be used by the object calling the method.

For example, consider when you're implementing a UITableView. The cellForRowAtIndexPath has a return type: UITableViewCell. But where do you receive this return value? You don't. You override this delegate method so that you can customize how the cell is set up. The UITableView class, for which your view controller is a delegate overrides this method... but UITableView calls the method on its delegate, then uses the return value (the cell it just set up) to do more work on its own.

You would only want your sendUserInfoBack to have a return value if you needed to do more work in the SetUpControllerDelegate class after that value returned.

For example, if we did:

- (BOOL)sendUserInfoBack:(User*)user;

Now the delegate that overrides this method can put some logic in to return either YES or NO depending on whatever... and we would then use it something like this in SetUpControllerDelegate:

if([self.delegate sendUserInfoBack:user]) {
    // everything's fine, we can dismiss view
    [self dismissViewControllerAnimated:YES completion:nil];
} else {
    // everything wasn't fine, we need to try again
    // pop up a UIAlertView perhaps try to get better info
}

This is just an example.

Sign up to request clarification or add additional context in comments.

6 Comments

-(void)sendUserInfoBack:(User*)user; why is this returning void? Shouldn't we return a User object?
I just updated my answer, added some clarity I think.
Ok I was unsure whether we could ever land in the signUpButton method again after calling the second view controller. I was hoping I could return where I left off in the signUpButton method.
For more clarity on delegate relationship, spend some time with UITableView and realize that all the tableView methods you override are the delegate methods that the UITableView class is calling on your view controller. Rather than thinking about what you need to do to get your table to look right, think about how your class is interacting with the TableView class and try imagining the work the TableView class is doing behind the scenes, interacting with the delegate methods you wrote.
@Brosef I made one last edit. Check my example of what you might do with sendUserInfoBack:.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.