today, i saw code that UIView's category reload respondsToSelector and forwardInvocation. i donot understand why do this. this code intent to unite UITableview style in iOS6 and iOS7. i konw resolveInstanceMethod and forwardInvocation can work togather to change function in runtime.
How to explain respondsToSelector and forwardInvocation. When ios call respondsToSelector?
i make a simple test,but it donot call respondsToSelector, the test code as follow:
#protocol MyViewDelegate <NSObject>//why cannot be <UIView>?
#optional
- (void)myViewDelegateMethod;
#end
#interface MyView : UIView
#property (nonatomic,weak) id<MyViewDelegate>delegate;
- (void)test;
#end
#implementation MyView
- (void)test{
NSLog(#"%s",__func__);
if ([self.delegate respondsToSelector:#selector(myViewDelegateMethod)]) {
[self.delegate myViewDelegateMethod];
}
}
#end
#implementation UIView (FunctionChain)
- (BOOL)respondsToSelector:(SEL)aSelector{
//when i call [myview test],can't execute this
return [super respondsToSelector:aSelector];
}
#end
Related
So I am calling delegate function but some how its not getting called, I tried everything from all the other similar threads but nothing works. It looks all good but the method is still not called. here is my code below -
So i created protocol like this -
AuthViewController.h
#class AuthViewController;
#protocol AuthViewControllerDelegate <NSObject>
- (void)updateNavigation:(NSString*)pageType
message:(NSString*)message;
#end
created a property -
#property (nonatomic, weak)id delegate;
And called the function in AuthViewController.m -
[self.delegate updateNavigation:#"xx" message:#"xx"];
Then in other class -
AssociateViewController.h
#interface AssociateViewController : UIViewController <AuthViewControllerDelegate>
#property (nonatomic, strong)AuthViewController *vc;
#End
AssociateViewController.m
First set the delegate in a button action or viewWillAppear(I tried both)-
self.vc = [[AuthViewController alloc] init];
self.vc.delegate = self;
And the here is the method which is somehow never called :( -
- (void)updateNavigation:(NSString*)pageType
message:(NSString*)message;
{
//method to do
}
Any help would be much appreciated. Thanks!
I have UIView, what called Popup and poping from UIViewContorller(ParentVC)
On UIView I have 4 buttons. When buttons is pressed, it needs to open new Controllers from(ParentVC). I am using Delegate, were is my mistake?
//Popup.h
#protocol PopupDelegate
#required
- (IBAction)stepOfRestoration:(id)sender;
- (IBAction)clientCall:(id)sender;
- (IBAction)readyTo:(id)sender;
- (IBAction)givePhone:(id)sender;
#end
#interface Popup : PSCustomViewFromXib
#property (nonatomic, assign) id <PopupDelegate> delegate;
#property (strong, nonatomic) IBOutlet UIView *view;
- (IBAction)stepOfRestoration:(id)sender;
- (IBAction)clientCall:(id)sender;
- (IBAction)readyTo:(id)sender;
- (IBAction)givePhone:(id)sender;
In .m i have this:
#synthesize delegate;
....
- (IBAction)stepOfRestoration:(id)sender {
[self.delegate buttonPressed];
}
And this is Parent .m
...
CGRect rect = CGRectMake(0,0,200,300);
Popup *popup1 = [[Popup alloc] initWithFrame:rect];
popup1.delegate = self;
....
-(void)buttonPressed {
[self performSegueWithIdentifier:#"infoSegue" sender:nil];
}
So were is my mistake?
You don't have a method called buttonPressed in your protocol, you need to call a method in your protocol, e.g.
Popup.m
- (IBAction)buttonPressed:(id)sender {
[self.delegate stepOfRestoration:sender];
}
Parent.m
- (IBAction)stepOfRestoration:(id)sender {
// some code
}
Link to long winded but hopefully helpful tutorial, good luck.
In your Parent .m, you must conform all the methods which are defined in protocol. In your Parent.m file, buttonPressed method is not present in protocol. So update the name of below method with buttonPressed as follow:-
Update below code at Popup.h while declaring PopupDelegate methods
- (IBAction)stepOfRestoration:(id)sender;
With
-(void)buttonPressed;
you shouldn't add IBAction methods in your protocol
instead add following methods corresponding each button action
//Popup.h
#protocol PopupDelegate
#required
- (Void)stepOfRestoration:(id)sender;
- (Void)clientCall:(id)sender;
- (Void)readyTo:(id)sender;
- (Void)givePhone:(id)sender;
#end
and call these protocol methods in corresponding button action methods
e.g. //Popup.m
- (IBAction)stepOfRestoration:(id)sender {
[self.delegate stepOfRestoration:sender];
}
and //Parent.m
-(Void)stepOfRestoration:(id)sender{
// code here
}
I'm trying to add this to my code
#implementation UIWebView(CustomScroll)
- (void) scrollViewDidScroll:(UIScrollView *)scrollView{
[self.delegate scrollViewDidScroll: scrollView];
}
#end
But getting "No known instance method for selector 'scrollViewDidScroll:'"
What am I missing here?
The UIWebViewDelegate protocol does not declare a method scrollViewDidScroll:. Hence, this is why you're getting the bad access error.
I'd recommend that you subclass UIWebView instead of trying to creating a category on it (yes, the docs recommend against subclassing... just don't override any of the methods it has, and it's safe).
On your subclass, you can either create a new protocol or simply overwrite the delegate property to also require that it conforms to `UIScrollViewDelegate (the later is shown below):
In Example:
// MyWebView.h
#import <UIKit/UIKit.h>
#interface MyWebView : UIWebView
#property (nonatomic, assign) id<UIWebViewDelegate, UIScrollViewDelegate> delegate;
#end
// MyWebView.m
#import "MyWebView.h"
#implementation MyWebView
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
/* As scrollViewDidScroll: is optional, you should check if the super class
responds to this method (it doesn't appear to now, but this may change in future) */
if ([[self superclass] instancesRespondToSelector:#selector(scrollViewDidScroll:)])
{
[super scrollViewDidScroll:scrollView];
}
/* Likewise, you should check if your own delegate responds to this selector */
if ([self.delegate respondsToSelector:#selector(scrollViewDidScroll:)])
{
[self.delegate scrollViewDidScroll:scrollView];
}
}
#end
i have created a delegate for my project the code of my main view is
VedantViewController.h
#protocol VedantDelegate;
#interface VedantViewController : UIViewController
{
id <VedantDelegate> delegate;
}
//some other outlets
#property(nonatomic, assign) id <VedantDelegate> delegate;
#protocol VedantDelegate <NSObject>
- (void)display:(NSString *)JSONResponse;
#end
VedantViewController.m
#synthesize delegate;
[delegate display:jsonResponse];
SecondViewController.h
#interface SecondViewController : UIViewController<VedantDelegate>
- (void)display:(NSString *)JSONResponse;
SecondViewController.m
- (void)display:(NSString *)string
{
}
but this code is not working properly
when i debug the code using breakpoints the code reaches the
[delegate display:abc];
but it does not calls display function in SecondViewController.m file
i think my code is right but some mistake that i can't recognize
let me explain you the flow of my project this could be the problem
by default the VedantViewController view is launched
after that when the show button is click it calls the SecondViewController view in the view these is list button that calls the function in VedantViewController this function then calls the delegate method that is [delegate display:jsonResponse];
Thanks in Advance,
Arun.
The view controller which is confirming with the protocol, should have this line in the viewDidLoad or anywhere you are making the object of that viewController
Add this line in SecondViewController.m
VedantViewControllerObject.delegate = self;
#protocol VedantDelegate;
#interface VedantViewController : UIViewController{
id<VedantDelegate> delegate;
}
//some other outlets
#property(nonatomic,assign) id<VedantDelegate> delegate;
#protocol VedantDelegate <NSObject>
-(void)displayAccounts:(NSString *)JSONResponse;
-(void)display:(NSString *)JSONResponse;
#end
and also set delegate to object of VedantViewControllerObject class as self in SecondViewController class and the object of VedantViewControllerObject class should be initialized and allocated.
vedantViewControllerObject.delegate = self;
In your VedantViewController.h file you declared method as below
-(void)displayAccounts:(NSString *)JSONResponse;
But you are calling it [delegate display:jsonResponse];
You just try to call
[delegate displayAccounts:jsonResponse];
And in SecondViewController.m
(void)displayAccounts:(NSString *)string{
}
There are some issues in your code:
set the delegate in second view controller
vedViewObject.delegate = self;
You added displayAccounts method in delegate and calling display method, that can cause issues. If that methods are not implemented in the delegate class.
Add if condition like: if(delegate)[delegate displayAccounts:jsonResponse];
I'm working with a custom delegate and protocol functionality.
I implemented my class like follows:
#protocol MyDelegate <NSObject>
#required
- (void)update;
#end
#interface MyHandlerClass : NSObject
{
id <MyDelegate>delegate;
}
#property (nonatomic, weak) id <MyDelegate>delegate;
#end
My implementation class looks like:
#implementation MyHandlerClass
#synthesize delegate = _delegate;
- (void)updateRequired: (id)sender
{
if(delegate)
{
[delegate update];
}
}
#end
And from another class I'm setting it like:
[sharedManager setDelegate:self];
But when the updateRequired is triggered it is showing as nil.
Then I added a setter method like:
- (void)setDelegate:(id<MyDelegate>)aDelegate
{
delegate = aDelegate;
}
Everything works fine !!!
Then I changed the updateRequired method (without custom setter) like:
- (void)updateRequired: (id)sender
{
if(_delegate)
{
[_delegate update];
}
}
It is also working fine !!!
I couldn't find why it is not worked for the first case and why it is worked for the other two cases ?
Please help me to find the issue, Thanks in advance
When you use
if(delegate)
You are pointing to the instance variable "delegate".
However, when you use
[sharedManager setDelegate:self]
This is setting the instance variable "_delegate" to "self".
Try this:
if (self.delegate) {
[self.delegate update];
}
You have inadvertently declared one ivar called delegate
id <MyDelegate>delegate;
and another ivar called _delegate
#synthesize delegate = _delegate;
Some suggestions...
don't declare the iVar separately from your #property declaration
don't #synthesize, since XCode 4.4 you don't have to. The compiler will autosynthesize and autocreate an iVar with leading underscore
always refer to you ivar via it's property, inside and outside of your class. Only exceptions are in init, dealloc and inside custom setters and getters.
So this is how your code should look
#protocol MyDelegate <NSObject>
#required
- (void)update;
#end
#interface MyHandlerClass : NSObject
#property (nonatomic, weak) id <MyDelegate>delegate;
#end
#implementation MyHandlerClass
- (void)updateRequired: (id)sender
{
if(self.delegate)
{
[self.delegate update];
}
}
#end
To access your delegate property in the updateRequired method, you can do it by either using the private variable _delegate or by using self.delegate. Because when you synthesize using delegate = _delegate, setters and getters are automatically created.
This line tells the compiler to create a setter and getter for delegate, and that they should use the ivar called _delegate. Without the = _delegate part, the compiler would assume that the property and ivar have the same name.