Why is my method not being called?
My UIViewController should be calling a method in my UIView called myMethod.
It only works on the inital UIView viewDidLoad.
After the view is loaded, I can't call the "myMethod" from someOtherMethod. And I don't understand why? XCode recognizes that the method exists and the method is exposed in my header.
MyViewController.h
#import “MyView.h”
#interface MyViewController : UIViewController {
MyView *mv;
}
MyViewContoller.m
#import “MyView.h”
- (void)viewDidLoad
{
mv = [[MyView alloc] initWithFrame:self.view.frame];
[self.view addSubview:mv];
//THIS WORKS IF CALLED FROM viewDidLoad
[mv myMethod];
}
- (void) someOtherMethod {
//THIS DOESN’T WORK IF CALLED LATER
[mv myMethod];
}
MyView.h
- (void) myMethod;
MyView.m
- (void) myMethod {
NSLog(#"My Method");
}
Related
// userprofileform.h(viewcontroller)
#class UserProfileForm;
#protocol UserProfileFormDelegate <NSObject>
- (void) UserProfileFormDelegateReload: (UserProfileForm *) sender;
#end
#interface UserProfileForm : OTSFormViewController <UIActionSheetDelegate>
#property(nonatomic,assign) id <UserProfileFormDelegate> delegate;
#end
//userprofileform.m
#import "UserProfileForm.h"
#implementation UserProfileForm
- (void)endFlow:(id)sender {
[self.delegate UserProfileFormDelegateReload:self];
[self.navigationController popViewControllerAnimated:YES];
}
//shopprofilecontroller.h
#import "UserProfileForm.h"
#interface ShopProfileController : OTSViewController <UserProfileFormDelegate>
#end
//shoprofilecontroller.m
#implementation ShopProfileController
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.title = #"Business";
UserProfileForm * userProfileForm = [[UserProfileForm alloc] init];
userProfileForm.delegate = self;
}
-(void)UserProfileFormDelegateReload:(UserProfileForm *)sender{
NSLog(#"delegates fired");
}
but the delegate method is not called upon popping the UserProfileForm.
I don't know why is it not firing. I have tried NSNotifications and it did not fire too.
I just tried your code and it worked fine.
The only thing I changed was at the end of viewDidLoad() of ShopProfileController I put the following line:
[userProfileForm endFlow:self];
So your delegate implementation should be correct.
Set a breakpoint within your endFlow() method, I bet its not getting called.
I have 2 classes named as:
InputFunctionView
BaseTemplateView
I created a method cancelStickerPreviewButtonPressed inside InputFunctionView class that I want to call it from BaseTemplateView class.
Here is my code:
InputFunctionView.h
#import <...>
#class InputFunctionView;
#protocol InputFunctionViewDelegate <NSObject>
...
#end
#interface InputFunctionView : UIView <...> {
}
- (void)cancelStickerPreviewButtonPressed:(id)sender;
#end
InputFunctionView.m
- (void)cancelStickerPreviewButtonPressed:(id)sender {
// This part doesn't work when called from other class. Why?
NSLog(#"cancel sticker preview");
[self.previewCancelButton removeFromSuperview];
[_stickerPreviewView removeFromSuperview];
}
BaseTemplateView.h
#import <...>
#interface BaseTemplateView : UIViewController
#end
BaseTemplateView.m
#import "InputFunctionView.h"
- (void) MethodA {
InputFunctionView *IFV = [[InputFunctionView alloc]init];
[IFV cancelStickerPreviewButtonPressed:nil];
}
My question is why in InputFunctionView.m method cancelStickerPreviewButtonPressed this below part doesn't work? previewCancelButton and stickerPreviewView are supposed to be removed from its superview but no. What am I missing?
// This part doesn't work when called from other class. Why?
NSLog(#"cancel sticker preview");
[self.previewCancelButton removeFromSuperview];
[_stickerPreviewView removeFromSuperview];
Might be help you using Class method
In InputFunctionView.h
+(void)yourMethod;
In InputFunctionView.m
+(void)yourMethod
{
NSLog(#"Your method called");
}
In BaseTemplateView.h
- (void) MethodA { // Need to import InputFunctionView.h
[InputFunctionView yourMethod];
}
Happy coding...
I am quite new to IOS, and I was working with delegates to call a method in parent ViewController.
ViewControllerRegistration.h
#protocol RegistrationViewControllerDelegate;
#interface ViewControllerRegistration : UIViewController
#property (nonatomic, weak) id<RegistrationViewControllerDelegate> delegate;
- (IBAction)registerNewUser:(id)sender;
#end
// 3. Definition of the delegate's interface
#protocol RegistrationViewControllerDelegate <NSObject>
-(void)loginResult:(NSString*)loginData;
#end
ViewControllerRegistration.m
- (void)registerNewUser:(id)sender {
id<RegistrationViewControllerDelegate> strongDelegate = self.delegate;
// Our delegate method is optional, so we should
// check that the delegate implements it
if ([strongDelegate respondsToSelector:#selector(loginResult:)]) {
[strongDelegate loginResult: #"#WHY YOU NOT BEING CALLED?"];
}
Parents:
ViewController.h
#import "ViewControllerRegistration.h"
#interface ViewController : UIViewController <GPPSignInDelegate,FBSDKLoginButtonDelegate,RegistrationViewControllerDelegate>
#end
ViewController.m
#implementation ViewController
#synthesize signInButton;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
ViewControllerRegistration *detailViewController = [[ViewControllerRegistration alloc] init];
// Assign self as the delegate for the child view controller
detailViewController.delegate = self;
}
//Local Strategy
- (IBAction)navigateToLocalSignUpNavBtn:(id)sender {
[self performSegueWithIdentifier:#"SegueRegisterUserAction" sender:self];
}
// Implement the delegate methods for RegistrationViewControllerDelegate
-(void)loginResult:(NSString*)loginData{
NSLog(#"I am called");
//^Above is never printed. That means delegate method is never called
}
Please note, my parent view controller is embedded in a navigation controller.
The delegate method is never called. Tried debugging, but in vain.
The view controller you are creating in viewDidLoad isn't the same one that you will be segueing to. It's another instance that will be deallocated at the end of the method. You need to access the correct instance in prepareForSegue and set the delegate there.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"SegueRegistrationUserAction"]) {
[(ViewControllerRegistration *)segue.destinationViewController setDelegate:self];
}
}
Yesterday, I had explained this in length on this thread. Please take a look and let me know if you have any specific question post that. I hope this would help you.
I have a UIView subclass with a delegate property. In the init method, I set
self.delegate = nil.
The view also has a button, so in the init method, I also set the target of the button to be self.delegate, which is nil:
[myButton addTarget:self.delegate action:#selector(buttonAction) forControlEvents:UIControlEventTouchUpInside]
In the UIViewController that sets up my UIView subclass, I call a method in the UIView that sets the UIView's self.delegate to the UIViewController. When I click the button, the change in target seems to be reflected.
I am wondering how this ends up working, as my understanding is that addTarget:action:forControlEvents takes an id as the target, and pointers should be pass by value in Obj-C. Thus, I am pretty confused about why the originally nil-valued pointer was updated after the addTarget method was already called.
The right way to do that is declaring a protocol for your view, which will delegate for button's tap action, i.e.
YourView.h
#class YourView;
#protocol YourViewDelegate
#optional
- (void)customView:(YourView *)view didSelectButton:(id)button;
#end
#interface YourView : UIView
//...
#property (weak, nonatomic) id <YourViewDelegate> delegate;
#end
YourView.m
#interface YourView()
#end
#implementation
- (id)init
{
if (self = [super init]) {
//...
[self setup];
}
return self;
}
- (void)awakeFromNib
{
//...
// setup logic when this view created from storyboard
[self setup];
}
- (void)setup
{
[myButton addTarget:self
action:#selector(buttonTapped:)
forControlEvents:UIControlEventTouchUpInside];
}
- (void)buttonTapped:(id)sender
{
if (self.delegate && [self.delegate respondsToSelector:#selector(customVIew:didSelectButton)] {
[self.delegate customView:self didSelectButton:sender];
}
}
#end
Then, in your view controller implement YourViewDelegate category:
#interface YourViewController()
//...
#end
#implementation
- (void)viewDidLoad
{
[super viewDidLoad];
//...
self.yourView.delegate = self;
}
//...
- (void)customView:(YourView *)view didSelectButton:(id)button
{
//do your stuff
}
#end
Objective-C uses Dynamic binding. Method to invoke is determined at runtime instead of at compile time. Which is why it is also referred to as late binding.
Reference link -
https://developer.apple.com/library/ios/documentation/general/conceptual/DevPedia-CocoaCore/DynamicBinding.html
So what will be the delegate and which method is being called is defined at runtime.
Why is my delegate method only called in MainViewController and not in MapViewController?
LocationService.h
#protocol LocationServiceDelegate <NSObject>
#optional
- (void) currentLocation: (CLLocation*) location;
#end
#property (nonatomic, assign) id delegate;
LocationService.m
if ([delegate respondsToSelector:#selector(currentLocation:)])
{
[delegate currentLocation:newLocation];
}
Here the method get called (in MainViewController)
MainViewController.h
#import "LocationService.h"
#interface MainViewController : UIViewController <LocationServiceDelegate>
MainViewController.m
locationService = [[LocationService alloc] init];
locationService.delegate = self;
- (void) currentLocation: (CLLocation*) location
{
// some code, this method get called perfectly
}
And in my other class, the same procedure wont work
MapViewController.h
#import "LocationService.h"
#interface MapViewController : UIViewController <MKMapViewDelegate, LocationServiceDelegate>
MapViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
locationService =[[LocationService alloc] init];
locationService.delegate = self;
}
- (void)currentLocation:(CLLocation *)location
{
// this method does not get called
}
Cheers!
Are you setting delegate to nil somewhere as the code looks fine to me? Please use break pointer to see if it step into currentLocation method implementation in MapViewController.