Advertise here




Advertise here

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

How do I populate a UIImage via button press on another view?

kryekrye Posts: 362Registered Users
edited September 2011 in iOS SDK Development
In my iPad app, I have a main view. Via a button press, a detail view is displayed (modal view). On that detail view I have an image view. Pressing a tab bar button displays a popover with a a custom view of images to choose from. (They are really just buttons).

I would like to populate the UIImageView on the Detalview with image "x" based on the button press from the popover.

So my question is, how do I tell the detailview to populate the UIImageView from a button press from the popover view?

I though I could do something like this in the popoverviewcontroller.m:

I have an action wired to each of the buttons in the popover view:
- (IBAction)buttonOnePressed {
		
	DetailViewController *detailView = [[DetailViewController alloc] init];
	
	detailView.myImageView.image = [UIImage imageNamed:@"imageOne.png"];
	
}

- (IBAction)buttonTwoPressed {
		
	DetailViewController *detailView = [[DetailViewController alloc] init];
	
	detailView.myImageView.image = [UIImage imageNamed:@"imageTwo.png"];
	
}


But it doesn't load the image.

Sorry about the crude mockup, but maybe a picture would better explain it....

5313135290_282cf55b5e_b.jpg

Thanks
Post edited by krye on
<a href="http://ineedcoffeetocode.com"; target="_blank">iNeedCoffeeToCode.com</a> <a href="http://rescuemyclassicmac.com"; target="_blank">RescueMyClassicMac.com</a> <a href="http://ryemac3.net"; target="_blank">RyeMAC3.net</a>

