Custom Delegate Does Not Receive a Call - iphone

My custom delegate does not receive a call. Here is my setup. ViewController has a SliderView object which is a subclass of UIScrollView:
SlideView.h
#import <UIKit/UIKit.h>
#protocol SlideViewDelegate <NSObject
#required
-(void) didTapImageData:(NSMutableArray*)imageData atIndex:(int)index;
#end
#interface SliderView : UIScrollView<UIGestureRecognizerDelegate> {
__weak id<SlideViewDelegate> slideViewDelegate;
}
#property (nonatomic, weak) id<SlideViewDelegate> slideViewDelegate;
#end
SlideView.m
#import "SliderView.h"
#implementation SliderView
#synthesize slideViewDelegate;
- (void) handleTap:(UITapGestureRecognizer *)recognizer{
NSLog(#"tapped");
[[self slideViewDelegate] didTapImageData: imageData atIndex:0 ];
}
ViewController.h
#interface ViewController : UIViewController <
UIScrollViewDelegate,
SlideViewDelegate>{
SliderView *thumbGalleryView;//delegate and reference are set in XCode
}
ViewController.m
#import "ViewController.h"
#implementation ViewController
-(void)didTapImageData:(NSMutableArray*) imageData atIndex:(int)index{
NSLog(#"NOT WORKING HERE");
}
So ViewController never receives a call at the method above. The thumbGalleryView is linked to ViewController and delegate is set to ViewController too. SlideView's handleTap is printing message fine but [[self slideViewDelegate] didTapImageData: imageData atIndex:0 ]; is ignored. Why?

You have set the delegate which is ivar of scroll view.
You have to set the slideViewDelegate to ViewController
Edited
Add IBOutlet
IBOutlet __weak id<SlideViewDelegate> slideViewDelegate;
Then from your xib connect slideViewDelegate to ViewController
Also remember to change the class of scroll view to SliderView
Added Image for clarity

Double-check where you set your delegate - if your delegate is nil at the time -handleTap: calls your -didTapImageData:atIndex: method, nothing will happen.

Related

Change UIImage view between two View Controllers

It's possible to change an image by clicking on a button inside an other View Controller?
I use this code in order to pass the data from the ViewController to the SecondViewController. I would want to add to the same button the commando to add an image to the SecondViewController... Excused my poor question...
ViewController.h
#import <UIKit/UIKit.h>
#import "SecondViewController.h"
#interface ViewController : UIViewController <SecondViewControllerDelegate> {
IBOutlet UITextField *userNameTextField;
}
#property (nonatomic, strong) UITextField *userNameTextField;
#end
ViewController.m
#import "ViewController.h"
#import "SecondViewController.h"
#interface ViewController ()
#end
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"to2"]){
SecondViewController *viewController = segue.destinationViewController;
viewController.delegate = self;
}
}
- (void)done:(NSString *)name{
[self dismissViewControllerAnimated:YES completion:nil];
NSLog(#"Back in first ViewController, metod Done, with name=%#",name);
userNameTextField.text=name;
}
#end
SecondViewController.h
#import <UIKit/UIKit.h>
#protocol SecondViewControllerDelegate <NSObject>
-(void) done:(NSString*)someText;
#end
#interface SecondViewController : UIViewController {
IBOutlet UITextField *someText;
IBOutlet UIButton *returnButton;
id delegate;
}
#property (nonatomic, assign) id <SecondViewControllerDelegate> delegate;
#property (nonatomic, strong) UITextField *someText;
- (IBAction)returnButtonPressed:(id)sender;
#end
SecondViewController.m
#import "SecondViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
#synthesize someText;
#synthesize delegate = _delegate;
- (IBAction)returnButtonPressed:(id)sender {
[self.delegate done:someText.text];
}
#end
Here is one way that should work for you:
Just set up an NSNotification in your ViewController with the image. Trigger the notification in the other viewController when the button is pressed.
in your image's view controller:
//in ViewDidLoad:
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(changeTheImage) name:#"CHANGE_THE_IMAGE" object:nil];
//then elsewhere in the class:
- (void)changeTheImage {
//change your image here
}
//and in your dealloc, make sure you add this, or it will keep "observing"
[[NSNotificationCenter defaultCenter] removeObserver:self];
Then in the button view controller:
//have this as your button action (or add the line to your button action)
- (IBAction)yourButtonWasPressed:(id)sender {
[[NSNotificationCenter defaultCenter]postNotificationName:#"CHANGE_THE_IMAGE" object:self];
What's the mean to change another UIViewController. because when you click on current UIViewController that's mean the current is on top and visible. what you called another can only be overlap inactive or it's does not exist right now.
So if you want somehow to change the UIImage from another UI, the simplest way is to hold the UIImage or image file name in a global store area such as your AppDelegate class, file. when click change the global area content. and in the ui for image show you can add some code in
- (void)viewWillAppear:(BOOL)animated {
//read and change UIImage content from global store
}
is it what you want ?

How to call a method from a UIViewController thats already on the UINavigationController stack

I have a UIViewController on a UINavigationStack and from this UIView I load another view not onto the stack but as a subview. This view that I load is just a preferences view for the app that I overlay onto what ever is showing.
i.e.
myViewController <- on the stack button touch loads as a subview to myViewController
+ prefrencesViewController
My question is, is there a way to call a method thats in myViewController from prefrencesViewController? I am trying to use delegates and protocols but its not working, so I am hoping there is either an easy way to do this I don't know about yet or maybe I could get some help with my delegate/protocol...
This is what my code looks like for delegate and protocol set up
//prefrencesViewController.h
#protocol GetPrefrencesViewControllerDelegate <NSObject>
-(void)reloadViewFromSavedPrefrences;
#end
//delegates and protocols
#property (nonatomic, weak) id <GetPrefrencesViewControllerDelegate> delegate;
//prefrencesViewController.m
//delegates and protocols
#synthesize delegate;
//.. inside button action
[[self delegate] reloadViewFromSavedPrefrences];
//myViewController.h
#import "prefrencesViewController.h"
#interface myViewController : UIViewController <UITabBarDelegate, GetGUIEncodedData, GetPrefrencesViewControllerDelegate> {
// prefrencesViewController set up
prefrencesViewController *pvc;
#property (strong, nonatomic) prefrencesViewController *pvc;
//myViewontroller.h
#synthesize pvc;
- (void)viewDidLoad
{
//..
[pvc setDelegate:self];
}
//Delegate and prefrences.. Saved pressed reload the view here.
-(void)reloadViewFromSavedPrefrences {
NSLog(#"WORKED");
}
any help would be greatly appreciated
I'm not sure that you are following the steps that I will present below but if you don't here is the example.
PresentedViewController.h
//import stuff
#protocol PresentedViewControllerDelegate <NSObject>
-(void)methodThatSouldBeImplementedByOtherController; //you can add params
#end
#interface PresentedViewController : UIViewController {
//instance variables
}
#property (nonatomic, assign(week for ARK)) id<PresentedViewControllerDelegate>delegate
//public methods here
PresentedViewController.m
#implementation PresentedViewController
#synthesize delegate;
//method implementation here
-(IBAction)buttonThatWillCallTheDelegate:(id)sender {
if([self.delegate respondsToSelector:#selector(methodThatSouldBeImplementedByOtherController)]) {
[self.delegate methodThatSouldBeImplementedByOtherController];
}
}
ControllerThatWillPresent.h
#interface ControllerThatWillPresent : UIViewController <PresentedViewControllerDelegate> {
//instance variables
}
//some methods maybe
ControllerThatWillPresen.m
#implementation ControllerThatWillPresen
-(void)methodThatWillShowTheVC {
PresentedViewController *vc = [PresentedViewController alloc] init]; //initWithNibname...
vc.delegate = self;
//presentVc, pushVc, addChild ...
}
-(void)methodThatSouldBeImplementedByOtherController {
//do stuff in delegate method
}

IOS setting a custom delegate

I'm working through the IOS HelloWorld example and I have a question regarding setting the delegate for a TextField. In the example it was as easy as control-dragging from the TextField to the ViewController. But now say I wanted to create a custom class to act as my delegate as so:
#import <Foundation/Foundation.h>
#interface SweetAssDelegate : NSObject <UITextFieldDelegate>
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField;
#end
#import "SweetAssDelegate.h"
#implementation SweetAssDelegate
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField
{
NSLog(#"Calling Delegate");
[theTextField resignFirstResponder];
return YES;
}
#end
How can I set this class to be the delegate of the TextField? As far as I can tell there is not way to accomplish this through the GUI. I tried manually setting the delegation after window load with no success:
#import "ViewController.h"
#import "SweetAssDelegate.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UITextField *inputField;
#end
- (void)viewDidLoad
{
[super viewDidLoad];
SweetAssDelegate *foo = [[SweetAssDelegate alloc] init];
[self.inputField setDelegate:foo];
NSLog(#"Delegate: %#", self.inputField.delegate);
}
I actually receive some sort of memory exception when bringing up the keyboard? Any ideas? Thanks.
As a side question, where should I always use viewDidLoad to initialize any variables? I noticed that init was not being called???
Your delegate object, foo, is allowed to fall out of scope and is released at the end of viewDidLoad and by the time the keyboard comes up, it doesn't exist anymore. Make it an ivar (or property) of your view controller, or otherwise make sure that foo doesn't fall out of scope at the end of viewDidLoad.
Thus, it could be something like:
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UITextField *inputField;
#property (strong, nonatomic) SweetAssDelegate *foo;
#end
- (void)viewDidLoad
{
[super viewDidLoad];
self.foo = [[SweetAssDelegate alloc] init];
[self.inputField setDelegate:self.foo];
NSLog(#"Delegate: %#", self.inputField.delegate);
}
Your textfield delegate must have the implemented to be your textfield delegate I guess.
A delegate manages the communication between objects, which means your custom delegate must allow communication between objects and must provide methods, the textfield can work with...
Another example is a tableView:
You can make a custom delegate which implements the delegates and then calls some tableview related Methods...
Here this code might be interesting for you:
#interface myCustomDelegateForTextFields <UITextFieldDelegate>
#end
#implementation myCustomDelegateForTextFields
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
return TRUE;
}
#end
#implementation ViewController
myCustomDelegateForTextFields *txtfielddelegate = [[myCustomDelegateForTextFields alloc] init];
UITextField *whatever;
whatever.delegate = txtfielddelegate;
//your textfield now listens to the BOOL method in your custom delegate
#end
Is it that what u were looking for? :)
you can ofc pack the myCustomDelegateForTextField delegate in another class and call the class

EXD_BAD_ACCESS passing data back to delegate

I'm a relatively new iPhone developer and am making great progress building my 2nd iPhone app. In the app I'm building now I'm doing some code separation with some protocols and delegates so that I car re-use some of my code in a variety of places throughout my code.
Here's what I want to happen:
CITRootViewController creates an instance of a CITReportCreator class, passing itself as a property so that the reportCreator can open additional view controllers and such.
CITReportCreator class is declared as implementing the CITImageCaptureDelegate protocol, which is declared in the CITImageCaptureViewController file.
CITImageCaptureViewController defines the delegate protocol and has a method that passes back data and references to the child view controller so that CITReportCreator can interact with it's data, close the related XIB, etc.
I believe I'm getting the delegate and protocol established correctly, and verified that my 'delegate' object still contains data when it is called, but I'm getting a EXC_BAD_ACCESS method when my view controller tries to pass data back to the delegate in this line of code:
[self.delegate childViewControllerDidFinish:self];
Here's a good portion of the rest of my code. I had this working by using CITRootViewController as my delegate instead of the CITReportCreator class, but now that I'm separating the code, something has broke.
CITReootViewController.m (the view controller that calls the Report Creator)
//create a nrew report
-(IBAction)createReport:(id)sender {
CITReportCreator *report = [CITReportCreator alloc];
[report createNewReport:self];
}
CITReportCreator.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "CITImageCaptureViewController.h"
#interface CITReportCreator : NSObject <CITImageCaptureDelegate>
#property (strong, nonatomic) NSArray *imageList;
#property (nonatomic) NSInteger imageIndex;
-(int) createNewReport:(UIViewController *)parent ;
//Delegate Methods
-(void) childViewControllerDidFinish:(UIViewController*)viewController;
#end
And CITReportCreator.m
#import "CITReportCreator.h"
#implementation CITReportCreator
{
UIViewController *parentController;
}
#synthesize imageList;
#synthesize imageIndex;
-(int) createNewReport:(UIViewController *)parent
{
//store a reference to the parent view controller
parentController = parent;
// init code....
//head to the first image capture view
[self startImageCapture];
return 0;
}
-(int)startImageCapture
{
//pull the image name from the array of images
NSString *imageName = [imageList objectAtIndex:imageIndex];
//prep the image capture controller
CITImageCaptureViewController *capture = [[CITImageCaptureViewController alloc] initWithNibName:#"CITImageCaptureViewController" bundle:nil];
//Assign the capture controller's delegate
capture.imageName = imageName;
capture.delegate = self;
//Display the capture controller
[parentController presentModalViewController:capture animated:YES];
return 0;
}
//a break point set here never gets hit.
-(void) childViewControllerDidFinish:(UIViewController*)viewController;
{
[viewController dismissModalViewControllerAnimated:YES];
}
#end
And finally, the CITImageCaptureViewControllers
CITImageCaptureViewController.h
#import <UIKit/UIKit.h>
#protocol CITImageCaptureDelegate <NSObject>
-(void) childViewControllerDidFinish:(UIViewController*)viewController;
#end
#interface CITImageCaptureViewController : UIViewController
{
id<CITImageCaptureDelegate> delegate;
}
#property (nonatomic,assign) id<CITImageCaptureDelegate> delegate;
#property (nonatomic, assign) NSString *imageName;
//continue button pressed method
-(IBAction)continueButtonPressed:(id)sender;
#end
And the .m file
#import "CITImageCaptureViewController.h"
#interface CITImageCaptureViewController ()
#end
#implementation CITImageCaptureViewController
#synthesize navItem;
#synthesize imageName;
#synthesize delegate = _delegate; //i think this may be part of the problem
//cutting out initWithNibName, viewDidLoad, etc...
- (IBAction)continueButtonPressed:(id)sender
{
[self.delegate childViewControllerDidFinish:self];
}
#end
I find nothing with delegates and protocols all that simple, but I'm guessing I'm missing a small change somewhere. Can you help me head in the right direction?

XCode: Call action in main view from modal view

I am trying to call an action (changeMainNumber) in a main view controller from a modal view controller. The action should change the UILabel mainNumber to 2. In ViewController.h, I have:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController {
IBOutlet UILabel *mainNumber;
}
#property (nonatomic, retain) UILabel *mainNumber;
-(IBAction)changeMainNumber;
ViewController.m:
#import "ViewController.h"
#implementation ViewController
#synthesize mainNumber;
- (IBAction)changeMainNumber:(id)sender {
mainNumber.text = #"2";
}
The next view controller is the modal view controller.
ModalViewController.h:
#import <UIKit/UIKit.h>
#class ViewController;
#interface ModalViewController : UIViewController {
}
-(IBAction)callChangeMainNumber:(id)sender;
and ModalViewController.m:
#import "ModalViewController.h"
#implementation ModalViewController
- (IBAction)callChangeMainNumber {
ViewController *viewController = [[ViewController alloc] init];
[viewController changeMainNumber];
}
With this setup the app keeps crashing when callChangeMainNumber is called and I can't figure out what is wrong. Any help you can provide is appreciated!
The code you posted from your ModalViewController is not referencing your ViewController. You are creating a new one in your code. The best solution to your problem would be to make your ViewController a delegate to the ModalViewController.
So in your ModalViewController.h file you should have this code above your #implementation.
#protocol ModalViewControllerDelegate
- (void)shouldChangeMainNumber;
#end
Then in your #implementation of the header have:
#property (nonatomic,assign)IBOutlet id <ModalViewControllerDelegate> delegate;
Now in the .m file where you have your IBAction method, tell the delegate that you want it to change the main number.
- (IBAction)callChangeMainNumber {
[self.delegate shouldChangeMainNumber];
}
Then in your ViewController.m file you need to set yourself as the delegate of the ModalViewController, usually in viewDidLoad is a good place to put it. So create a property in your header for the ModalViewController first and synthesize it, then add this to viewDidLoad.
self.modalViewController.delegate = self;
and finally you need to implement the delegate method in your .m file somewhere
- (void)shouldChangeMainNumber {
mainNumber.text = #"2";
}