I'm creating a shopping list app, and trying to implement a custom delegate when editing an item. When creating the #protocol at the bottom of the header file, when trying to declare a property of that protocol in the #interface section I'm getting an error of: Cannot find protocol declaration for GEMEditItemViewControllerDelegate
This is what my header file looks like.
#import <UIKit/UIKit.h>
#import "GEMItem.h"
#interface GEMEditItemViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate>
#property GEMItem *item;
#property (weak) id<GEMEditItemViewControllerDelegate> delegate;
#end
#protocol GEMEditItemViewControllerDelegate <NSObject>
#required
- (void)controller:(GEMEditItemViewController *)controller didUpdateItem:(GEMItem *)item;
#end // End of delegate protocol
Alternatively in a separate instance when declaring the protocol above the interface I cannot access the view controller to pass as a parameter for that declaration method.
That header file looks like:
#import <UIKit/UIKit.h>
#import "GEMItemManager.h"
#protocol GEMAddItemViewControllerDelegate <NSObject>
/*
// Tried to add the controller (controller:(GEMAddItemviewController *)controller) as first paramiter, but was getting and errror, so I have omitted it for the time being
- (void)controller:(GEMAddItemViewController *)controller didSaveItemWithName:(NSString *)name andQuantity:(float)quantity andPrice:(float)price andCategory:(NSString *)category andNotes:(NSString *)notes;
*/
- (void)didSaveItemWithName:(NSString *)name andQuantity:(float)quantity andPrice:(float)price andCategory:(NSString *)category andNotes:(NSString *)notes;
#end
#interface GEMAddItemViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate>
#property (weak) id<GEMAddItemViewControllerDelegate> delegate;
#property NSArray *categories;
#end
Any thoughts on how to correct this would be greatly appreciated!!
You can do it like this also
#protocol GEMEditItemViewControllerDelegate;
#interface GEMEditItemViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate>
#property GEMItem *item;
#property (weak) id<GEMEditItemViewControllerDelegate> delegate;
#end
#protocol GEMEditItemViewControllerDelegate <NSObject>
#required
- (void)controller:(GEMEditItemViewController *)controller didUpdateItem:(GEMItem *)item;
#end
Try it this way:
#class GEMEditItemViewController; // forward declaration of class
#protocol GEMEditItemViewControllerDelegate <NSObject>
#required
- (void)controller:(GEMEditItemViewController *)controller didUpdateItem:(GEMItem *)item;
#end // End of delegate protocol
#interface GEMEditItemViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate>
#property GEMItem *item;
#property (weak) id<GEMEditItemViewControllerDelegate> delegate;
#end
BTW - you should move the two picker view protocols from the header file to a class extension in the .m file. The world doesn't need to know this implementation detail.
Your header file should looks like this:
#class GEMEditItemViewController;
#class GEMItem;
#protocol GEMEditItemViewControllerDelegate <NSObject>
#required
- (void)controller:(GEMEditItemViewController *)controller didUpdateItem:(GEMItem *)item;
#end // End of delegate protocol
#interface GEMEditItemViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate>
#property GEMItem *item;
#property (weak) id<GEMEditItemViewControllerDelegate> delegate;
#end
You should not use direct import in your header file. #class directive is used to prevent cycle dependencies. In your case GEMItem import should be in your meta file.
Related
I have two classes, one view controller an another NSObject class that performs async processes, once its done I want to interrupt the view controller similar to what a button does as IBAction, to update UI. I wanted to keep this functionality in modularized for better use in later stages. Is there a way to do this on Objective-c?
CircleDetectionViewController.h:
#import <UIKit/UIKit.h>
#import "CameraController.h"
#interface CircleDetectionViewController : UIViewController <MyDelegate>
#property (weak, nonatomic) IBOutlet UIImageView *screenPreview;
#end
CircleViewController.mm:
#interface CircleDetectionViewController () <CvVideoCameraDelegate>
#end
#implementation CircleDetectionViewController
CvVideoCamera *camera;
//code
#end
CameraController.h:
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
#import "CircleDetectionViewController.h"
#protocol MyDelegate <NSObject>
-(void) updateUI;
#end
#interface CameraController : NSObject <MyDelegate>
#property (nonatomic, strong) AVCaptureDevice *inputDevice;
#property (nonatomic, strong) AVCaptureSession *session;
#property (nonatomic, strong) AVCaptureStillImageOutput *photoOutput;
#property (nonatomic, weak) id <MyDelegate> delegate;
#end
CameraController.m:
#import "CameraController.h"
#import "FlashHelper.h"
#import "ImageProcessor.h"
#implementation CameraController
#synthesize delegate;
FlashHelper *Flash;
ImageProcessor *IMGProcessor;
int shootCounter;
int NUMSHOTS = 2;
-(id)init{
//code
}
For some reason the code says "No type or protocol named MyDelegate"
Any help would be really appreciated!
In NSObject class create a delegate:
#protocol MyDelegate <NSObject>
-(void) updateUI;
#end
and declare a property of delegate
#property (nonatomic, weak) id <MyDelegate> delegate;
In viewcontroller class invoke the delegate class
NSObject class obj.delegate = self;
and implement the delegate method.
Always update your UI from Main Thread.
To get the main thread use this:
dispatch_async(dispatch_get_main_queue(), ^{
// call your delegate method or update UI here
});
For details for delegate methods check this.
I have a custom delegate that I have created for a subclass of UITextField. In the delegate class, I've declared an enum like this:
MyCustomDelegate.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "MyCustomTextField.h"
#interface MyCustomDelegate : NSObject <MyDelegate, UITextFieldDelegate>
#property (nonatomic, strong)MyCustomTextField *customTextField;
#end
MyCustomTextField.h:
#import <UIKit/UIKit.h>
typedef enum {
EnumTypeA,
EnumTypeB,
EnumTypeC,
EnumTypeD,
EnumTypeE
} MyEnumType;
#class MyCustomDelegate;
#protocol MyDelegate <NSObject>
#required
- (void)methodA;
- (void)methodB;
#end
#interface MyCustomTextField : UITextField
#property (nonatomic, weak)id <MyDelegate>myDelegate;
#property (nonatomic) MyEnumType enumType;
#end
Now, I am trying to use this enum in conjunction with my custom UITextField elsewhere in my project, like this:
MyViewController.h
#import "MyCustomTextField.h"
#import "MyCustomDelegate.h"
#import <UIKit/UIKit.h>
#interface MyViewController : UIViewController
#property (weak, nonatomic) IBOutlet MyCustomTextField *mySampleTextField;
#end
MyViewController.m:
- (void)viewDidLoad {
[super viewDidLoad];
[self.mySampleTextField setMyEnumType:EnumTypeA];
}
However, I am getting the error, "No visible #interface for 'MyCustomTextField' declares the selector 'setMyEnumType'".
Can anyone see what it is I'm doing wrong?
Objective-C will automatically generate setter for you based on the name of the property (enumType) instead of the name of type (MyEnumType). So your setters should be the following instead:
[self.mySampleTextField setEnumType:EnumTypeA];
When I tried having protocols in below two classes, compiler says that the protocol declarations cannot be found
ViewController:
#import <UIKit/UIKit.h>
#import "SecondViewController.h"
#protocol FlipOtherSideViewControllerDelegate;
#interface ViewController : UIViewController<FlipsideViewControllerDelegate> {
id <FlipOtherSideViewControllerDelegate> __unsafe_unretained delegate;
}
- (IBAction)switchMode:(id)sender;
#property (unsafe_unretained) id <FlipOtherSideViewControllerDelegate> delegate;
#end
#protocol FlipOtherSideViewControllerDelegate
- (void)flipothersideViewControllerDidFinish:(ViewController *)controller;
#end
SecondViewController:
#import <UIKit/UIKit.h>
#import "ViewController.h"
#protocol FlipsideViewControllerDelegate;
#interface SecondViewController : UIViewController <FlipOtherSideViewControllerDelegate> {
id <FlipsideViewControllerDelegate> __unsafe_unretained delegate;
}
#property (unsafe_unretained) id <FlipsideViewControllerDelegate> delegate;
#end
#protocol FlipsideViewControllerDelegate
- (void)flipsideViewControllerDidFinish:(SecondViewController *)controller;
#end
Any suggestion on above?
Thanks in advance.
Why you declaring below the interface? Try to declare just before the interface declaration. I think there should not be any error then.
I've declared a protocol named ScrollableTimelineViewProtocol in a file ScrollableTimelineView.h as below :
#import <UIKit/UIKit.h>
#import "AbstractView.h"
#import "RedTimeIndicator.h"
#import "EventsModel.h"
#import "TimeStrands.h"
#define LABEL_TAG_OFFSET -500
#protocol ScrollableTimelineViewProtocol <NSObject>
- (void) showPopup : (NSInteger)tag;
#end
#interface ScrollableTimelineView : UIView<TimeStrandDelegate,UIScrollViewDelegate>
{
}
#property (nonatomic,assign) id<ScrollableTimelineViewProtocol> delegate;
And I'm trying to use it in a view controller :
#import <UIKit/UIKit.h>
#import "AbstractViewController.h"
#import "TimeStrands.h"
#import "ScrollableTimelineView.h"
#protocol TimelineDelegate <NSObject>
- (void) detailedShownDelegate;
- (void) detailedViewHiddenDelegate;
#end
#interface TimelineViewController : UIViewController<ScrollableTimelineViewProtocol>;
But I get an error saying Could not find protocol declartion for ScrollableTimelineViewProtocol. Help.
There should not be semicolon at the end
Import the class where ScrollableTimelineViewProtocol declared.
#protocol scrollableTimelineViewProtocol;
#property (strong, nonatomic) IBOutlet UITableView *tblView;
#property (strong, nonatomic) IBOutlet id<scrollableTimelineViewProtocol> delegate;
#end
#protocol scrollableTimelineViewProtocol <NSObject>
-(void)runFast;
#end
Just simple... Try this...
Remove semocolon from interface..
#interface TimelineViewController : UIViewController<ScrollableTimelineViewProtocol>;
Into
#interface TimelineViewController : UIViewController<ScrollableTimelineViewProtocol>
I'm trying to see why the type can't be read from the protocol. I figured that the it's because the #interface is below the protocol but if someone can help me figure out the problem and explain to me why that would be great.
#import <UIKit/UIKit.h>
#protocol ARCHCounterWidgetDelegate <NSObject>
- (UIColor *) counterWidget: (ARCHCounterWidget *) counterWidget;
#end
#interface ARCHCounterWidget : UIView
#property (weak, nonatomic) id<ARCHCounterWidgetDelegate> delegate;
#end
You have to either forward declare the class or the protocol:
// tell the compiler, that this class exists and is declared later:
#class ARCHCounterWidget;
// use it in this protocol
#protocol ARCHCounterWidgetDelegate <NSObject>
- (UIColor *) counterWidget: (ARCHCounterWidget *) counterWidget;
#end
// finally declare it
#interface ARCHCounterWidget : UIView
#property (weak, nonatomic) id<ARCHCounterWidgetDelegate> delegate;
#end
or:
// tell the compiler, that this protocol exists and is declared later
#protocol ARCHCounterWidgetDelegate;
// now you can use it in your class interface
#interface ARCHCounterWidget : UIView
#property (weak, nonatomic) id<ARCHCounterWidgetDelegate> delegate;
#end
// and declare it here
#protocol ARCHCounterWidgetDelegate <NSObject>
- (UIColor *) counterWidget: (ARCHCounterWidget *) counterWidget;
#end
The compiler is not yet aware of the ARCHCounterWidget, and therefore cannot resolve the type in the delegate method. Simple solution is:
#import <UIKit/UIKit.h>
// Reference the protocol
#protocol ARCHCounterWidgetDelegate
// Declare your class
#interface ARCHCounterWidget : UIView
#property (weak, nonatomic) id<ARCHCounterWidgetDelegate> delegate;
#end
// Declare the protocol
#protocol ARCHCounterWidgetDelegate <NSObject>
- (UIColor *) counterWidget: (ARCHCounterWidget *) counterWidget;
#end
It just makes it so that the compiler knows that the protocol is defined SOMEWHERE and can be referenced