I am losing my default UIScrollViewdelegate methods when I subclass it - iphone

I try to subclass the UScrollview but it ends up losing the default UIScrollview delegate method.
#import <UIKit/UIKit.h>
#protocol myscrollviewDelegate <NSObject>
-(void) myscrollview_return;
#end
#interface myscrollview : UIScrollView <UIScrollViewDelegate> {
id<myscrollviewDelegate> delegate;
}
#property(nonatomic, assign) id<myscrollviewDelegate> delegate;
#end
(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
never get called when scroll.
what's wrong? Can I subclass the UIScrollview and add additonal delegate and at the same times keeping the original delegates??

You are not adding a property, but overriding it, as UIScrollView already has a delegate property. When you set a delegate using the new property, the reference will be stored in the instance variable you added, not in the private instance variable of the original UIScrollView.
My theory is that the implementation of UIScrollView accesses the instance variable without using the property. I haven't verified it, but try not adding a new ivar and overriding the delegate property.

You can do this without creating a second delegate property.
First, make your delegate protocol inherit from UIScrollViewDelegate:
#protocol myscrollviewDelegate <NSObject, UIScrollViewDelegate>
Then, declare the delegate property in your header for your class:
#interface myscrollview : UIScrollView <UIScrollViewDelegate>
#property(nonatomic, assign) id<myscrollviewDelegate> delegate;
And the key is to not synthesize the property, but rather make it dynamic in your implementation file.
#implementation myscrollview
#dynamic delegate;
...

This is because You implement the delegate methods with id id delegate; I hope so
so change the name of delegate. instead using delegate use other name like "delegateSomeClass" etc
Now the delegates method of UIscrollView calls
hope it will clear :)

Related

Access delegate methods of UIPageViewController when you've created a protocol

I'm using the UIPageViewController and I've made my own protocol like this:
#protocol MyDataDelegate <NSObject, UIPageViewControllerDelegate>
- (void)recieveData:(NSString *)theData;
#end
How can I set the delegate of UIPageViewController to self so I can use those delegate methods? The normal code for this would be self.delegate = self; but since I've made another delegate it gives me a warning "Assigning to 'id<MyDataDelegate>' from incompatible type 'PageScrollViewController *const_strong'" I want to set this to self so I can access the delegate methods of the UIPageViewController
Your subclass eclipses delegate property of UIPageViewController. Give your delegate property some other name, for instance: #property (nonatomic,weak) id myDelegate;
Have you declared your PageScrollViewController class to conform to MyDataDelegate? You can either do this in the main #interface declaration:
#interface PageScrollViewController : UIPageViewController <MyDataDelegate>
// ...
#end
Or in the class category in your .m file:
#interface PageScrollViewController () <MyDataDelegate>
// ...
#end

Trying to Implement Delegate Inheritance

