Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 03-16-2009, 07:49 AM   #1 (permalink)
New Member
 
Join Date: Mar 2009
Posts: 5
splitbrain is on a distinguished road
Question Subclassing UITextField / Delegate

Hi

I want to attach certain functionality to UI elements and to make it easier reusable I'd like to subclass the original UI elements. But it looks I'm missing something.

Here's what I did:

Code:
#import <UIKit/UIKit.h>
@interface UIMyField : UITextField <UITextFieldDelegate> {

}

- (id)initWithFrame:(CGRect)frame;
@end

Code:
#import "UIMyField.h"
@implementation UIMyField

- (id)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        self.delegate = self;
    }
    self.text = @"init";
    return self;
}

- (void)textFieldDidBeginEditing:(UITextField *)textField {
    textField.text = @"foo";
}

- (void)dealloc {
    [super dealloc];
}
@end
I then changed the class of a textfield in InterfaceBuilder to MyField but it seems that neither the initWithFrame nor the textFieldDidBeginEditing is ever called. What did I miss? Is there an example on how to subclass and extend core UI elements somewhere?
splitbrain is offline   Reply With Quote
Old 03-16-2009, 09:38 AM   #2 (permalink)
Registered Member
 
Join Date: Feb 2009
Posts: 7
beowulf573 is on a distinguished road
Default

Try

Code:
- (id)initWithCoder:(NSCoder *)inCoder;
beowulf573 is offline   Reply With Quote
Old 03-16-2009, 09:54 AM   #3 (permalink)
New Member
 
Join Date: Mar 2009
Posts: 5
splitbrain is on a distinguished road
Talking works

Excellent, initWithCoder worked :-). I assume initWithCoder is used when the class is instantiated by the InterfaceBuilder and initWithFrame when instantiating it yourself?

Thanks for your help.

Code:
- (id)initWithCoder:(NSCoder *)inCoder {
    if (self = [super initWithCoder:inCoder]) {
        self.delegate = self;
    }
    self.text = @"initcoder";
    return self;
}
splitbrain is offline   Reply With Quote
Old 03-16-2009, 10:51 AM   #4 (permalink)
New Member
 
Join Date: Mar 2009
Posts: 5
splitbrain is on a distinguished road
Unhappy keyboard use freezes application

Hmm looks like I called success too early :-( For some reason the program now freezes when I press a keyboard button.

The culprit seems to be the self delegation:

Code:
self.delegate = self;
Removing the line restores the keyboard functionality but my textFieldDidBeginEditing doesn't work anymore of course.

So what's the proper way to attach a default handler to this event to my subclass?
splitbrain is offline   Reply With Quote
Old 03-16-2009, 03:24 PM   #5 (permalink)
Registered Member
 
Join Date: Feb 2009
Posts: 7
beowulf573 is on a distinguished road
Default

I was doing the exact same thing this weekend and ran into locking issues when implementing an empty shouldChangeCharactersInRange message. So far I've not come up with a solution but did read of other people experiencing it.
beowulf573 is offline   Reply With Quote
Old 06-22-2009, 01:44 PM   #6 (permalink)
New Member
 
Join Date: Jun 2009
Posts: 1
CowTipper is on a distinguished road
Default

i don't think delegates were ever intended to be sent to self. if you're looking at creating a default handler that will be used whenever any instance of your subclassed UITextField is loaded, you can try making a small handler class, and then have it set that class as its delegate on init, ie:.

SomeClass.h:

Code:
@class DefaultHandlerClass

@interface SomeClass : UITextField

{
   DefaultHandlerClass *dClass;
}

@property (nonatomic,retain) DefaultHandlerClass *dClass

SomeClass.m:

Code:
@synthesize dClass;

//...

- (id)initWithCoder:(NSCoder *)inCoder {
    if (self = [super initWithCoder:inCoder]) {
        dClass = [[DefaultHandlerClass alloc] init]
        self.delegate = dClass;
    }
    self.text = @"initcoder";
    return self;
}

- (void)setDelegate:(id)aDelegate
{
  [self setDelegate:dClass];
  [dClass setDelegate:aDelegate];
}

- (id)delegate
{
  return [dClass delegate];
}

- (void)dealloc
{
   self.delegate = nil;
   if ( dClass != nil ) [dClass release];
   [super dealloc];
}
DefaultHandlerClass.h:
Code:
@interface DefaultHandlerClass <UITextFieldDelegate>

{
  id delegate
}

@property (nonatomic,assign) id delegate;
DefaultHandlerClass.m

Code:
@implementation DefaultHandlerClass

@synthesize delegate;

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
   //...do your custom stuff here...
  
  //now forward message to this class' delegate
  if ( [delegate respondsToSelectore:@selector(textFieldDidBeginEditing:)] )
   {
      [delegate textFieldDidBeginEditing:textField];
   }
}

//... other delegate methods...
a little messy, and untested, but you get the idea.

Last edited by CowTipper; 06-22-2009 at 01:47 PM.
CowTipper is offline   Reply With Quote
Old 04-16-2011, 07:30 AM   #7 (permalink)
Registered Member
 
Join Date: Apr 2011
Posts: 1
Paco is on a distinguished road
Default

Found a much easier way to do this:

You first need to create the delegate:

mydelegate.h:

#import <Foundation/Foundation.h>
@interface mydelegate : NSObject <UITextFieldDelegate>{}
- (void)textFieldDidEndEditingUITextField *)textField;
@end

mydelegate.m:
#import "mydelegate.h"
@implementation mydelegate
- (void)textFieldDidEndEditingUITextField *)textField
{
//do your stuff...
}
@end

Then, you need to create the class that extend the UITextField:

myTextField.h:

#import <UIKit/UIKit.h>
#import "mydelegate.h"
@interface myTextField : UITextField{}
@end


myTextField.m:

#import "myTextField.h"
@implementation myTextField
- (id)initWithFrameCGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
//Set the delegates to catch events
self.delegate = [[mydelegate alloc] init];
}
return self;
}
@end

And this is how is done!!
Paco is offline   Reply With Quote
Reply

Bookmarks

Tags
delegate, extending, subclassing, uitextfield

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 334
3 members and 331 guests
guusleijsten, Kryckter, LEARN2MAKE
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,649
Threads: 94,113
Posts: 402,880
Top Poster: BrianSlick (7,990)
Welcome to our newest member, Anwerbl
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 08:48 PM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0