objective c multiple inheritance conflict with many - iphone

I just started to build in objective c from iphone.
I have interface:
#interface test : UIView
that implements all methods from UIView, now i want it interface inherit from CDVPlugin also.
How can i do it?
i read that objective c doesn't offer multiple inheritance.

you can't inherent from CDVPlugin and UIView.
I would suggest doing something like this
#interface test : NSObject {
UIView *view;
CDVPlugin *plugin;
}
#property(nonatomic, retain) UIView *view;
#property(nonatomic, retain) CDVPlugin *plugin;
#end
and you can add methods to that class to handle anything that you're trying to do. Then just use test.view to access the view and test.plugin to access the plugin.

Related

Objective-C Design Help Needed, Need Protocol Possibly?

I have a situation where ClassA contains a UIView property. I have two children of ClassA, ChildA and ChildB, both set this UIView property for themselves with two different types of UIView subclasses. I'd like to require that both of these UIView subclasses have a property called maximumDimension, and then I'd like to be able to set it in ClassA using its own UIView property.
What is the best way to accomplish this? Would it be a protocol? If so would someone be able to provide code on how this can be achieved in Objective-C?
Would it be a protocol?
Yes:
#protocol Foo <NSObject>
#property (nonatomic, assign) int maximumDimensions; // wild guess to type from name
#end
Then the actual property:
#property (nonatomic, strong) id <Foo> bar;
For discussion's sake, here's a solution that uses a category instead of a protocol, extending UIView to have a maximumDimensions property:
UIView+MaximumDimensions.h
#interface UIView (MaximumDimensions)
#property ( nonatomic, readonly ) CGSize maximumDimensions ;
#end
UIView+MaximumDimensions.m
#implementation UIView (MaximumDimensions)
-(CGSize)maximumDimensions { return self.bounds.size ; }
#end
Now, in the methods of ClassA, you can access self.view.maximumDimensions. (Because UIView now has a maximumDimensions property.) Your subclasses of UIView, ChildA and ChildB can implement -maximumDimensions to return the correct answer.

Forward declaring a protocol in objective-c

