I'm trying to make a simple Cocoa application using the newest version of XCode. In interface builder I added NSTextField and NSButton. When I press the button, I want it to clear whatever is in the text field.
I made a new class called AppController.h. This is the contents:
#import <Foundation/Foundation.h>
#interface AppController : NSObject {
IBOutlet id textView;
}
- (IBAction) clearText: sender;
#end
AppController.m looks like this:
#import "AppController.h"
#implementation AppController
- (IBAction) clearText: sender
{
[textView setString: #" "];
}
#end
I connected the button to clearText and the textbox to textView.
The program compiles and runs. But when I press the button, nothing happens. Why is that?
here's the run down.
1.Create an IBAction in your appController class header.
- (IBAction)someMethod:(id)sender;
2.Then create an IBOutlet for you text field
IBOutlet NSTextField *textFieldname;
You then connect the IBAction to the button in interface builder, and your IBOutlet to your textfield.
Inside the implementation file (.m) IBAction method do
- (IBAction)someMethod:(id)sender{
textFieldname.stringValue = #"";
}
This is very basic. I suggest you google for some tutorials. There's plenty out there. Here's something that may help. Chapter 8 describes how to do exactly what you're asking.
link text
Related
I have a problem with a protocol.
My "initial View Controller" is a Navigation Controller. On the root page i show an other Navigation Controller in which is View Controller embedded. onclick a segue should be fired...this works perfectly but the delegate method from the "ViewController" is never called.
The image I added is a example how I build the connection between the 2 NavigationControllers with the InterfaceBuilder in iOS 5.
MyViewController.h
#protocol MyProtocol <NSObject>
#required
- (void) myFunction:(NSString *)string;
#end
#interface MyViewController : UIViewController <MyProtocol>
#property (nonatomic, assign) id<MyProtocol> delegate;
#end
MyViewController.m
#import "MyViewController.h"
#implementation PropertyController
#synthesize delegate = _delegate;
- (void) myFunction:(NSString *)string {
[_delegate myFunction:string];
}
- (IBAction) callDelegate:(id)sender {
![enter image description here][1][self myFunction:#"test"];
}
And this is the code for the ViewController which is showing the NavigationController from above
ViewController.h
#import "MyViewController.h"
#interface ViewController : UIViewController <MyProtocol>
ViewController.m
#import "ViewController.h"
#implementation ViewController
- (void) myFunction:(NSString *)string {
NSLog(#"myFunction was called");
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
[((MyViewController *) segue.destinationViewController) setDelegate:self];
}
- (IBAction) showModalNavigationController {
[self performSegueWithIdentifier:#"NameFromSegueInInterfaceBuilder" sender:self];
}
I cant find a solution for my problem.
I hope somebody can help me
thank you :)
I see a couple of problems here:
In your storyboard screenshot, you have a second navigation controller. You should not not need to embed your PropertyController in a navigation controller. Instead, have the root view controller segue directly to the PropertyController. If for some reason you do need that navigation controller, then you would need to change your prepareForSegue implementation above, because segue.destinationViewController in this case points to the UINavigationController. So you would need to get that nav controller object, and then send setDelegate to the rootViewController of that nav controller object. But again, only if you decide to keep that navigation controller.
How does MyViewController relate to your ViewController and PropertyController classes? The PropertyController class (or a superclass) needs to have the #property and synthesize statements for the delegate property.
I've been having the same issue, to make it work, I found a work around which xcode does not really like, but it still is working though --> setting your delegate as you do it, makes your navigation controller have your view as delegate, if you NSLog self.delegate in your destination controller it will be null. To prevent this do -->
self.delegate = self.navigationController.delegate;
in your destination controller (viewdidload), it will get the delegation you created on the navigation controller, and allow you yo use it in your destination controller
It is dirty but it's the only way I found. Hope it helps.
I have a little problem and hope that you can help me.
I want to call a instance method of a subclassed window and set the user interface up there:
//AppDelegate.h
#import <Cocoa/Cocoa.h>
#class MainView;//The main window
#interface DownloadedAppDelegate : NSObject <NSApplicationDelegate> {
IBOutlet MainView*mainview;//the objects are in the same nib, outlet connected with the window
}
#property(nonatomic,retain) IBOutlet MainView*mainview;
#end
.
//AppDelegate.m
#import "MainView.h"
#synthesize mainview;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[mainview launched];//But sometimes this code fails, I don't know why
//launched sets up the interface
}
-(void)dealloc {
mainview=nil;
}
MainView belongs to NSWindow.
Is there something wrong or something to improve? Should I build up the UI somewhere else? Do you know why this code does not work always?
Try putting
[mainview launched];
in
-(void)awakeFromNib {
}
Use the debugger! Is launched even getting called?
Set a break point at the launched call and look at the value of mainview. It is nil? This is because outlets are not guaranteed to be connected until awakeFromNib.
I'm trying to make a simple Cocoa application using XCode 3.2.3. In interface builder I added NSTextField and NSButton. When I press the button, I want it to clear whatever is in the text field.
I made a new class called AppController.h. This is the contents:
#import <Foundation/Foundation.h>
#interface AppController : NSObject {
IBOutlet id textView;
}
- (IBAction) clearText: sender;
#end
AppController.m looks like this:
#import "AppController.h"
#implementation AppController
- (IBAction) clearText: sender
{
[textView setString: #" "];
}
#end
I connected the button to clearText and the textbox to textView.
The program compiles without error and runs. But when I press the button, nothing happens. Why is that?
Using id for an IBOutlet is a bad practice. Use
IBOutlet NSTextView* textView;
instead.
Please check using the debugger, or putting NSLog(#"foo!"); before [textView setString:#""] to see if the action method is really called.
Another pitfall is that there are NSTextView and NSTextField. These two are different!
The former supports both setString: and setStringValue:, while the latter only supports setStringValue:.
Which object did you use in the interface builder?
I've been through a bunch of Core Data examples and the Apple documentation. I'm at a wall after working on this all day.
All I want to happen is I type some text into a text field, save the file, open it again and see the text there.
I made a very very simple Core Data document-based app to experiment. Here are the particulars:
1) The data model has one Entity ("Note") with one attribute ("title") which is an NSString.
2) I created a view controller "ManagingViewController" that loads in a view called "NoteView" into a box in MyDocument.xib without a problem. NoteView.nib has just one NSTextField in it.
ManagingViewController.h
#import <Cocoa/Cocoa.h>
#import "Note.h"
#interface ManagingViewController : NSViewController {
NSManagedObjectContext *managedObjectContext;
IBOutlet NSTextField *title;
}
#property (retain) NSManagedObjectContext *managedObjectContext;
#property (retain, readwrite) NSTextField *title;
#end
and ManagingViewController.m
#import "ManagingViewController.h"
#import "Note.h"
#implementation ManagingViewController
#synthesize managedObjectContext;
#synthesize title;
- (id)init
{
if (![super initWithNibName:#"NoteView" bundle:nil]) {
return nil;
}
return self;
}
#end
I have a NSManagedObject called "Note.h"
#import <CoreData/CoreData.h>
#import "ManagingViewController.h"
#interface Note : NSManagedObject
{
}
#property (nonatomic, retain) NSString * title;
#end
and the .m file:
#import "Note.h"
#import "ManagingViewController.h"
#implementation Note
#dynamic title;
#end
In NoteView.nib my:
1) File's Owner is ManagingViewController and the IBOutlets to the Text Field and the view are connected.
2) I dragged over an NSObjectController object into the Interface Builder document window called "Note Object Controller". I set mode to "Entity" and the Entity Name to "Note". "Prepares content" and "Editable" are checked on. (All the examples I've done and been able to find use an NSArrayController here. I don't need an array controller right? I do want to be able to open multiple windows for the same app but I still don't think I need an arraycontroller? All the examples have a NSTableView and a add button. There's no need for an add button here since I don't have an NSTableView).
3) The NSTextView bindings for value I have it bound to "Note Object Controller" with a controller key of representedObject and a Model Key Path of title.
When I run my app I get
[<NSObjectController 0x20004c200> addObserver:<NSTextValueBinder 0x20009eee0>
forKeyPath:#"representedObject.title" options:0x0 context:0x20009f380] was
sent to an object that is not KVC-compliant for the "representedObject" property.
What am I doing wrong? I want to type in the text field, save the file, open it again and see the text there.
[<NSObjectController 0x20004c200> addObserver:<NSTextValueBinder 0x20009eee0> forKeyPath:#"representedObject.title" options:0x0 context:0x20009f380] was sent to an object that is not KVC-compliant for the "representedObject" property.
What am I doing wrong?
The error message tells you what you're doing wrong: You're trying to bind to the representedObject property of your object controller, but it doesn't have one. Binding to properties that don't exist cannot work.
The Note is the content object of the NSObjectController, so that's the controller key you need to bind to: content.
I am trying to respond to a click within a textfield. When the click occurs, I am going to open a panel. My initial thought was to use a delegate method to respond to the click event - but I found that:
This method doesn't work:
(void)textDidBeginEditing:(NSNotification *)aNotification
This method does work, but only when I actually edit the text within the text field, not when I first click it. And - if I edit the text a second time, this method stops working:
(void)controlTextDidBeginEditing:(NSNotification *)aNotification
I could use as much detail as possible - or a code example, ideally. I know that an nstextfield inherits from NSControl, which has a mouseDown event. Is there a similar way to respond to the event with a textfield, also?
Since NSTextField inherits from the NSControl class, it also inherits the -(void)mouseDown:(NSEvent*) theEvent method.
I needed to have an NSTextField call a delegate function upon clicking it today, and thought this basic code might be useful. Note that NSTextField already has a delegate and that in SDK v10.6, the delegate already has a protocol associated with it. Note that if you don't care about protocols, compiler warnings, etc., you don't need the protocol and property declarations or the getter and setter.
MouseDownTextField.h:
#import <Appkit/Appkit.h>
#class MouseDownTextField;
#protocol MouseDownTextFieldDelegate <NSTextFieldDelegate>
-(void) mouseDownTextFieldClicked:(MouseDownTextField *)textField;
#end
#interface MouseDownTextField: NSTextField {
}
#property(assign) id<MouseDownTextFieldDelegate> delegate;
#end
MouseDownTextField.m:
#import "MouseDownTextField.h"
#implementation MouseDownTextField
-(void)mouseDown:(NSEvent *)event {
[self.delegate mouseDownTextFieldClicked:self];
}
-(void)setDelegate:(id<MouseDownTextFieldDelegate>)delegate {
[super setDelegate:delegate];
}
-(id)delegate {
return [super delegate];
}
AppDelegate.h:
#interface AppDelegate <MouseDownTextFieldDelegate>
...
#property IBOutlet MouseDownTextField *textField;
...
AppDelegate.m:
...
self.textField.delegate = self;
...
-(void)mouseDownTextFieldClicked:(MouseDownTextField *)textField {
NSLog(#"Clicked");
...
}
...
If you're building with 10.5 SDK, don't have the protocol inherit from NSTextFieldDelegate.