2

I want to put something like this in a method for UITextField & UITextView.

- (void)changeKeyboardType:(UIKeyboardType)keyboardType {
    paymentTextView.keyboardType = UIKeyboardTypeAlphabet;
    [paymentTextView resignFirstResponder];
    [paymentTextView becomeFirstResponder];
}

How do I do this? I know I can create categories for both UITextField & UITextView but is it possible to do it in one shot?

By one shot, I mean add it to both classes with one protocol instead of making two categories, one for UITextView & one for UITextField. I've heard a protocol is similar to a Ruby module, but in a Ruby module, I can implement the method. In a protocol, it only seems that I can declare the method but not implement it. Can I also implement the method in the protocol, and then include this protocol in UITextField & UITextView?

How to add a method to an existing protocol in Cocoa? is close but not quite.

Community
  • 1
  • 1
ma11hew28
  • 121,420
  • 116
  • 450
  • 651
  • why do you need a category for this? You coud do this with a simple method too, just pass the textfield or textview in as a parameter. – Nick Weaver May 25 '11 at 20:16
  • @Nick Weaver, I don't need a category, but making a category and then including the category in the `.pch` file allows me to easily reuse the same method in any file. – ma11hew28 May 26 '11 at 00:16

3 Answers3

4

What about something like this?

// UIView+UITextInputTraits.h

@interface UIView (UITextInputTraits)
- (void)changeKeyboardType:(UIKeyboardType)keyboardType;    
@end


// UIView+Additions.m

#import "UIView+UITextInputTraits.h"

@implementation UIView (UITextInputTraits)

- (void)changeKeyboardType:(UIKeyboardType)keyboardType {
    if ([self conformsToProtocol:@protocol(UITextInputTraits)]) {
        id<UITextInputTraits> textInput = (id<UITextInputTraits>)self;
        if (textInput.keyboardType != keyboardType) {
            [self resignFirstResponder];
            textInput.keyboardType = keyboardType;
            [self becomeFirstResponder];
        }
    }
}

@end
ma11hew28
  • 121,420
  • 116
  • 450
  • 651
3

For each of these, you can create a category.

Interface file:

@interface UITextField (ChangeKeyboard)
- (void)changeKeyboardType:(UIKeyboardType)keyboardType;
@end

Implementation file:

@implementation UITextField (ChangeKeyboard)
- (void)changeKeyboardType:(UIKeyboardType)keyboardType {
    self.keyboardType = keyboardType;
    [self resignFirstResponder];
    [self becomeFirstResponder];
}
@end

That would be the way to add these, but I haven't tested the functionality.

Andrew Pouliot
  • 5,423
  • 1
  • 30
  • 34
  • Thanks. That's what I was thinking. But, I'll have to do that for `UITextView` as well, so I was wondering how to do this in one shot. I figured out a [solution to do it in one shot](http://stackoverflow.com/questions/6130315/how-to-add-a-method-to-uitextfield-uitextview/6132880#6132880). However, your solution, although it takes more code and is less extensible, is more straight forward and easier to understand. – ma11hew28 May 29 '11 at 18:51
0

Like @Josh said, method swizzling isn't what you are looking for. However what I actually had in mind (My bad for not researching more into it before submitting an answer) is to add method at runtime on UITextView and UITextField. While this needs a bit more code to implement, it can give you the sort of one-shot you are looking for (You create a method and add it to both UITextView & UITextField at run-time)

Here's a blog post about it:

http://theocacao.com/document.page/327

http://www.mikeash.com/pyblog/friday-qa-2010-11-6-creating-classes-at-runtime-in-objective-c.html

Pier-Olivier Thibault
  • 3,907
  • 2
  • 33
  • 33
  • Swizzling doesn't really apply here since he's trying to add a method, not change an existing one. – jscs May 25 '11 at 20:49
  • By one shot, I meant add it to both classes with one protocol instead of making two categories, one for `UITextView` & one for `UITextField`. I've heard a protocol is similar to a Ruby module, but in a Ruby module, I can implement the method. In a protocol, it only seems that I can declare the method. Can I also implement the method in the protocol? Anything is possible. – ma11hew28 May 26 '11 at 00:21
  • You can only define method using protocols like you said. As for what @josh said, he's right. Method Swizzling wasn't what I was looking for either. I kinda rushed my answer here. I'll update it – Pier-Olivier Thibault May 26 '11 at 12:30