My class .h looks like:
#protocol AppInfoDelegate;
#class InfoTextView;
#interface AppInfoViewController : UIViewController <AppInfoDelegate> {
}
#property (nonatomic, retain) NSArray *textObjectsArray;
#property (nonatomic, retain) InfoTextView *itView;
#property (nonatomic, retain) UIButton *pgBackButton;
#property (nonatomic, retain) UIButton *pgFwdButton;
#end
#protocol AppInfoDelegate <NSObject>
- (void)closeButtonPressed:(id)sender;
#end
I get a warning that the protocol definition for AppInfoDelegate cannot be found. What is the proper way to do this and why cannot it not be found? Do I need to have the whole definition of the protocol before the interface? Thanks!
Using #protocol MyProtocol; is useful when you are asserting, for example, that a method will take id <MyProtocol> as an argument.
It is not useful when you are claiming that your class conforms to <MyProtocol>. The reason for this is that the compiler needs the full protocol declaration in order to verify that your class actually conforms to the protocol. (This compile-time check is one great reason to use formal protocols instead of the older informal ones.)
You can fix in two ways. One, as #skram suggests, is to just forward-declare the whole thing. This works, but it's also rather limited in my view. Why bother with a protocol in that case - just put everything in the class #interface and be done with it.
The second approach, which I prefer, is to actually have a separate header, such as MyProtocol.h. You can then freely import this into any header or implementation files as needed. This allows you to reuse a protocol easily (and avoid the headaches of circular imports that sometimes arise).
Try this:
#protocol AppInfoDelegate <NSObject>
- (void)closeButtonPressed:(id)sender;
#end
#class InfoTextView;
#interface AppInfoViewController : UIViewController <AppInfoDelegate> {
}
#property (nonatomic, retain) NSArray *textObjectsArray;
#property (nonatomic, retain) InfoTextView *itView;
#property (nonatomic, retain) UIButton *pgBackButton;
#property (nonatomic, retain) UIButton *pgFwdButton;
#end
Yes, superclass and adopted protocol definitions need to be defined (verbatim or by using #import) before the class definition. They cannot be forward-declared.
I've always seen the whole protocol definition before the #interface. I believe you can also put it into a separate file though

Common views in viewControllers - Code re-usability

I have few common views in most of my viewControllers. What I noticed is that I can reuse single code for all viewControllers which is absolutely wise. For this I decided to create a class Utils which has static methods like
+(void)createCommonViews:(float)yAxis:(NSString*)text;
In my case common views are three labels and two images.
Problem : I am not able to add these views from Utils. I am wondering how can I send self as a parameter so that I may add the views from Utils. It may be wrong to add views outside the viewController. In that case what can be the solution? Taking all these views in a UIView, setting return type of Utils method as UIView and then adding UIView to viewController (after calling method from viewController) might solve my problem. But what I am looking for is some other solution.
+(void) createCommonViews:(float)yAxis withText:(NSString*) text toTarget:(UIViewController*) target
{
//create views
[target addSuview:view];
}
But I think returning a Uiview and then adding it in the UIViewController afterwards, is a far better solution.
The method you're attempting is to have your view object as a singleton. This is uncommon at best, at worst a crash waiting to happen. Better design is for each of your view controller classes to have its own instance of your custom view, like so:
#interface MyCommonView : UIView
// ...
#end
#interface MyViewController_A : UIViewController {
MyCommonView *commonView;
}
#property (strong, nonatomic) IBOutlet MyCommonView *commonView;
#end
// Meanwhile somewhere else...
#interface MyViewController_B : UIViewController {
MyCommonView *commonView;
}
#property (strong, nonatomic) IBOutlet MyCommonView *commonView;
#end
Create a viewController that acts as a parent view for all your common stuff, call it CommonViewController then implement this in all the viewcontrollers you want it to appear
-(void) viewDidLoad
{
[self.view addSubView:[[CommonViewController alloc] initWithRect:..];
}
Or alternatively using xib files

some confusions about " property" in Objective-C

#interface TheViewController : UIViewController
{
IBOutlet UITableView *table;
}
#property (nonatomic,retain) IBOutlet UITableView *table;
or just like this:
#interface TheViewController : UIViewController
{
}
#property (nonatomic,retain) IBOutlet UITableView *table;
Is it ok like the second one?
And what is the difference ?
And which is recommended ?
Is it ok like the second one?
The two syntaxes are correct, generally speaking.
And what is the difference ?
The second one will also declare the ivar for you, but will only work correctly newer Objective C runtime systems.
And which is recommended ?
good question... I think they are pretty equivalent, provided you can restrict yourself to the newer ObjC runtime systems. For more hints at possible downsides of not declaring ivars explicitly, please have a look at this S.O. post.
In Objective-C 2.0, synthesized properties will automatically create the corresponding ivars as required. So both syntaxes are correct..This article will make it clear for you..
These two are not quite equivalent even in the ObjC 2.0 environment because of the IBOutlet. That has to be declared on the property. They'd be equivalent like this:
#interface TheViewController : UIViewController
{
IBOutlet UITableView *table;
}
#property (nonatomic,retain) UITableView *table;
#interface TheViewController : UIViewController
{
}
#property (nonatomic,retain) IBOutlet UITableView *table;
Notice the added IBOutlet in the property definition.
Generally they're equivalent in Objective-C 2.0 environment, but the debugger, for example, won't see the generated ivar as this object's member in the variables view and you'll have to ask for the value by using gdb's command line po command using the accessor method (not the short-form dot notation though).

cannot find protocol declaration custom protocol delegate iphone

Slowly but surely getting this delegation and protocol stuff on iphone but I cannot understand this error.
I have declared my protocol in my first viewcontroller.
In the second viewcontroller i try to add it at the top after i have imported it into the header file and it cannot find it. see my code below.
//SendSMS
#import <UIKit/UIKit.h>
#import "LoginPage.h"
#import "MessageOptions.h"
#protocol SMSProtocol <NSObject>
-(NSString *)postbackType;
#end
#interface SendSMS : UIViewController <UITextViewDelegate, UITextFieldDelegate> {
id<SMSProtocol> delegate;
MessageOptions *messageOptions;
LoginPage *loginPage;
IBOutlet UITextField *phonenumber;
IBOutlet UITextView *smsBody;
IBOutlet UIScrollView *scrollview;
}
#property (nonatomic, retain) id<SMSProtocol> delegate;
-(IBAction)LoadMessageOptions;
#end
Then my second view
#import <UIKit/UIKit.h>
#import "SendSMS.h"
#interface ScheduledSMS : UIViewController <SMSProtocol>{
}
-(IBAction)popBack;
#end
That is surely strange. Have you tried restarting Xcode? Xcode has a habit of not indexing symbols for me when I add new files.
You should also look into how your naming conventions. SendSMS is not really a good class name, more of a action method name. I would go for SendSMSViewController, since that is what it is.
By that it would follow that SMSProtocol should be named SendSMSViewControllerDelegate, since that is what it is.
Methods in a delegate protocol should contain the sender and one of the three words will, did, or should. If not at the very least it should name what it expects to return. -(NSString *)postbackType; should probably be -(NSString *)postbackTypeForSendSMSViewController:(SendSMSViewController*)controller;.