Set label title from mouseEntered in objective-c - objective-c

I have this code in my NSButton subclass:
-(void)mouseEntered:(NSEvent *)theEvent{
NSLog(#"ENTER");
NSString *myString = #"foo";
[myTextField setStringValue:myString];
}
-(IBAction)changeStringValue:(id)sender{
NSString *myString = #"foo";
[myTextField setStringValue:myString];
}
The IBAction works fine but the same method of myTextField called inside the mouseEntered event doesn't work. The event is working (except setString), in fact I can see the NSLog and if I insert NSLog(#"%#", myTextField.stringValue);, it says null.
Does anyone have a clue?
Edit: I noticed that the previous stringValue NSLog, if inserted in -(void)awakeFromNib{...}, occours 2 times even if there's only one button of MyButton class: one time it's correct and the other time it's null. I'm a little bit confused.
Edit2: i've inserted [self performSelectorOnMainThread:#selector(changeStringValue:) withObject:myTextField waitUntilDone:YES]; inside the mouseEnter: event and NSLog(#"Running"); inside the changeStringValue function: now hovering the button i call the function (i see the "running" log) but nothing happens. The function, as a Sent Action assigned to a button, is still working. I've also tried with waitUntilDone:YES/NO and withObject:myTextField/self but it's the same.

Related

How does (id)sender work in cocos2d?

The following code works good for me:
In the init method of a menu layer:
CCMenuItemFont *item1 = [CCMenuItemFont itemWithString:#"Level 1" target: self selector: #selector(startLevel:)];
item1.userData = (__bridge void*) ([NSNumber numberWithInt:1]);
...//create menu and add in the item1
-(void)startLevel: (CCMenuItem *)sender
{
NSNumber *number = sender.userData;
...
}
My questions are:
I didn't pass item1 when call the method startLevel: how does it know that the sender is item1?
is it written into selector? or is it written in cocoa?
CCMenuItem passes itself as parameter to this selector. Details are in CCMenuItem source code.
Regarding omitting passing itself as a parameter, do you mean like...
- (void) pushedStart : (id) sender
{
//start game
}
but you can't do
[self pushedStart];
because it needs a parameter? If so, what you can do this:
id junkID;
[self pushedStart: junkID];
JunkID will initialize to whatever the hell it is an unassigned ID assigns to, so you pass it as a reference and just don't use it for anything, which is good if you want to have a "start game" button but have the game automatically start inside of a timer or whatever else you're doing with your buttons
As a side note, and getting more into the guts of cocoa, the way it KNOWS (and what YOU must not forget) is that colon. When you call a function you put the variable after a colon [self eat: food];
When you put together the menu item you set it up with target:self, which makes the button use itself (not the layer "self" you use when you call [self eatABanana]) as a target. The button push of
menuButton = target:self selector:#selector(pushButton:)
is represented like
[self pushButton:menuButton]
If you forgot that colon, it's the same as calling a function and not passing the variable, which doesn't give a very helpful error message insofar as it doesn't help you locate where the problem is occurring. I've spent hours upon hours chasing down memory crashes resulting from writing #selector(startGame) instead of #selector(startGame:) in those damn menu buttons. I always feel stupid when I finally figure it out.

Why can I not reset a text field within an IBAction associated with it?

I have an IBAction called keyboardResponse associated with a text field called myTextFieldIBOutlet via the "Editting Changed" event handler in the xib:
- (IBAction)keyboardResponse:(id)sender
{
// process this single character - function I wrote else where that works fine.
[self processSingleCharacter:myTextFieldIBOutlet.text];
// clear input text
myTextFieldIBOutlet.text = #"";
}
It's supposed to clear the input after the user types something into it.
I get a run time error with this code in iOS Simulator:
Thread 1: EXC_BAD_ACCESS (code=2, address=0xbf7fff0c)
Why? I had synthesized the IBOutlet myTextFieldIBOutlet already.
if myTextFieldIBOutlet is synthesized, you should change the last line to:
self.myTextFieldIBOutlet.text = #"";
If the textfield you want to clear is the same control that calls this action, you can also use the sender variable you are sending
[sender setText:#""];

String Problems

A very stupid question from a noob.
I have an action, that sets the string of a label.
- (IBAction) changeProductText:(NSString *)str{
lblProductTxt.text = str;
}
This is the string I want to set that to:
TestText = [NSString stringWithFormat:#"Hi"];
And this is how I am doing it:
[self.navigationController pushViewController:nextController animated:YES];
[nextController changeProductText:TestText];
My problem is that it wont set the string to anything is random whats going into the string. It may crash when I click on the cell it may not, so I am doing something wrong.
stringWithFormat gives you an autoreleased format, without seeing more of the code I'm guessing its hitting an autorelease pool and you're trying to access garbage that was your string.
Is this the exact sequence of the statements?
[self.navigationController pushViewController:nextController animated:YES];
[nextController changeProductText:TestText];
I am not 100% sure but I believe that the second line will not be executed before the nextController is being pushed.
Try to reverse them.
(1st create and initialize the nextController)
2nd assign all values that you want to pass down to nextController
3rd push nextViewController on the stack of View Controllers.
[nextController changeProductText:TestText];
[self.navigationController pushViewController:nextController animated:YES];
The only parameter of an IBAction is the sender:
- (IBAction) clickMyButton: (id) sender;
A string is hardly a valid sender for an action, so whatever you are setting to lblProductTxt.text, it is not a string, it is the sender that performs the action.
In your action method, you can of course set lblProductTxt.text. You'll have to find out yourself where you get the string.
Update
From your comments I deduce you don't have an IBAction, you simply have a void method. Your use of IBAction got me on the wrong foot. Declare it like:
- (void) changeProductText: (NSString *) newText;
Omit the (IBAction) designator, as that is only necessary for, well, real IB action methods.
No matter if you use
NSString *testText = [NSString stringWithFormat: #"Hi"];
or
NSString *testText = [NSString stringWithString: #"Hi"];
The result is exactly the same: an autoreleased NSString with the text "Hi". Only the way it was created is slightly different. If one works and the other crashes, then the same thing is wrong and you are just lucky it doesn't crash.
Now what is wrong is impossible to see from what you posted so far.

Drag and drop between nstableviews in nscollectionview sets window controller property to nil?

In the main window of my application, I have a collection view such that each collection view item contains an NSTableView. The window controller for this window has an NSString * property projecttitle. This property is bound to an NSTextField in the window for which I have overridden the default return key behavior so that the user can hit Return and write a carriage return into the text field. Now, after changing the string in the text field and THEN dragging an item between the table views for two different collection view items, the projecttitle property becomes nil. I sort of feel like maybe I just have way too much going on here and that this bug will be impossible to track down, but maybe someone has seen something even remotely similar to this behavior elsewhere?
EDIT: Putting a breakpoint on the projecttitle property doesn't seem to yield anything useful. The program execution does not break at all upon dragging and dropping, but the property will indeed be nil after this.
EDIT 2: After more digging around, it appears the behavior is related to the NSFormatter object. It happens not only when dragging and dropping, but apparently any time the nstextfield attempts to resign as responder. This behavior stops when I disconnect the formatter object in IB. Here's the string validation code for the formatter which forces the string to be less than or equal to 4 lines long and with each line being no longer than 32 characters. This seems to work fine when actually typing the in the text field, but apparently, not after.
-(BOOL)isPartialStringValid:(NSString **)partialStringPtr
proposedSelectedRange:(NSRangePointer)proposedSelRangePtr
originalString:(NSString *)origString
originalSelectedRange:(NSRange)origSelRange
errorDescription:(NSString **)error {
NSArray * lines = [*partialStringPtr componentsSeparatedByString:#"\n"];
if ( [lines count] > 4 ) {
return NO;
}
for (NSString * line in lines) {
if ( [line length] > self.maxlength ) {
return NO;
}
}
return YES;
}
Okay, solved. Turned out it was the -getObjectValue:forString:errorDescription: method. I had it implemented as
-(BOOL)getObjectValue:(id *)obj forString:(NSString *)string errorDescription:(NSString **)error {
*obj = string;
return YES;
}
Changing *obj = string to *obj = [NSString stringWithString:string] fixed everything right up.

Objective C unable to update UILabel more than once

I have a method which I created that appends some new text to a UILabel. I've tried two ways of doing this (one is commented out) but both of them only update the label the first time. Any more calls to this method do not update the label.
- (void) updateLog: (NSString*) text
{
/*
NSMutableString *newText = [logLabel.text mutableCopy];
[newText appendString: text];
logLabel.text = newText;
*/
logLabel.text = [logLabel.text stringByAppendingFormat:#"%#", text];
}
I am calling the method like this (the method is in the viewController):
[viewController updateLog: #"\nStarting...\n"]; // Works
[viewController updateLog: #"Test\n"]; // Does not work
I have searched everywhere for an answer, what am I missing? Thanks!
UILabel, unless set up otherwise, only displays a single line of text.
Change the numberOfLines property if you want more.
I actually figured this out. Turns out the string WAS being successfully updated, but the label size was too small, so the text was hidden.