Replies

  • kryekrye Posts: 362Registered Users
    edited January 2011
    Think I may be onto something. Shouldn't populate one view's images from another controller. Bad design. Instead, call a method:

    In my detail view, added methods:
    - (void)loadButtonOneImage {
    	
    	UIImage *stockImage = [UIImage imageNamed: @"imageOne.png"];
    	[obverseImage setImage:stockImage];	
    	
    }
    
    - (void)loadButtonTwoImage {} //etc, etc
    - (void)loadButtonThreeImage {} //etc, etc
    

    Now just need to figure out howe to call that method from the popoverviewcontroller.
    - (IBAction)buttonOnePressed {
    		
    	DetailViewcontroller *detailView = [[DetailViewcontroller alloc] init];
    	
    	[detailView loadButtonOneImage];   //does not work???????
    	
    }
    
    <a href="http://ineedcoffeetocode.com"; target="_blank">iNeedCoffeeToCode.com</a> <a href="http://rescuemyclassicmac.com"; target="_blank">RescueMyClassicMac.com</a> <a href="http://ryemac3.net"; target="_blank">RyeMAC3.net</a>
  • biztybizty Posts: 13Registered Users
    edited January 2011
    krye wrote: »
    Think I may be onto something. Shouldn't populate one view's images from another controller. Bad design. Instead, call a method:

    In my detail view, added methods:
    - (void)loadButtonOneImage {
    	
    	UIImage *stockImage = [UIImage imageNamed: @"imageOne.png"];
    	[obverseImage setImage:stockImage];	
    	
    }
    
    - (void)loadButtonTwoImage {} //etc, etc
    - (void)loadButtonThreeImage {} //etc, etc
    

    Now just need to figure out howe to call that method from the popoverviewcontroller.
    - (IBAction)buttonOnePressed {
    		
    	DetailViewcontroller *detailView = [[DetailViewcontroller alloc] init];
    	
    	[detailView loadButtonOneImage];   //does not work???????
    	
    }
    


    I would use protocols and delegation. Your popoverviewcontroller should have a pointer to the detailViewcontroller called delegate. Then you can call methods on the detailViewcontroller. You use a protocol to make sure that your detailViewcontroller implements the needed methods to update the imageview. Another thing is that you don't need a method for every image. Why not just have one method and then pass a index or something.

    You can read about delegation here:
    https://developer.apple.com/library/ios/#documentation/General/Conceptual/DevPedia-CocoaCore/Delegation.html
    And about protocols here:
    https://developer.apple.com/library/ios/#documentation/General/Conceptual/DevPedia-CocoaCore/Protocol.html%23//apple_ref/doc/uid/TP40008195-CH45-SW1

    So in the header of your PopoverViewController you shold have something like this
    @protocol PopoverViewControllerDelegate <NSObject>
    - (void) popoverViewController: (PopoverViewController *) popController didSelectImageAtIndex:(int) index;
    @end
    

    And have the instance variable delegate:
    id <PopoverViewControllerDelegate> delegate;
    

    That you should declare as a property also:
    @property (nonatomic, assign) id<PopoverViewControllerDelegate> delegate;
    

    And of course synthesize:
    @synthesize delegate;
    

    In your detailViewController when you create the popOverviewController, you should set the delegate to self. So you would have something like this:
    PopoverViewController *popController = [[PopoverViewController alloc] init];
    [popController setDelegate:self];
    

    Then you should implement the didSelectImageAtIndex method in the detailViewController:
    - (void) popoverViewController: (PopoverViewController *) popController didSelectImageAtIndex:(int) index {
    	switch (index) {
    		case 0:
    			UIImage *stockImage = [UIImage imageNamed: @"imageOne.png"];
    			[obverseImage setImage:stockImag];
    			break;
    		case 1:
    			UIImage *stockImage = [UIImage imageNamed: @"imageTwo.png"];
    			[obverseImage setImage:stockImag];
    			break;
    		case 2:
    			UIImage *stockImage = [UIImage imageNamed: @"imageThree.png"];
    			[obverseImage setImage:stockImag];
    			 break;
    		default:
    			break;
    	}
    }
    

    The last thing you should do is to call the method when the user taps on a image in your popoverViewController. So just do something like this:
    - (IBAction)buttonOnePressed {
    	if (delegate && [delegate respondsToSelector:@selector(popoverViewController:didSelectImageAtIndex:)])
    		[delegate popoverViewController:self didSelectImageAtIndex:0];
    }
    

    Notice that I check to see if is has a delegate and if the delegate implements the method before calling it.

    I hope you get the idea. :)
  • timle8n1timle8n1 Posts: 414Registered Users @ @
    edited January 2011
    krye wrote: »
    DetailViewcontroller *detailView = [[DetailViewcontroller alloc] init];
    

    This line will ALWAYS create a new instance of DetailViewController not access an existing one - which is want you want.

    You could pass in the instance of DetailViewController to your popover - but IMHO that is bad design.

    You should make your DetailViewController the delegate of your PopOverController and then implement
    - (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
    

    in your DetailViewController.
  • kryekrye Posts: 362Registered Users
    edited January 2011
    Thanks for the replies, still a little lost on delegation. I'll have to read up on it a bit more. Can't seem to get it to work.

    Thanks.
    <a href="http://ineedcoffeetocode.com"; target="_blank">iNeedCoffeeToCode.com</a> <a href="http://rescuemyclassicmac.com"; target="_blank">RescueMyClassicMac.com</a> <a href="http://ryemac3.net"; target="_blank">RyeMAC3.net</a>
  • kryekrye Posts: 362Registered Users
    edited January 2011
    OK, now I'm officially confused. I thought the DetailViewController would be the delegate.

    Also, the part about:
    - (void) popoverViewController: (PopoverViewController *) popController didSelectImageAtIndex:(int) index {
    	switch (index) {
    		case 0:
    			UIImage *stockImage = [UIImage imageNamed: @"imageOne.png"];
    			[obverseImage setImage:stockImag];
    			break;
    		case 1:
    			UIImage *stockImage = [UIImage imageNamed: @"imageTwo.png"];
    			[obverseImage setImage:stockImag];
    			break;
    		case 2:
    			UIImage *stockImage = [UIImage imageNamed: @"imageThree.png"];
    			[obverseImage setImage:stockImag];
    			 break;
    		default:
    			break;
    	} 
    

    wouldn't work since the popover view is just a xib with some buttons on it. It's not a table view with indexes.


    I've been messing with is code and searching online for over 3 hours now and still, I'm totally lost as to how this is supposed to work. Who is the delegate supposed to be? The one with the method who's called, or the one who does the calling?
    <a href="http://ineedcoffeetocode.com"; target="_blank">iNeedCoffeeToCode.com</a> <a href="http://rescuemyclassicmac.com"; target="_blank">RescueMyClassicMac.com</a> <a href="http://ryemac3.net"; target="_blank">RyeMAC3.net</a>
  • kryekrye Posts: 362Registered Users
    edited January 2011
    bizty wrote: »
    ....

    Dang! I'm at my wits end with this! This should be so simple I know, but I've spent the past 5-6 hours trying to figure out how to make a delegate method. Must be missing something. I just don't get it. I've looked at a few tutorials, and it looks like I'm following the rules, but it just doesn't work!

    Maybe the whole thing is backwards.

    In my case, wouldn't the delegate be the detailview since it's the one that's going to populate the UIImageView? The popovercontroller, when a button is pressed, should send a method to the detail view as to what to do.
    <a href="http://ineedcoffeetocode.com"; target="_blank">iNeedCoffeeToCode.com</a> <a href="http://rescuemyclassicmac.com"; target="_blank">RescueMyClassicMac.com</a> <a href="http://ryemac3.net"; target="_blank">RyeMAC3.net</a>
  • kryekrye Posts: 362Registered Users
    edited January 2011
    I found a useful guide HERE.

    My code compiles without error. I think I got it right, but still nothing. My "load the imageview" method is not called by the popover viewcontroller.
    <a href="http://ineedcoffeetocode.com"; target="_blank">iNeedCoffeeToCode.com</a> <a href="http://rescuemyclassicmac.com"; target="_blank">RescueMyClassicMac.com</a> <a href="http://ryemac3.net"; target="_blank">RyeMAC3.net</a>
  • biztybizty Posts: 13Registered Users
    edited January 2011
    krye wrote: »
    In my case, wouldn't the delegate be the detailview since it's the one that's going to populate the UIImageView? The popovercontroller, when a button is pressed, should send a method to the detail view as to what to do.

    The delegate should be the detailview yes! The what I'm doing when I set the delegate property of popoverviewcontroller to self.

    Hard to say what you need to do in order to get it working. Should work if you follow my description.
  • kryekrye Posts: 362Registered Users
    edited January 2011
    bizty wrote: »
    The delegate should be the detailview yes! The what I'm doing when I set the delegate property of popoverviewcontroller to self.

    Hard to say what you need to do in order to get it working. Should work if you follow my description.

    Thanks, I''ll give it another go.
    <a href="http://ineedcoffeetocode.com"; target="_blank">iNeedCoffeeToCode.com</a> <a href="http://rescuemyclassicmac.com"; target="_blank">RescueMyClassicMac.com</a> <a href="http://ryemac3.net"; target="_blank">RyeMAC3.net</a>
  • kryekrye Posts: 362Registered Users
    edited January 2011
    Got it, after many hours & days of reading up on delegates, etc. Also, Chapter 4 of this $25 course was a big help: iOS SDK Tutorials | iPhone SDK Developing iPad Applications from Lynda.com

    Figured I post everything for anyone else who is killing themselves figuring out delegates:

    main view controller .h
    #import "ImagePickerPopoverController.h"
    //add to interface
    <ImagePickerPopoverControllerDelegate>
    
    //add method
    - (void)didClickButton:(id)sender;
    

    main view controller .m
    //delegate method fired on behalf of the popover vier controller
    - (void)didClickButton:(NSString *) buttonName {
    	
    	UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:nil message:@"This totally works!!!" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
    		
    		[alert show];
    }
    
    //method to display the popover controller
    - (IBAction)setImageButtonPressed:(id)sender {
    	
    	if ([self.popoverController isPopoverVisible]) {
    		
    		[self.popoverController dismissPopoverAnimated:YES];
    		
    	} else {
    	
    		ImagePickerPopoverController* ipPopover = [[ImagePickerPopoverController alloc] init];
    		popoverController = [[UIPopoverController alloc]
    										 initWithContentViewController:ipPopover];
    		
    		//this is one of the lines that I was missing before that was KILLING me!!!!!
                    ipPopover.delegate = self;
    		
    		[ipPopover release];
    		
    		self.contentSizeForViewInPopover = CGSizeMake(320.0, 485.0);
    		
    		[popoverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
    	}
    }
    

    popover controller .h
    @protocol ImagePickerPopoverControllerDelegate
    - (void)didClickButton:(NSString *) buttonName;
    
    //after @interface
    id<ImagePickerPopoverControllerDelegate> delegate;
    
    @property (nonatomic, assign) id<ImagePickerPopoverControllerDelegate> delegate;
    
    //action on the popover controller that will fire the delegate method in the main view controller
    - (IBAction)aButtonPressed:(id)sender;
    

    popover controller .m
    @synthesize delegate;
    
    //IBAction on the popover controller, 
    - (IBAction)aButtonPressed:(id)sender {
    
           //just getting the button's name and storing it fore now (Il'll need it later)
    	UIButton *temp = (UIButton *) sender;
    	NSString *buttonName = [temp titleForState:UIControlStateNormal];
    							
    	if (delegate != nil) {
    		[delegate didClickButton:buttonName];
    	}
    }
    

    Thanks again for all your help.
    <a href="http://ineedcoffeetocode.com"; target="_blank">iNeedCoffeeToCode.com</a> <a href="http://rescuemyclassicmac.com"; target="_blank">RescueMyClassicMac.com</a> <a href="http://ryemac3.net"; target="_blank">RyeMAC3.net</a>
  • kryekrye Posts: 362Registered Users
    edited January 2011
    Would I be able to do some kind of FOR statement in my save method? Something like:
    for ([myObject.name isEqual:@"buttonOne"]) {
    			
    			[myObject setValue:@"test" forKey:@"imageChosen"];
    }
    

    I basically want to say "Hey, for the row in my database table that has "buttonOne" saved under the 'name' attribute, go ahead and save the string"test" under the 'imagesChosen' attribute.

    I'm just finding it hard to save data to a row in the database table without using a table view and table view cells in the app.

    So when saving data, writing to attributes, etc, how do you target a specific row in the database table?
    <a href="http://ineedcoffeetocode.com"; target="_blank">iNeedCoffeeToCode.com</a> <a href="http://rescuemyclassicmac.com"; target="_blank">RescueMyClassicMac.com</a> <a href="http://ryemac3.net"; target="_blank">RyeMAC3.net</a>
  • mart0593mart0593 Posts: 6New Users
    edited September 2011
    krye wrote: »
    Would I be able to do some kind of FOR statement in my save method? Something like:
    for ([myObject.name isEqual:@"buttonOne"]) {
    			
    			[myObject setValue:@"test" forKey:@"imageChosen"];
    }
    

    I basically want to say "Hey, for the row in my database table that has "buttonOne" saved under the 'name' attribute, go ahead and save the string"test" under the 'imagesChosen' attribute.

    I'm just finding it hard to save data to a row in the database table without using a table view and table view cells in the app.

    So when saving data, writing to attributes, etc, how do you target a specific row in the database table?

    been reading you code and trying to follow. i've been stuck on a similar problem... would you happen to have to source code for download. i can't seem to get yours. thanks..... i'm sort of stuck.
  • mart0593mart0593 Posts: 6New Users
    edited September 2011
    krye wrote: »
    Got it, after many hours & days of reading up on delegates, etc. Also, Chapter 4 of this $25 course was a big help: iOS SDK Tutorials | iPhone SDK Developing iPad Applications from Lynda.com

    Figured I post everything for anyone else who is killing themselves figuring out delegates:

    main view controller .h
    #import "ImagePickerPopoverController.h"
    //add to interface
    <ImagePickerPopoverControllerDelegate>
    
    //add method
    - (void)didClickButton:(id)sender;
    

    main view controller .m
    //delegate method fired on behalf of the popover vier controller
    - (void)didClickButton:(NSString *) buttonName {
    	
    	UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:nil message:@"This totally works!!!" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
    		
    		[alert show];
    }
    
    //method to display the popover controller
    - (IBAction)setImageButtonPressed:(id)sender {
    	
    	if ([self.popoverController isPopoverVisible]) {
    		
    		[self.popoverController dismissPopoverAnimated:YES];
    		
    	} else {
    	
    		ImagePickerPopoverController* ipPopover = [[ImagePickerPopoverController alloc] init];
    		popoverController = [[UIPopoverController alloc]
    										 initWithContentViewController:ipPopover];
    		
    		//this is one of the lines that I was missing before that was KILLING me!!!!!
                    ipPopover.delegate = self;
    		
    		[ipPopover release];
    		
    		self.contentSizeForViewInPopover = CGSizeMake(320.0, 485.0);
    		
    		[popoverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
    	}
    }
    

    popover controller .h
    @protocol ImagePickerPopoverControllerDelegate
    - (void)didClickButton:(NSString *) buttonName;
    
    //after @interface
    id<ImagePickerPopoverControllerDelegate> delegate;
    
    @property (nonatomic, assign) id<ImagePickerPopoverControllerDelegate> delegate;
    
    //action on the popover controller that will fire the delegate method in the main view controller
    - (IBAction)aButtonPressed:(id)sender;
    

    popover controller .m
    @synthesize delegate;
    
    //IBAction on the popover controller, 
    - (IBAction)aButtonPressed:(id)sender {
    
           //just getting the button's name and storing it fore now (Il'll need it later)
    	UIButton *temp = (UIButton *) sender;
    	NSString *buttonName = [temp titleForState:UIControlStateNormal];
    							
    	if (delegate != nil) {
    		[delegate didClickButton:buttonName];
    	}
    }
    

    Thanks again for all your help.


    got it to work... the - (void)didClickButton:(id)sender; in the .h mainview does not need to be there. you added to the .h in the popover view.
  • mart0593mart0593 Posts: 6New Users
    edited September 2011
    where you able to set different button to one method? - (void)didClickButton:(NSString *) buttonName {

    i tried fooling around with if else if statement and UIButton tags. i can't seem to get it to work, as NSString does not have this property....

    any thoughts???

    s
    krye wrote: »
    Would I be able to do some kind of FOR statement in my save method? Something like:
    for ([myObject.name isEqual:@"buttonOne"]) {
    
    			
    
    [myObject setValue:@"test" forKey:@"imageChosen"];
    }
    

    I basically want to say "Hey, for the row in my database table that has "buttonOne" saved under the 'name' attribute, go ahead and save the string"test" under the 'imagesChosen' attribute.

    I'm just finding it hard to save data to a row in the database table without using a table view and table view cells in the app.

    So when saving data, writing to attributes, etc, how do you target a specific row in the database table?
  • NareshKondaNareshKonda HyderabadPosts: 1New Users Noob
    Once you've created the view, you need to set it's userInteractionEnabled property to true. Then you need to attach a gesture to it.

    imageView.userInteractionEnabled = true
    //now you need a tap gesture recognizer
    //note that target and action point to what happens when the action is recognized.
    let tapRecognizer = UITapGestureRecognizer(target: self, action: Selector("imageTapped:"))
    //Add the recognizer to your view.
    imageView.addGestureRecognizer(tapRecognizer)
    Now you still need the function, in this case, imageTapped:, which is where the action happens when the gesture is recognized. Mindmajix provides IOS training which makes you learn everything on the ios development and also rectify errors generated while developing.The gesture that was recognized will be sent as an argument, and you can find out which imageView was tapped from they gestures view property.

    func imageTapped(gestureRecognizer: UITapGestureRecognizer) {
    //tappedImageView will be the image view that was tapped.
    //dismiss it, animate it off screen, whatever.
    let tappedImageView = gestureRecognizer.view!
    }
Sign In or Register to comment.