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
Related
I have a window with a large NSTextFeildCell, where text can be modified. Upon clicking a button another window appears where the text from the original window can be used some how. The issue I am having is when I attempt to retrieve that text the log spits out...
" -[NSTextView stringValue]: unrecognized selector sent to instance 0x100151860"
Fallowed by a long trace...
I have tried to solve this several different ways but with no luck.
currently,
First window controller
.h
#import <Cocoa/Cocoa.h>
#class NextWindowController;
#interface TextViewWindowController : NSWindowController
#property (nonatomic, weak) NextWindowController *NextWindow;
#property (nonatomic, weak) IBOutlet NSTextFieldCell *txtTextView;
- (IBAction)btnClicked:(id)sender;
- (NSString*)getText;
#end
.m
#import "TextViewWindowController.h"
#import "NextWindowController.h"
#implementation TextViewWindowController
#synthesize NextWindow;
- (IBAction)btnClicked:(id)sender{
[NextWindow setCallingWindow:self];
[NextWindow showWindow:self];
}
- (NSString*)getText{
return [_txtTextView stringValue];// there is a problem with the view...
}
#end
Next Window controller
.h
#import <Cocoa/Cocoa.h>
#class TextViewWindowController;
#interface NextWindowController : NSWindowController{
NSMutableString* str;
}
#property (nonatomic, weak) TextViewWindowController *callingWindow;
#end
.m
#import "NextWindowController.h"
#import "TextViewWindowController.h"
#implementation NextWindowController
#synthesize callingWindow;
- (IBAction)btnEnterClicked:(id)sender{
[str setString:callingWindow.txtTextView.stringValue];
}
- (id)initWithWindow:(NSWindow *)window{
self = [super initWithWindow:window];
if (self) {
str = [[NSMutableString alloc] init];
}
return self;
}
#end
I have also tried str = [callingWindow getText] with the same result.
Any help would be very appreciated!
It's not super intuitive to figure out from Apple's documentation, but to get the raw string value of a NSTextView (which inherits from NSText), just use:
[_txtTextView string];
And since you're using properties, it might be smarter to use the accessor in your function, like this:
- (NSString*)getText{
return [self.txtTextView string];
}
I've declared a property called Squad, but when I send [self getSquad] I get "no visible #interface for SquadViewController declares the selector 'getSquad'".
SquadViewController.h:
#import "FlipsideViewController.h"
#import "Squad.h"
#interface SquadViewController : UIViewController <FlipsideViewControllerDelegate, UIPopoverControllerDelegate>
#property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
#property (strong, nonatomic) UIPopoverController *flipsidePopoverController;
#property (nonatomic, retain) IBOutlet UILabel *squadNameLabel;
#property Squad *squad;
- (IBAction)updateTitleWithName:(id)sender;
#end
SquadViewController.m:
#import "SquadViewController.h"
#interface SquadViewController ()
#end
#implementation SquadViewController
#synthesize squadNameLabel;
#synthesize squad;
...
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
if (![self getSquad]) //<--THIS IS WHERE THE ERROR IS
{
[self setSquad:[Squad squadWithName:#"New Squad"]]; //<-- NOT HERE, SO THE SETTER SEEMS TO EXIST
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
...
I thought that "#synthesize squad" would generate getSquad and setSquad, so I'm confused.
Here's the code for Squad, if for some reason that I don't get it's relevant (I'm new to Objective C, I still find it very confusing (I'm from a java background)):
Squad.h:
#import "SquadBuilderObject.h"
#interface Squad : NSObject
#property NSString *name;
+ (id) squadWithName:(NSString*)name;
#end
Squad.m:
#import "Squad.h"
#implementation Squad
#synthesize name;
+ (id)squadWithName:(NSString *)name
{
Squad *newSquad = [[Squad alloc] init];
[newSquad setName:name];
return newSquad;
}
#end
The standard getter for a property named squad is squad, not getSquad.
The "get…" nomenclature is typically reserved for things returned by reference (e.g. - (BOOL)getSquad:(Squad **)outSquad).
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.
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.
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.