Cocoa NSTextField - cocoa

i have a problem with accessing value from the NSTExtField in different class here is the code:
AppDelegate.h
#import <Cocoa/Cocoa.h>
#interface AppDelegate : NSObject <NSApplicationDelegate>
#property (assign) IBOutlet NSWindow *window;
#property (weak) IBOutlet NSTextField *numberOfPhrases;
#end
AppDelegate.m
#import "AppDelegate.h"
#implementation AppDelegate
#synthesize numberOfPhrases;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSLog(#"%#",[numberOfPhrases stringValue]);
}
TestClass.h
#interface TestClass : NSObject
- (IBAction)doSomething:(id)sender;
#end
TestClass.m
#implementation TestClass
- (IBAction)doSomething:(id)sender {
NSLog(#"%#",[numberOfPhrases stringValue]); ?????????
}

You obviously can't access the text field value in another class without a link to it.
To access the text field's value you either need to have one more IBOutlet to it in this class or an IBOutlet to AppDelegate so that you can access its property.
TestClass.h
#interface TestClass : NSObject
{
IBOutlet NSTextField *numberOfPhrases; // connect it to the new referencing outlet of text field by dragging a NSObject object in your xib and setting its class to "TestClass"
}
- (IBAction)doSomething:(id)sender;
#end
OR an another option is to have a IBOutlet of AppDelegate in TestClass (because if you only create a new instance of AppDelegate and not its IBOutlet then a different instance of text field will be created and you will not be able to access the value of your text field)
TestClass.h
#interface TestClass : NSObject
{
IBOutlet AppDelegate *appDel; // connect in the xib
}
- (IBAction)doSomething:(id)sender;
#end
TestClass.m
#implementation TestClass : NSObject
- (IBAction)doSomething:(id)sender
{
[[appDel numberOfPhrases]stringValue]; //get the string value in text field
}
#end

The only thing you're missing is the addition to your TestClass.m file:
#import "TestClass.h"
#import "AppDelegate.h"
#implementation TestClass
- (IBAction)doSomething:(id)sender {
AppDelegate *theInstance = [[AppDelegate alloc] init];
[theInstance numberOfPhrases];
}
#end
You need to include the class header of AppDelegate.h in TestClass.m, then you simply call an instance through [[AppDelegate alloc] init]; You'll need to link your NSTextField to the Sent Actions in Interface Builder do:Something -> TestClass and Referencing Outlets numberOfPhrases -> AppDelegate.
Output:
2014-01-21 23:32:56.499 test[6236:303] Wonders Never Cease

Related

What is the proper way to declare a delegate variable?

In MyModel.h, I declared a delegate variable like this:
#property(weak) IBOutlet id <MyProtocol> delegate;
I've also seen a delegate variable declared like this:
#property(weak) IBOutlet NSObject <MyProtocol>* delegate;
I'm wondering which I should use.
Also, Xcode 6.2 indicates I'm doing something wrong because when I connect the delegate outlet in IB, Xcode still shows an empty circle to the left of the declaration instead of a filled in circle. This is what I did:
1) In IB, I dragged on Object out of the Library onto the dock, and I changed its class to: MyModel.
2) In IB, I dragged another Object onto the dock, and I changed its class to: MyController. I declared the MyController class like this:
#interface MyController : NSObject <MyProtocol>
#property(strong) IBOutlet MyModel* model;
#end
3) In IB, I hooked up the delegate outlet for the MyModel Object to the MyController Object.
But in Xcode, it still shows an empty circle to the left of the line:
#property(weak) IBOutlet id <MyProtocol> delegate;
In other words, Xcode is saying the outlet is not connected to anything--yet my app is able to communicate with the controller using the delegate property.
If I delete <MyProtocol> from that line, the circle to the left of the line fills in, i.e. Xcode is saying the outlet is now connected to something. Is that an Xcode bug?
Here are the files for my HelloDelegate app:
MyProtocol.h:
//
// MyProtocol.h
// HelloDelegate
//
#class MyModel; //#import "MyModel.h" doesn't work for some reason
#protocol MyProtocol
-(void)sayHello:(MyModel*)model;
#end
MyModel.h:
//
// MyModel.h
// HelloDelegate
//
#import <Foundation/Foundation.h>
#import "MyController.h"
#interface MyModel : NSObject
#property NSString* name;
-(id)initWithName:(NSString*)name;
-(void)doStuff;
#end
MyModel.m:
//
// MyModel.m
// HelloDelegate
//
#import "MyModel.h"
#interface MyModel()
#property(weak) IBOutlet id <MyProtocol> delegate;
#end
#implementation MyModel
-(void)doStuff {
[[self delegate] sayHello:self];
}
-(id) init {
return [self initWithName:#"world"];
}
//Designated initializer:
-(id) initWithName:(NSString *)name {
if (self = [super init]) {
[self setName:name];
}
return self;
}
#end
MyController.h:
//
// MyController.h
// HelloDelegate
//
#import <Foundation/Foundation.h>
#import "MyProtocol.h"
#interface MyController : NSObject <MyProtocol>
#property(strong) IBOutlet MyModel* model;
#end
MyController.m:
//
// MyController.m
// HelloDelegate
//
#import "MyController.h"
#import "MyModel.h"
#import <Cocoa/Cocoa.h>
#interface MyController()
#property(weak) IBOutlet NSTextField* label;
#end
#implementation MyController
-(void)sayHello:(MyModel*)model {
NSString* labelText = [NSString stringWithFormat:#"Hello, %#!", [model name]];
[[self label] setStringValue:labelText];
}
#end
AppDelegate.m:
//
// AppDelegate.m
// HelloDelegate
//
#import "AppDelegate.h"
#import "MyController.h"
#import "MyModel.h"
#interface AppDelegate ()
#property (weak) IBOutlet NSWindow *window;
#property (strong) IBOutlet MyController* controller;
#end
#implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
[[[self controller] model] doStuff];
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
}
#end
The main difference comes along when you type something as id <SomeProtocol> and then try to send it a message such as respondsToSelector: and the compiler won't let you. It comes as a surprise - or at least it sure came as a surprise to me - that id <SomeProtocol> is not a form of id. The only messages you can send to such a beast without casting are those defined in the protocol. That's in stark contrast to id plain and simple, which can be sent any known message.
Thus, in my view, as in that of those who know better than I, NSObject <SomeProtocol>* is better, because now this thing is seen by the compiler as an NSObject, and can be sent all the messages declared for NSObject.

View Switching: Unrecognised selector sent to instance

I made some example that changes view by clicking button.
When clicking the "fist" button in view, I keep getting the error:
[__NSArrayM changeLogView:]: unrecognized selector sent to instance 0x100539e30
Here is the simplified code:
DSWAppDelegate.h
#import <Cocoa/Cocoa.h>
#class DSWHomeViewController;
#interface DSWAppDelegate : NSObject <NSApplicationDelegate>
#property (assign) IBOutlet NSWindow *window;
#property (weak) IBOutlet NSButton *logBtn;
#property (weak) IBOutlet NSTabView *tabView;
#end
DSWAppDelegate.m
#import "DSWAppDelegate.h"
#import "DSWLogViewController.h"
#implementation DSWAppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
[self.tabView setTabViewType:NSNoTabsNoBorder];
NSTabViewItem *item = nil;
DSWLogViewController *logvc = [[DSWLogViewController alloc initWithNibName:#"DSWLogViewController" bundle:[NSBundle mainBundle]];
item = [[NSTabViewItem alloc] initWithIdentifier:#"log"];
[item setView:logvc.view];
[self.tabView insertTabViewItem:item atIndex:0];
}
#end
DSWLogViewController.h
#import <Cocoa/Cocoa.h>
#interface DSWLogViewController : NSViewController
#property (weak) IBOutlet NSButton *firstBtn;
#property (weak) IBOutlet NSButton *secondBtn;
#property (weak) IBOutlet NSBox *box;
- (IBAction)changeLogView:(id)sender;
- (IBAction)testSelector:(id)sender;
#end
DSWLogViewController.m
#import "DSWLogViewController.h"
#implementation DSWLogViewController
- (IBAction)changeLogView:(id)sender
{
NSLog(#"changeLogView : %#", sender);
}
- (IBAction)testSelector:(id)sender
{
NSLog(#"testSelector : %#", sender);
}
#end
And I checked class name of file owner.
Something is sending a changeLogView: message to a mutable array instead of your view controller. Chances are, whatever you've connected the IBAction to is pointing to the wrong object - an array of some sort, rather than your view controller.

hide an object from another class

I'm trying to hide an object in my viewController, with code executed from a custom class, but the object is nil.
FirstViewController.h
#import <UIKit/UIKit.h>
#interface FirstViewController : UIViewController {
IBOutlet UILabel *testLabel;
}
#property (nonatomic, retain) IBOutlet UILabel *testLabel;
- (void) hideLabel;
FirstViewController.m
I synthesize testLabel and I have a function to hide it. If I call the function from viewDidAppear it works, but I want to call it from my other class. When called from the other class, testLabel is nil
#import "FirstViewController.h"
#import "OtherClass.h"
#implementation FirstViewController
#synthesize testLabel;
- (void) hideLabel {
self.testLabel.hidden=YES;
NSLog(#"nil %d",(testLabel==nil)); //here I get nil 1 when called from OtherClass
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
OtherClass *otherClass = [[OtherClass alloc] init];
[otherClass hideThem];
//[self hideLabel]; //this works, it gets hidden
}
OtherClass.h
#class FirstViewController;
#import <Foundation/Foundation.h>
#interface OtherClass : NSObject {
FirstViewController *firstViewController;
}
#property (nonatomic, retain) FirstViewController *firstViewController;
-(void)hideThem;
#end
OtherClass.m
calls the hideLabel function in FirstViewController. In my original project, (this is an example obviously, but the original project is at work) I download some data here and I want to hide my loading label and indicator when download is done
#import "OtherClass.h"
#import "FirstViewController.h"
#implementation OtherClass
#synthesize firstViewController;
-(void)hideThem {
firstViewController = [[FirstViewController alloc] init];
//[firstViewController.testLabel setHidden:YES]; //it doesn't work either
[firstViewController hideLabel];
}
Any ideas?
Your UILabel is nil because you just initialized your controller but didn't load it's view. Your controller`s IBoutlets are instantiated from the xib or storyboard automatically when you ask access to the bound view for the first time, so in order to access them you first have to load its view by some means.
EDIT (after OP comments):
Since your FirstViewController is already initialized and your OtherClass is instantiated by that controller, you could just hold a reference to it and not try to initialize a new one.
So try something like this:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
OtherClass *otherClass = [[OtherClass alloc] init];
otherClass.firstViewController = self;
[otherClass hideThem];
}
In your OtherClass.m:
-(void)hideThem {
[self.firstViewController hideLabel];
}

Xcode Storyboard - Transfer of data

I'm new to storyboarding so the answer to this may be simplistic,
I've created a viewController in which a UITextField is present. My test is to transfer the data (text) from that text field into a viewController that is pushed onto the screen.
The coding that i have is as follows:
ViewController1.h -
#import <UIKit/UIKit.h>
#import "ViewController2.h"
#interface ViewController1 : UIViewController
#property (nonatomic, retain) IBOutlet UITextField *inputText;
#end
ViewController1.m
#import "ViewController1.h"
#implementation ViewController
#synthesize inputText;
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"showTextController"]) {
ViewController2 *vc2 = [segue destinationViewController];
vc2.selectedText.text = self.inputText.text;
}
}
#end
ViewController2.h -
#import <UIKit/UIKit.h>
#interface ViewController2 : UIViewController
#property (nonatomic, retain) IBOutlet UILabel *selectedText;
#end
ViewController2.m
#import "ViewController2.h"
#implementation ViewController2
#synthesize selectedText;
#end
The segue between viewController1 and 2 in storyboard is referred to as 'showTextController'.
Is this the correct coding for something so simple? Do i need to be using 'ViewDidLoad' method along with the prepareForSegue:sender method?
It looks correct to me. In fact, this is simpler than we have had in the past since the storyboard takes care instantiating our view controller objects. One thing to note is that if you're using ARC then you shouldn't be retaining your UILabel.
Hope this helps.

Checkbox setState:0 on app launch

I'm having a problem with a checkbox. I want to set it to 0 (unchecked) on app launch, but the checkbox is controlled by another class "myClass" for example.
Here's what I did:
I opened Interface Builder and put a checkbox (NSButton) in my window, dragged NSObject in my MainMenu.xib window, renamed it to say "myClass". Added an outlet called "myCheckbox" (NSButton) and linked it to the checkbox I created earlier. Finally, I added some things.
Here's the code for my myClass.m:
#import "myClass.h"
#implementation myClass
- (void) changeState
{
[myCheckbox setState:0];
}
#end
myClass.h
#import <Cocoa/Cocoa.h>
#interface myClass : NSObject {
IBOutlet NSButton *myCheckbox;
}
- (void) changeState;
#end
Then I made some changes in the AppDelegate files so they execute some things when the app is launched:
#import "UntitledAppDelegate.h"
#import "myClass.h"
#implementation UntitledAppDelegate
#synthesize window;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
myClass * someClass = [[myClass alloc] init];
[someClass changeState];
}
#end
UntitledAppDelegate.h:
#import <Cocoa/Cocoa.h>
#interface UntitledAppDelegate : NSObject <NSApplicationDelegate> {
NSWindow *window;
}
#property (assign) IBOutlet NSWindow *window;
#end
The purpose (if this works) is to set a value to the check box depending on the setting stored in the Defaults file.
The problem might be easy or too simple but I'm only a beginner...
Some help would be appreciated, Thanks !
- (void) awakeFromNib
{
[myCheckbox setState:0];
}
in myClass.m solved it.

Resources