I have a class called ToolbarView which is a subclass of UIView and basically creates a UIView that has a disappearing / reappearing UIToolbar on top. I also have a subclass of ToolbarView called DraggableToolbarView enables the user to drag the view around the screen.
I need to create a delegate for ToolbarView so it can notify another object / class of when the toolbar reappears and disappears. I also need to create a delegate for DraggableToolbarView so I can notify another object / class when the view is dragged. DraggableToolbarViews delegate will also need to notify another object / class of when the toolbar reappears and disappears.
So I decided to implement ToolbarViewDelegate, and have DraggableToolbarViewDelegate inherit from it and have its own method like following:
ToolbarView.h
#import <UIKit/UIKit.h>
#protocol ToolbarViewDelegate;
#interface ToolbarView : UIView <UIGestureRecognizerDelegate>
{
id <ToolbarViewDelegate> _toolbarViewDelegate;
}
#property(nonatomic, assign) id <ToolbarViewDelegate> toolbarViewDelegate;
#end
ToolbarView.m
#import "ToolbarView.h"
#import "ToolbarViewDelegate.h"
...
- (void) showBars
{
...
if (self.toolbarViewDelegate)
{
[self.toolbarViewDelegate toolbarViewWillShowToolbar:self];
}
...
}
- (void) hideBars
{
...
if (self.toolbarViewDelegate)
{
[self.toolbarViewDelegate toolbarViewWillHideToolbar:self];
}
...
}
ToolbarViewDelegate.h
#class ToolbarView;
#protocol ToolbarViewDelegate
#required
- (void) toolBarViewWillShowToolbar:(ToolbarView *)toolbarView;
- (void) toolBarViewWillHideToolbar:(ToolbarView *)toolbarView;
#end
DraggableToolbarView.h
#import "ToolbarView.h"
#protocol DraggableToolbarViewDelegate;
#interface DraggableToolbarView : ToolbarView
{
id <DraggableToolbarViewDelegate> _draggableToolbarViewDelegate;
}
#property(nonatomic, assign) id <DraggableToolbarViewDelegate> draggableToolbarViewDelegate;
#end
DraggableToolbarView.m
#import "DraggableToolbarView.h"
#import "DraggableToolbarViewDelegate.h"
...
- (void)drag:(UIPanGestureRecognizer *)sender
{
...
if (self.draggableToolbarViewDelegate)
{
[self.draggableToolbarViewDelegate draggableToolbarViewWillDrag:self];
}
...
}
...
DraggableToolbarViewDelegate.h
#import "ToolbarViewDelegate.h"
#class DraggableToolbarView;
#protocol DraggableToolbarViewDelegate <ToolbarViewDelegate>
#required
- (void) draggableToolbarViewWillDrag:(DraggableToolbarView *)draggableToolbarView;
#end
SomeViewController.h
#import <UIKit/UIKit.h>
#import "ToolbarViewDelegate.h"
#import "DraggableToolbarViewDelegate.h"
#interface SomeViewController : UIViewController <ToolbarViewDelegate, DraggableToolbarViewDelegate>
{
}
#end
SomeViewController.m
#import "DraggableToolbarView.h"
...
- (void) toolbarViewWillShowToolbar:(ToolbarView*)toolbarView
{
//NSLog(#"Toolbar Showed");
}
- (void) toolbarViewWillHideToolbar:(ToolbarView*)toolbarView
{
//NSLog(#"Toolbar Hidden");
}
- (void) draggableToolbarViewWillDrag:(DraggableToolbarView*)draggableToolbarView
{
//NSLog(#"Dragged");
}
...
[draggableToolbarView setDraggableToolbarViewDelegate:self];
...
When I do this only the DraggableToolbarDelegate methods are responding. However when I also do [drabbleToolbarView setToolbarViewDelegate:self] it works. I've tried doing each delegate separately without inheritence and it works fine so I believe the problem isn't in any other part of the code.
Anyone might know why? I figured by making the protocols inherit, I wouldn't also have to set the ToolbarViewDelegate for a DraggableToolbar object.
UPDATE: Added a lot more code
In your code, any given DraggableToolbarView instance has two properties to connect to delegates, one called toolbarViewDelegate which it inherits from its superclass, and one called draggableToolbarViewDelegate which is defined in DraggableToolbarView itself. You've got to set both of those if you want the controller to get all the delegate messages.
What you're trying to do is possible, however. You need to use the same property name in both your view classes, so that there is only one delegate connection for any instance.
First, change the name of the delegate in the superclass. (Note that you don't need, and indeed shouldn't bother, to declare an ivar for the property -- it's created by #synthesize.)
#interface ToolbarView : UIView <UIGestureRecognizerDelegate>
#property (nonatomic, assign) id <ToolbarViewDelegate> delegate;
#end
You will use the same property name in the subclass.
#interface DraggableToolbarView : ToolbarView
#property (nonatomic, assign) id <DraggableToolbarViewDelegate> delegate;
#end
This is allowed as long as the name of the backing ivar in the subclass is different than that of the superclass, e.g.,
// In superclass
#synthesize delegate;
// In subclass
#synthesize delegate = delegate_;
Now change all the delegate messages in the two view classes to use this one property:
- (void)showBars
{
if (self.delegate)
{
[self.delegate ...
- (void)drag:(UIPanGestureRecognizer *)sender
{
//...
if (self.delegate)
{
[self.delegate ...
Now you can send setDelegate: to a DraggableToolbarView and it will use the same delegate for the dragging methods and the show/hide methods.
Finally, a terminology/explanatory note. In response to your previous question, Caleb used the correct term for "stacked" protocols, and Richard did not. Protocols don't inherit from each other, but one protocol can adopt the other. The relationship is similar, but distinct. When an object conforms to a protocol, it promises to implement the methods declared in that protocol. No implementation comes along with the protocol. The same is true of one protocol adopting the other -- the methods are just declared to exist in both. When you write:
#protocol DraggableToolbarViewDelegate <ToolbarViewDelegate>
you are saying that any object which promises to implement DraggableToolbarViewDelegate's methods will also implement the methods from ToolbarViewDelegate. That's all that it means. Again, no implementation comes along with that promise.
In this case, that means that a DraggableToolbarView can expect its delegate to implement the methods in ToolbarViewDelegate.
You have not given the entire code, but from whatever is out here,
Make sure that
Your ToolBarView and its subclasses have an id <ToolBarViewDelegate> delegate as a property.
Your DraggableToolbarViewDelegate extends NSObject protocol.
and your other ViewController object conforms to delegate protocol and not the toolbarview.
Once your controller gives implementation of delegates methods and conforms to the protocol, set the delegate of view's object to self and then use delegate property set in the view to call these protocol methods.

protocol method is not being called by the delegate object

Another case of protocol method not being called - NO idea what am I doing wrong here...
Here is the code, omitting unnecessary info...
first header file: AccessNumber.h
#protocol AddItemDelegate <NSObject>
#required
- (void) processSuccessful: (BOOL)success;
#end
#interface AccessNumber : UIViewController <UITableViewDelegate, UITableViewDataSource, ABPeoplePickerNavigationControllerDelegate, UIAlertViewDelegate> {
id <AddItemDelegate> delegate;
}
#property (retain) id <AddItemDelegate> delegate;
#end
first .m file: AccessNumber.m - I am calling the protocol method from viewdidload just for testing purposes, it should basically get called from another method, but same thing for the sake of this convo (tried both of course)
#import "AccessNumber.h"
#import "History.h"
#synthesize delegate;
- (void)viewDidLoad
{
[super viewDidLoad];
....
[[self delegate] processSuccessful:YES];
}
second file header: History.h
#interface History : UIViewController <UITableViewDelegate, UITableViewDataSource, AddItemDelegate> {
....
}
method implementation in history.m
- (void) processSuccessful: (BOOL)success {
NSLog(#"SUCCESS");
}
Appreciate any help. Thanks!
In the code i don't see something like:
theAccessNumber.delegate = self;
You must set the History instance as the delegate property of the AccessNumber instance.
Regards.
The code seems a little bit funny but you are not telling your "AccessNumber" class who is his delegate, even though you are making the "History" class implement the protocol established by yourself (otherwise you would get a warning).
You have to set the delegate for the "AccessNumber" class like this when setting it up from within "AccessNumber.m":
self.delegate = historyInstance;
or like this when setting it up from within "History.m":
accessNumberInstance.delegate = self;
There are very vew situations where you should retain a delegate, normally your delagate will outlive the object. So change your property from retain to assign. And be sure you are setting the delegate. Where are you doing it? If your object really depends on it you should be passing it in the constructor (iniWithDelagate). Try doing a NSLog before calling the delagate method just to see if it isn't nil.

Making a delegate for a UIViewController

I've looked all over, and found many people with similar problems, but I still can't get my delegates working. I want to make a model view controller pop up, then call a method in the view that made the model view asking it to dismiss it. So I have this line:
mergeConfig *view = [[mergeConfig alloc] initWithNibName:#"mergeConfig" bundle:nil];
and I'm trying [view setDelegate:self]; as said to on apple's developer pages, but expectably my model view doesn't have a setDelegate method.
So what I want to know is, how do I get it so that I can set a delegate? And then once I do, does it just automatically pass calls to methods to methods in the parent view with the same name? Apple's pages didn't say what code to put in the model view controller.
You need to define a delegate on your custom view controller, as such:
#interface mergeConfig {
id delegate;
}
#property (nonatomic, assign) id delegate;
#end
#implementation mergeConfig
#synthesize delegate;
#end
Then, elsewhere in the class for your view controller you can invoke whatever methods you need on your delegate.
Personally I like to improve the above by defining a protocol that my delegates comply to, as follows:
#protocol MyDelegateProtocol
- (void)delegateMethod;
#end
#interface mergeConfig {
id<MyDelegateProtocol> delegate;
}
#property (nonatomic, assign) id<MyDelegateProtocol> delegate;
#end
#implementation mergeConfig
#synthesize delegate;
#end
If you simply need to dismiss the modal view controller, just call [self.parentViewController dismissModalViewControllerAnimated:YES]; at the appropriate time. No need for delegates unless you need to pass information back up the chain.

Can I Add a custom Delegate to a Custom CALayer

I am trying to add a delegate to a CALayer so I can know when the animation sequence is complete. It's animating 40 sublayers around the screen. Once I add the delegate as I do below, all the animation stops on the CALayer.
Here is my code:
#protocol NIArticlesLayerDelegate;
#interface NIArticlesLayer : CALayer {
id<NIArticlesLayerDelegate> delegate;
}
#property (nonatomic, assign) id<NIArticlesLayerDelegate> delegate;
#end
#protocol NIArticlesLayerDelegate <NSObject>
#optional
-(void)itemAtCenter:(id)item;
#end
Checking the CALayer Docs, CALayer already has a property called delegate which MUST be assigned to the owning view. Try changing the name?