confused about delegate pattern - ios

I'm creating a custom UIView subclass (shareView) from a Nib.
I created a custom protocol for shareView like this:
#protocol sharePopupDelegate
#required
-(void)userPublishedContent;
-(void)userAbortedPublish;
#end
#interface shareView : UIView
{
id<sharePopupDelegate> delegate;
}
In my main.storyboard I created a custom UIViewController myViewController with a shareView view instance called "popup" inside.
So now I got
#property (weak, nonatomic) IBOutlet shareView *popup;
I would like now to delegate myViewController from shareView methods i declared, so I did
self.popup.delegate = self;
inside myViewController but the protocols' methods are not being called inside myViewController.
So i correctly see the shareView instance but cannot interface to its delegate.
Can you help me please?
Thanks in advance

Make sure that you have the protocol declared in myViewController.
For example
#interface MyViewController : UIViewCOntroller <sharePopupDelegate>

In this section of the code:
#interface shareView : UIView
{
id<sharePopupDelegate> delegate;
}
You are creating a strong reference to the delegate, which is not what you want most of the time. Change it to this:
#interface shareView : UIView
#property(weak, nonatomic) id<sharePopupDelegate> delegate;
The shareView class itself must have some way to know when a user publishes content. Maybe you have an action linked up to the shareView which calls a method in the shareView class. For examaple:
- (void)publishButtonTapped {
// some code
}
What you want to do is let the delegate know in that method, something like this:
- (void)publishButtonTapped {
// some code
[self.delegate userPublishedContent];
}
Then whatever action the user takes to cancel:
- (void)cancelButtonTapped {
// some code
[self.delegate userAbortedPublish];
}
Hope this helps.

Related

Delegate form UIView to UIViewController

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
}

Setting BOOL to "YES" in custom delegate

