I'm going through some tutorial for editing table cells whose data is stored in a server. Everything is working fine - I can edit a table cell and click on the "save" button, but if I go back to the table overview it's not updated.
I've got 3 table fields:
titleField
authorField
atextField
I don't know if the problem comes from this piece of code, but I suppose so. The tutorial example has just 2 fields, and I need 3 fields, but I don't know how to implement this piece of code for 3 textfields:
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
if (textField == titleField) {
[authorField becomeFirstResponder];
}
if (titleField == authorField) {
[self save];
}
return YES;
}
I already tried if (titleField == authorField == atextField), but the error message says: Comparison between pointer and integer ('int' and 'UITextField'). I also tried if (titleField == authorField && titleField == atextField && authorField == atextField){and I don't get an error, but it doesn't change the fact that the data doesn't update the changes.
How should the code above look like?
Those IF's dont have sense, you cannot do this:
if (titleField == authorField == atextField)
Because you are comparing the result of the first == with the textfield, hence the Comparison between pointer and integer error.
In the 2nd one,
if (titleField == authorField && titleField == atextField && authorField == atextField)
This is never going to get called, because the titleField cannot be 3 things at the same time.
My first thought would be doing something like this:
if (textField == titleField) {
[authorField becomeFirstResponder];
}
else if ((textField == authorField){
[atextField becomeFisrtResponder];
else if (titleField == atextField) {
[self save];
}
I think this is what you want to do.
Related
I am writing a thread that should be stopped if a button is pressed.
This means that for every action that I do, I also want to check if the stop flag is set so I can stop properly.
This is a piece of the code which should make it clearer:
while([self checkForDrop] != 0 && STOP == FALSE){
sleep(0.4);
} if (STOP == TRUE){
return 99;
}
ret = [self doSomething]
if(ret == 0){
[self updateStatus]
} else {
printf("%d", ret) // Print error
}
ret = [self doSomethingElse]
if(ret == 0){
[self updateStatus]
} else {
printf("%d", ret) // Print error
}
... and so on ...
Every time I do something, I want to also check if a condition is met (STOP == TRUE), if it is, the program should return 99 and stop.
I could write an if statement for every line, but that would make the code unreadable and ugly. I would guess that I am not the only one that stumbled upon this, so there should be a better way.
I am practicing some bool functions and I seem to be stuck any help will be appreciated. I must be making some little mistake.
-(BOOL) checkForWin
{
if ([[dictionary valueForKey:[cowsShuffled objectAtIndex:cowsCard]] intValue] == 2{
return YES;
}
}
-(void) moo
{
if (checkForWin == YES) {
NSLog (#"foo");
}
}
You need to call the method (not function), and you don't need to compare to YES. The if statement does that implicitly:
if ([self checkForWin]) …
Also note that checkForWin has a problem: it doesn't return anything if the if statement fails. It should be simply:
- (BOOL)checkForWin{
return [[dictionary valueForKey:[cowsShuffled objectAtIndex:cowsCard]] intValue] == 2;
}
Footnote: Strictly speaking, if (x) … isn't exactly the same as if (x == YES) …. It's actually closer to if (x != NO) …, but of course that's the same thing for most intents and purposes (and those for which it isn't are largely pathological).
Your method call is wrong. You call a method like this: [object method].
In your case [self checkForWin].
I'm trying to validate dynamically created text fields. The total number of textfields may vary.
The idea is to populate the empty fields with string like player 1, player 2 etc.. Here is what I try
-(IBAction)validateTextFields:sender
{
self.howManyPlayers = 3;
int emptyFieldCounter = 1;
NSMutableArray *playersNames = [NSMutableArray arrayWithCapacity:self.howManyPlayers];
while (self.howManyPlayers > 1)
{
self.howManyPlayers--;
UITextField *tmp = (UITextField *) [self.view viewWithTag:self.howManyPlayers];
if (tmp.text == nil)
{
[tmp setText:[NSString stringWithFormat:#"Player %d", emptyFieldCounter]];
emptyFieldCounter++;
}
[playersNames addObject:tmp.text];
}
}
The problems is that if I touch the button which invoke validateTextFields method. The first and the second textfield are populated with text Player 1 and Player 2, but the third field is not populated.
I notice also that if I type a text let's say in the second field touch the button then remove the text and again touch the button that field is not populated with text Player X.
How to make all that things to work correctly ?
change your code for two lines like this:
while (self.howManyPlayers >= 1) //edited line
{
UITextField *tmp = (UITextField *) [self.view viewWithTag:self.howManyPlayers];
if (tmp.text == nil)
{
[tmp setText:[NSString stringWithFormat:#"Player %d", emptyFieldCounter]];
emptyFieldCounter++;
}
[playersNames addObject:tmp.text];
self.howManyPlayers--; // moved line
}
I forgot ur second question, so edited my answer.
For that try with this. Change if (tmp.text == nil) with if (tmp.text == nil || [tmp.txt isEqualToString:#""])
The reason only two fields are populated is that you are only going through the while loop twice. It should be
while (self.howManyPlayers >= 1)
You should also move the decrement to the end of your while loop
while (self.howManyPlayers >= 1)
{
// other code here
self.howManyPlayers--;
}
For the second part of your question, I think when you delete the text from the control, it stops being nil and now becomes an empty string. So you need to check for an empty string as well as nil in your code.
if (tmp.text == nil || [tmp.txt isEqualToString:#""])
if (menuPlayed == TRUE && [sender tag == 0]) {
NSLog(#"You're pressing the right button at the right time");
}
Any idea why this is throwing up a "Expected "]
"" error? I have absolutely no idea what's wrong with those comparisons :(
Change:
if (menuPlayed == TRUE && [sender tag == 0])
to:
if (menuPlayed == TRUE && [sender tag] == 0)
Also note that you should never write expressions such as menuPlayed == TRUE - always write this as just menuPlayed, i.e. in this particular case:
if (menuPlayed && [sender tag] == 0)
And as mentioned in #rokjarc's answer, you might want to add some parentheses for clarity, although these are not actually required:
if (menuPlayed && ([sender tag] == 0))
Change your code to:
if ((menuPlayed == TRUE) && ([sender tag] == 0))
And you'll probably have to typecast sender, something like
if ((menuPlayed == TRUE) && ([(UIButton *)sender tag] == 0))
Ofcourse you shouldn't just use (UIButton *) for typecast.
Use the correct class of your sender object or use one
of it's ancestor classes. I believe 'tag' is added to
UIView in this object hierarchy.
I want to use a wrapping text field that can potentially contain carriage returns in my app. Is there any way to force the NSTextField object to write a carriage return into the text area instead of sending its action to its target when the Return key is pressed?
This is covered in Technical Q&A QA1454, which also enumerates reasons why one would use NSTextField instead of NSTextView in this case.
You can implement the following method in the text field delegate:
- (BOOL)control:(NSControl*)control
textView:(NSTextView*)textView
doCommandBySelector:(SEL)commandSelector
{
BOOL result = NO;
if (commandSelector == #selector(insertNewline:))
{
// new line action:
// always insert a line-break character and don’t cause the receiver
// to end editing
[textView insertNewlineIgnoringFieldEditor:self];
result = YES;
}
return result;
}
Okay, I figured out one way to do it, but this very well may not be the best (or even a good) way. I subclassed NSTextField, and overrode -textShouldEndEditing: like so:
-(BOOL)textShouldEndEditing:(NSText *)textObject {
NSEvent * event = [[NSApplication sharedApplication] currentEvent];
if ([event type] == NSKeyDown && [event keyCode] == 36) {
[self setStringValue:[[self stringValue] stringByAppendingString:#"\n"]];
return NO;
}
else {
return [super textShouldEndEditing:textObject];
}
}
I found a combination of Sean and Bevarious worked best for me. Sean's answer assumes that the new line is always wanted to be added to the end (instead of for instance where the user's cursor is placed).
-(BOOL)textShouldEndEditing:(NSText *)textObject
{
NSEvent * event = [[NSApplication sharedApplication] currentEvent];
if ([event type] == NSKeyDown && [event keyCode] == 36)
{
[textObject insertNewlineIgnoringFieldEditor:nil];
return NO;
}
else
{
return [super textShouldEndEditing:textObject];
}
}
Swift version:
override func textShouldEndEditing(textObject: NSText) -> Bool {
let event = NSApplication.sharedApplication().currentEvent
if event?.type == NSEventType.KeyDown && event?.keyCode == 36 {
self.stringValue = self.stringValue.stringByAppendingString("\n")
return false
} else {
return super.textShouldEndEditing(textObject)
}
}