3
votes

I'm trying to figure out a way to bring up the keyboard when an SKLabelNode is tapped and then having that label be editable, similar to UITextView or UITextField.

I've already added a UITextView to the SKScene but as that sits on top of the scene, it's a fairly clunky solution. I'd rather try one of two things: 1. Keyboard appears when sklabelnode is tapped, or as a worst case - keyboard is always up and any input reflects on the SkLabelNode.

In order to not reinvent the wheel, is there a way an SKLabelNode can be customized to act more like UITextView or UITextField?

Answers in Objective-C or Swift would be fine.

1

1 Answers

3
votes

What you are saying comes very close to reinventing the wheel. SKLabelNode, as the name suggests, is not meant to act like a text field. The biggest problem here is triggering the keyboard and transferring any input to the label node.

Here's a workaround. You can maintain a UITextField and keep it hidden on the SKView. It's purpose is to handle input from the keyboard, which shall be reflected on the SKLabelNode.

The following code needs to be added the SKScene class. It works, and I have verified it myself.

CODE

Maintain an instance variable for a UITextField. I am assuming the label node is also accessible from anywhere within the class.

UITextField *field;
SKLabelNode *labelNode; //For demonstrative purposes 

Handle touch on the SKLabelNode as follows

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInNode:self];

    SKNode *node = [self nodeAtPoint:point];
    if ([node isEqual:labelNode])
    {
        if (field == nil)
        {
            field = [[UITextField alloc]initWithFrame:CGRectMake(10, 10, 100, 30)];
            field.delegate = self;
            field.hidden = true;
            [self.view addSubview:field];
        }

        field.text = labelNode.text;
        [field becomeFirstResponder];

    }
    else
    {
        [field resignFirstResponder];
        //To hide keyboard when tapped outside the label.
    }
}

Notice that we are setting the UITextField's delegate to self. This has been done so we can get the text from the text field as it is being edited in the following method.

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
    labelNode.text = newString;
    return YES;
}

NOTE that you have to implement the UITextFieldDelegate in the scene's header file.

@interface MyScene : SKScene <UITextFieldDelegate>

A WORD OF WARNING

While the aforementioned workaround might achieve what you are describing in the question, SKLabelNode still cannot act as an effective tool for editing text due to the lack of various visual aids that go along with the same (Eg. cursor, highlighting, etc).

It would still be best to use UIKit for forms and text editing.