I've make a delegate so my two different view controllers can communicate and I'm stuck trying to set a BOOL to YES in my child view controller.
childViewController.h
#protocol pageTwoViewControllerDelegate;
#interface pageTwoViewController : UIViewController {
UIButton *takePhotoTransition;
}
#property (nonatomic, weak) id<pageTwoViewControllerDelegate> delegate;
#end
#protocol pageTwoViewControllerDelegate <NSObject>
- (BOOL)didPushTakePhoto;
#end
childViewController.m
...
- (IBAction)takePhotoTransition:(id)sender {
id<pageTwoViewControllerDelegate> strongDelegate = self.delegate;
if ([strongDelegate respondsToSelector:#selector(didPushTakePhoto)]) {
strongDelegate.didPushTakePhoto = YES; // ERROR: No setter method for 'setDidPushTakePhoto:' for assignment property
}
NSLog(#"Button push recieved");
}
How can I get past this error and set my BOOL to YES when my button is pushed?
The protocol is just telling everyone that knows about your class through the protocol, that the property anObject will be there. Protocols are not real, they have no variables or methods themselves
Try to modify your code to be like this, you are setting a non existence variable or property.
you have to implement new Class instead of id
your protocol will look like
#protocol pageTwoViewControllerDelegate <NSObject>
- (void)setdidPushTakePhoto:(BOOL)aBOOL;
- (BOOL)didPushTakePhoto;
#end
and your class.h will contain
#property (nonatomic, getter=get_didPushTakePhoto) BOOL didPushTakePhoto;
and your class.m will contain implementation
-(BOOL)didPushTakePhoto
{
return _didPushTakePhoto;
}
- (void)setdidPushTakePhoto:(BOOL)aBOOL{
_didPushTakePhoto=aBool;
}
You are getting confused between a method and a property.
The definition of your protocol "pageTwoViewControllerDelegate", says it should implement a method with name "didPushTakePhoto" which returns a BOOL value.
What you are trying to do is entirely different. You are trying to set a non-existent property. Whenever you are accessing something followed by a dot ".", that should be a property of the class to which that object belongs. The protocol you defined does not talk anything about the property.
So inside the if condition, you should be calling the method "didPushTakePhoto" on your delegate object, like below.
[strongDelegate performSelector:#selector(didPushTakePhoto)];
If you know for sure that your delegate implementations do have the protocol method implemented, then since you already cast self.delegate to strongDelegate which is declared as id, you don't need the if condition. You could directly call the method like below.
[strongDelegate didPushTakePhoto];
Hope this helps
Have you assigned the delegate of your ChildViewController belongs to ParentViewController?
Try this:
ParentChildViewController.m
#import "ChildViewController.h"
#interface ParentViewController () <ChildDelegate>
...
-(IBAction)btnClicked:(id)sender
{
ChildViewController *ctrl = [[ChildViewController alloc] init];
ctrl._delegate = self;
// do present childViewController or similar action here
}
- (void)didPushTakePhoto: (BOOL)result{
NSLog(#"result: %d",result);
}
ChildViewController.h
#protocol ChildDelegate
- (void)didPushTakePhoto: (BOOL)result;
#end
#interface pageTwoViewController : UIViewController {
UIButton *takePhotoTransition;
}
#property (assign, nonatomic) id _delegate;
#end
ChildViewController.m
...
- (IBAction)takePhotoTransition:(id)sender {
if ([self._delegate respondsToSelector:#selector(didPushTakePhoto:)]) {
[self._delegate didPushTakePhoto:YES];
// do dismiss here
}
}

iOS: delegate from child to parent view

Here is what I wish to do:
There is a parent ViewController. On parent's load, ChildVC is called which contains a UITableView.
Now on childView's table's didSelectRowAtIndexPath method, I wish to pass the selected cell content to parentView. And from parentView I wish to load a second viewController.
How do I do this by delegate?
Edited:
Child :
#class ViewController;
#protocol CustomViewControllerDelegate;
#interface CustomViewController : UITableViewController
{
AppDelegate *appDelegate;
id<CustomViewControllerDelegate> delegate;
}
#property(nonatomic, weak) id<CustomViewControllerDelegate> delegate;
#end
#protocol CustomViewControllerDelegate
-(void)didSelectRow:(NSString *)str;
#end
parent
#class CustomViewController;
#interface ViewController : UIViewController<CustomViewControllerDelegate> // i get the error here
{
AppDelegate *appDelegate;
}
On ChildVC declare a protocol:
#protocol ChildVCDelegate
- (void)didSelectCell:(SomeContent *)content;
#end
Also add the delegate:
#property (nonatomic, weak) id<ChildVCDelegate> delegate;
In the implementation of didSelectRowAtIndexPath, add:
if (_delegate) {
[_delegate didSelectCell:someContent];
}
In the parent view controller implement didSelectCell and when it creates/shows the ChildVC, set it as the delegate.
I'm not sure what kind of content you want to pass to the parent, so I represented it as SomeContent, but it can be whatever you want to pass.

Why can I not call a method from another class

I have a custom class (Packages) that is of form NSObject. I have many instances of this object. In initializing each of these instances, I pass self from my UIViewController names ViewController.
In the code for these packages, I would like to call a method from ViewController.
-(void)toThisView:(UIView *)someView
{
[imagesToRender addObject:someView];
[self.mainImageView addSubview:someView];
}
and in Packages.m
I have
- (UIView *)handleTapFrom:(UITapGestureRecognizer *)sender
{
[view2 toThisView:sender.view]; // Error No visible #interface for 'UIViewController' declares the selector 'toThisView:'
}
where view2 is UIViewController *view2 and its being set as view2 = object via the init method of this classes
- (id)initWithPath:(NSString *)path andObject:(NSObject *)object
Why am I getting this error:
No visible #interface for 'UIViewController' declares the selector 'toThisView:'
if view2 is your custom type object then you can simply do this :
[(YourCustomClass *)view2 toThisView:sender.view];
import YourCustomClass. in viewController.
It sounds like you have a class named ViewController which is a subclass of UIViewController.
It also sounds like you have an instance variable named view2 which you declared like this:
#implementation Packages {
UIViewController *view2;
}
or possibly like this:
#interface Packages : NSObject
#property (nonatomic, strong) UIViewController *view2;
You need to declare view2 to be a ViewController, not a UIViewController. In other words, declare it like this:
#implementation Packages {
ViewController *view2;
}
or like this:
#interface Packages : NSObject
#property (nonatomic, strong) ViewController *view2;
I think you need to add
-(void)toThisView:(UIView *)someView
To your viewController.h file, otherwise it won't be visible from any other class.
1st import your custom class in viewController.
create an object of the class.
Call method simply like this.
[object toThisView:YourPrameter];
Before calling also declare this method in your class .h file like this
-(void)toThisView:(UIView *)someView;

Trigger method in parent uiviewcontroller from uibutton in uiscrollview

I have a uibutton inside a uiScrollview inside a uiviewcontroller. When I click the button I want to be able to call a method in the uiviewcontroller.
I have the following action on my button that calls a method within my uiscrollview:
[categoryButton addTarget:self action:#selector(categoryButtonWasClicked:) forControlEvents:UIControlEventTouchUpInside];
But this just calls a method within my uiscrollview (which I will still keep). How do I then call a method in the viewcontroller??
Thank you for any help you can provide.
enter code hereTry doing something like this
#import <UIKit/UIKit.h>
#protocol myUIScrollViewProtocol <NSObject>
-(void)buttonWasPressInScrollView:(id)sender;
#end
#interface MyUIScrollView : UIScrollView
#property (weak, nonatomic)id myDelegate;
#end
Create a subclass of UIScrollView and add a delegate then assign your UIViewController as the delegate and implement the "buttonWasPress.." method in it.
Then from the categroryButtonWasClicked method in your uiScrollView:
-(void)categoryButtonWasClicked{
if ([self.myDelegate respondsToSelector:#selector(buttonWasPressInScrollView:)]){
[self.myDelegate buttonWasPressInScrollView:self];
}
...
}
in your viewController's .h add the following
#interface MyViewController : UIViewController <myUIScrollViewProtocol>

Resources