own delegate - function work in 50%, something is wrong - objective-c

i've got own delegate for my own class.
MainMenuViewDelegate
#import <Foundation/Foundation.h>
#class MainMenuView;
#protocol MainMenuViewDelegate <NSObject>
-(void) mainMenuViewLibrary:(MainMenuView*)controller withString:(NSString*)string;
#end
MainMenuView.h
#import <UIKit/UIKit.h>
#import "WorkspaceView.h"
#import "MainMenuViewDelegate.h"
#interface MainMenuView : UIView
#property (nonatomic,weak) id <MainMenuViewDelegate> delegate;
....
#end
MainMenuView.m
#implementation MainMenuView
#synthesize delegate;
...
-(void)library:(id)sender{
//test
NSLog(#"it's work");
NSString *string = #"some text";
[delegate mainMenuViewLibrary:self withString:string];
NSLog(#"finish");
}
WorkspaceView.h
#import <UIKit/UIKit.h>
#import "MainMenuViewDelegate.h"
#interface WorkspaceView : UIView <MainMenuViewDelegate> {
int menuStatus;
UILabel *label;
}
#property int menuStatus;
#property (nonatomic, retain) UILabel *label;
#end
WorkspaceView.m
#import "WorkspaceView.h"
#import "MainMenuView.h"
#implementation WorkspaceView
#synthesize menuStatus;
#synthesize label;
....
-(void) mainMenuViewLibrary:(MainMenuView*)controller withString:(NSString*)string{
[label setText: string];
}
#end
The problem appears when i press btnLibrary and invokes -(void)library:(id)sender function.
console print it's work, then my delegate function is invokes, but i don't see any change in my label (placed in WorkspaceView), and in finish console print finish.

None of your objects is set as the delegate so the delegate is nil - messages sent to nil are silenced. Nothing happens.
If it is not a problem, put the NSLog in:
-(void) mainMenuViewLibrary:(MainMenuView*)controller withString:(NSString*)string;
in your WorkspaceView and check whether the method is called.
Hope that helps.

Related

Calling a method from another class. error : No visible #interface ... declares the selector

I have two classes DetailViewController and Substitution, I would use the Substitution class methods but I get this error:
No visible #interface "Substitutions" declares the selector "Crypt ::"
DetailViewController.h
#import <UIKit/UIKit.h>
#import "Substitutions.h"
#interface DetailViewController : UIViewController
#property (weak, nonatomic) IBOutlet UITextField *tvC;
- (IBAction)bCrypter:(id)sender;
#property (nonatomic, strong) Substitutions * s;
DetailViewController.m
#import "DetailViewController.h"
#implementation DetailViewController
#synthesize s;
#synthesize tvC;
- (IBAction)bCrypter:(id)sender
{
s = [[Substitutions alloc]init];
[s Crypter:tvC.text :1]; <-- No visible #interface "Substitutions" declares the selector "Crypter::"
//NSLog(#"%#",tvC.text);
}
Substitutions.h
#interface Substitutions : NSObject
+ (NSString*)Crypter:(NSString*)msg :(id)cles;
#end
Substitutions.m
#import "Substitutions.h"
#implementation Substitutions
+ (NSString*)Crypter:(NSString*)msg :(id)cles
{
NSLog(#"%#",msg);
return #"";
}
Because Crypter is class method not instance method so you should call directly with class name not need to create instance for call method.
Ex.
[Substitutions Crypter:tvC.text :1];

Set text in the textfield does not work in Obj-C

I would like to set an text in the text field in another class and get it from another class. This is something what I want, but it does not work. Can you please help me. Thank you!
aaa.h
#import <Cocoa/Cocoa.h>
#interface aaa : NSImageView {
IBOutlet NSTextField *message;
}
#property (nonatomic, retain) IBOutlet NSTextField *message;
#end
aaa.m
#import "aaa.h"
#import "bbb.h"
#implementation aaa
#synthesize message;
- (void)awakeFromNib {
// [message setStringValue:#"ok, this works!"]; //but i don't want it from here
[self hello];
}
#end
bbb.h
#import <Foundation/Foundation.h>
#interface NSObject (bbb)
- (void)hello;
#end
bbb.m
#import "bbb.h"
#import "aaa.h"
#implementation NSObject (bbb)
- (void)hello {
aaa *obj = [[[aaa alloc] init] autorelease];
[obj.message setStringValue:#"This doesn't work :("]; // set text here, dont work.
NSLog(#"TEST: %#", [obj.message stringValue]);
}
#end
You are using category, so first thing it is used for extending the functionality of existing class. So you cannot set textfield value inside category. But else you can add some functonality after extracting the value. So you have to pass the value inside the category first. Try like this below:
- (void)awakeFromNib {
NSString *resultString=[self hello:#"This doesn't work :("];
[message setStringValue:resultString];
}
#end
#interface NSObject (bbb)
- (NSString*)hello:(NSString*)yourString;
#end
#implementation NSObject (bbb)
- (NSString*)hello:(NSString*)yourString {
return yourString;
}
#end

IOS application - define protocol in separate file

I have defined a protocol in a separate file (myProtocol.h). Here is the code for it:
#import <Foundation/Foundation.h>
#protocol myProtocol <NSObject>
-(void) loadDataComplete;
#end
Now I want to call this method so I have done the following code:
firstViewController.h:
#import "myProtocol.h"
#interface firstViewController : UIViewController{
id <myProtocol> delegate;
}
#property (retain) id delegate;
-(void) mymethod;
firstViewController.m
#implementation firstViewController
#synthesize delegate;
- (void)viewDidLoad {
[self mymethod];
}
-(void) mymethod {
//some code here...
[delegate loadDataComplete];
}
I have another file where the protocol is also utilized:
secondViewController.h:
#import "myProtocol.h"
#interface secondViewController : UIViewController<myProtocol>{
}
secondViewController.m:
-(void) loadDataComplete{
NSLog(#"loadDataComplete called");
}
but my secondViewController is not calling the protocol methad. Why is it so? Any suggestion will be appreciated.
First, as #Abizern suggested, try to reformat your code a little bit. Use capital letter for classes. Said this here the solution for your answer.
This is the protocol. I would name it like FirstViewControllerDelegate since the class that implements the object is a delegate for FirstViewController.
#import <Foundation/Foundation.h>
#protocol MyProtocol <NSObject>
- (void)doSomething;
#end
This is SecondViewController.
#import <UIKit/UIKit.h>
#import "MyProtocol.h"
#interface SecondViewController : UIViewController <MyProtocol>
#end
#implementation SecondViewController
// other code here...
- (void)doSomething
{
NSLog(#"Hello FirstViewController");
}
#end
This is FirstViewController.
#import <UIKit/UIKit.h>
#interface FirstViewController : UIViewController
// it coud be better to declare these properties within a class extension but for the sake of simplicity you could leave here
// the important thing is to not declare the delegate prop with a strong/retain property but with a weak/assign one, otherwise you can create cycle
#property (nonatomic, strong) SecondViewController* childController;
#property (nonatomic, weak) id<MyProtocol> delegate;
#end
#implementation FirstViewController
// other code here...
- (void)viewDidLoad
{
[super viewDidLoad];
self.childController = [[SecondViewController alloc] init];
self.delegate = self.childController; // here the central point
// be sure your delegate (SecondViewController) responds to doSomething method
if(![self.delegate respondsToSelector:#selector(doSomething)]) {
NSLog(#"delegate cannot respond");
} else {
NSLog(#"delegate can respond");
[self.delegate doSomething];
}
}
#end
For the sake of completeness, be sure to understand the delegate pattern means. Apple doc is your friend. You could take a look at the-basics-of-protocols-and-delegates to have a basic intro on the argument. Furthermore, SO search allows you to find a lot of answers on the topic.
Hope that helps.

Why is my NSDictionary not initializing my specific keys and values when in my model, but works within my controller?

In this example my NSDictionary initializes with 0 key/value pairs, as shown in my debugger. It will initialize properly when I do the exact same thing in my ViewController but I would much prefer to stick to MVC design and have the NSDictionary in my model.
ShakespeareViewController.h
#import <UIKit/UIKit.h>
#interface ShakespeareViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *sonnetDisplay;
#end
ShakespeareViewController.m
#import "ShakespeareViewController.h"
#import "ShakespeareModel.h"
#interface ShakespeareViewController ()
#property (nonatomic, strong) ShakespeareModel *sonnet;
#end
#implementation ShakespeareViewController
#synthesize sonnetDisplay = _sonnetDisplay;
#synthesize sonnet = _sonnet;
- (IBAction)sonnetButton:(UIButton *)sender
{
self.sonnetDisplay.text = [self.sonnet grabSonnet:#"19"];
}
#end
ShakespeareModel.h
#import <Foundation/Foundation.h>
#interface ShakespeareModel : NSObject
-(NSString *)grabSonnet:(NSString *)atNumber;
#end
ShakespeareModel.m
#import "ShakespeareModel.h"
#interface ShakespeareModel()
#property (nonatomic, strong) NSDictionary *sonnets;
#end
#implementation ShakespeareModel
#synthesize sonnets = _sonnets;
-(NSDictionary *)sonnets
{
if (!_sonnets)
{
_sonnets = [[NSDictionary alloc] initWithObjectsAndKeys:#"19", #"19", nil];
}
return _sonnets;
}
-(NSString *)grabSonnet:(NSString *)atNumber
{
NSString *chosenSonnet = [self.sonnets objectForKey:#"19"];
return chosenSonnet;
}
#end
Any ideas on what I am doing wrong are greatly appreciated. I can't see why this wouldn't initialize with the object 19 at key value 19.
I don't see any place where you set the view controller's sonnet property to an instance of ShakespeareModel -- so when you call grabSonnet: you're sending a message to nil (and thus getting nothing back.
You should put self.sonnet = [[ShakespeareModel alloc] init] in your view controller some time before you call grabSonnet:... probably in the initializer or in -viewDidLoad.

'Existing ivar 'delegate' for unsafe_unretained property 'delegate' must be __unsafe_unretained

I'm getting the error above, but unsure how to go about fixing it. This is my code:
.h:
#import <UIKit/UIKit.h>
#protocol ColorLineDelegate <NSObject>
-(void)valueWasChangedToHue:(float)hue;
#end
#interface ColorLine : UIButton {
id <ColorLineDelegate> delegate;
}
#property (nonatomic, assign) id <ColorLineDelegate> delegate;
#end
.m:
#import "ColorLine.h"
#implementation ColorLine
#synthesize delegate;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
#end
The error occurs in the synthesize line. I can't find a problem though.
Use this syntax:
#interface SomeClass : NSObject {
id <SomeClassDelegate> __unsafe_unretained delegate;
}
#property (unsafe_unretained) id <SomeClassDelegate> delegate;
Looks like your project might be using ARC then properties should be declared this way:
#import <UIKit/UIKit.h>
#protocol ColorLineDelegate <NSObject>
-(void)valueWasChangedToHue:(float)hue;
#end
#interface ColorLine : UIButton
#property (nonatomic, weak) id <ColorLineDelegate> delegate;
#end
I had the same problem when I used old example code which did not feature ARC in my ARC project. It seems that you do not need to put the variable declarations into the interface definition any more. So your code should work like this:
h:
#import <UIKit/UIKit.h>
#protocol ColorLineDelegate <NSObject>
-(void)valueWasChangedToHue:(float)hue;
#end
#interface ColorLine : UIButton {
// Get rid of this guy!
//id <ColorLineDelegate> delegate;
}
#property (nonatomic, assign) id <ColorLineDelegate> delegate;
#end
.m:
#import "ColorLine.h"
#implementation ColorLine
#synthesize delegate;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
#end
Perhaps a bit late but to be "ARC compliant", you simply have to replace
#property (nonatomic, assign) id <ColorLineDelegate> delegate;
by
#property (nonatomic, strong) id <ColorLineDelegate> delegate;
Bye.
If you want a weak property, this also works.
#interface MyClass : NSObject {
__weak id <MyClassDelegate> _delegate;
}
#property (nonatomic, weak) id <MyClassDelegate> delegate;
you can also use
#dynamic delegate
in the implementation instead of synthesize.