Question

How can I get the textfield in this method to call textfieldshouldreturn? I'm guessing its not working beause the UIView doesn't have a delegate property, but I'm not sure how to make a UIView I've created within a method conform to a protocol. I've seen several posts regarding delegation but everything I've tried hasn't worked. I'm sure its something simple. Thanks in advance.

- (void) launchCreateNewListActionSheet{
    self.listActionSheet= [[UIActionSheet alloc] initWithTitle:@"Create A New List"
                                                  delegate:self
                                         cancelButtonTitle:nil
                                    destructiveButtonTitle:nil
                                         otherButtonTitles:nil];

    UIView *addToNewList = [[UIView alloc] initWithFrame:CGRectMake(0, 44, 320, 464)];
    addToNewList.backgroundColor = [UIColor whiteColor];

    UILabel *addToNewListLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 23, 100, 20)];
    addToNewListLabel.text = @"List Name: ";

    UITextField *enterNewListName = [[UITextField alloc] initWithFrame:CGRectMake(100, 20, 180, 30)];
    enterNewListName.layer.borderWidth = 1;
    enterNewListName.layer.borderColor = [[UIColor blackColor] CGColor];
    enterNewListName.delegate = self;

    [addToNewList addSubview:addToNewListLabel];
    [addToNewList addSubview:enterNewListName];


    UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc]     initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(addToExistingList)];

    UIBarButtonItem *cancelBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelListPicker)];

    UIBarButtonItem *fixedCenter = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
fixedCenter.width = 180.0f;

    UIToolbar* toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
    toolbar.barStyle = UIBarStyleBlackOpaque;
    [toolbar sizeToFit];

    [toolbar setItems:@[cancelBtn, fixedCenter, doneBtn] animated:YES];

    [self.listActionSheet addSubview:toolbar];
    [self.listActionSheet addSubview:addToNewList];
    [self.listActionSheet showInView:self.view];
    [self.listActionSheet setBounds:CGRectMake(0,0,320, 464)];
} 

Here is my .h file. I have implemented as it is working for text fields in other methods.

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "ZBarSDK.h"
#import "ProgressView.h"

@class ScannerViewController;

@protocol ScanViewDelegate <NSObject>;
@required
-(void)postURL:(NSURL*)url selectedAction:(NSString*)action;
@end

@interface ScannerViewController : UIViewController <ZBarReaderViewDelegate,        UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate, UIWebViewDelegate,    UIPickerViewDelegate, UIActionSheetDelegate>

    id <ScanViewDelegate> delegate;
}
@property (weak, nonatomic) IBOutlet ZBarReaderView *readerView;
@property (weak, nonatomic) IBOutlet UITableView *scannerList;
@property (retain) id delegate;

@property (strong) NSMutableArray* barCodeArray;
@property (strong) NSMutableArray* quantityArray;
@property (strong) NSURL* url;
@property (strong) NSString* action;
@property NSString *listItems;
@property NSString *listItemNames;
@property NSArray *listItemNamesArray;
@property NSArray *hrefArray;
@property int pickerViewRow;
@property (strong) UIWebView *webView;
@property (strong) ProgressView* loading;
@property BOOL isLoading;
@property (strong) UITextField *enterNewListName;
@property (strong) UITextField *addToNewListDescription;
@property (strong) NSMutableArray *textFieldArray;

-(IBAction)sendToCart:(id)sender;
-(IBAction)sendToList:(id)sender;
-(void)startLoadingURL;
@end

Here is the textfieldshouldreturn method:

-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
    if([self.textFieldArray containsObject:textField])
    {
        NSUInteger index = [self.textFieldArray indexOfObject:textField];
        NSNumber *newQuantity = [NSNumber numberWithInteger:[textField.text integerValue]];
        [self.quantityArray replaceObjectAtIndex:index withObject:newQuantity];
        NSLog(@"Your new quantity is: %@", newQuantity);
    }
    [textField resignFirstResponder];
    return YES;
}
Was it helpful?

Solution

The key point here is that Andres would like to use UiTextField on an UIActionSheet. UIActionSheet has a little bit different behaviour eating taps, actually it prevents a healthy use of UiTextField added to the actionsheet.

Please see this SO answer where it was found that using a custom solution is better: keyboard in UIActionSheet does not type anything

Basically it is better to use UIAlertView for a modal text input view form (please see this link) a custom view imitating UIActionSheet with more space for customisation (search eg. github as a starting point) but there's one solution for UIActionSheet too.

In order to place the UITextField in the view hierarchy where UIActionSheet doesn't steel pushes use after showing the UIActionSheet this code snippet:

    [self.listActionSheet addSubview:toolbar];
    // [self.listActionSheet addSubview:addToNewList];  // please comment-delete this line
    [self.listActionSheet showInView:self.view];
    [self.listActionSheet setBounds:CGRectMake(0,0,320, 464)];
    // this is the 2 new lines below
    UIWindow *appWindow = [UIApplication sharedApplication].keyWindow;
    [appWindow insertSubview:addToNewList aboveSubview:listActionSheet];  // you add custom view here

OTHER TIPS

Have you enabled the respective class to be compatible with UITextFieldDelegate?

Please goto the .h file of the current class, and make it compatible to UITextFieldDelegate.

Eg: If your ClassName is HomeController

I am assuming you are getting a warning something similar to this:

Assigning to id<UITextFieldDelegate> from incompatible type "HomeController"

Solution:

@interface HomeController : UIViewController <UITextFieldDelegate>
    // YOur Class Variable.
@end

Your UIView does not need delegate property. It just needs to implement the UITextField delegate methods. They are all optional, so the compiler won't complain if you don't implement them.

Your code looks OK. But to see if things are hooked up right implement textFieldDidBeginEditing: in your UIView subclass to generate a log and see if the log comes up when you select your text field.

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
   NSLog(@"textFieldDidBeginEditing: %@ (delegate: %@)", textField, [textField delegate]);
}

If that works fine then log on textFieldShouldReturn: etc. If that doesn't work, then something has gone awry elsewhere. The code you've posted looks OK on quick glance.

First of all if your class doesn't conform to a protocol that has methods required it will generate a warning at the line that sets the delegate to be the class.

Nwo, if you want to make a custom class a delegate of a UITextField you will have to declare that and implement the required method. In your case you have to do the following:

In YourCustomView.h

@interface YourCustomView : UIView (or other class) <UITextFieldDelegate> // this will show that this class conforms to UITextFieldDelegate protocol
//other methods or properties here
@end

In YourCustomView.m

@implementation YourCustomView 

-(void)launchCreateNewListActionSheet {
   //some code here 
    UITextField *textField = //alloc init methd
    textField.delegate = self;
}

#pragma mark - UITextFieldDelegate //this is optional only if you want to structure the code
- (BOOL)textFieldShouldReturn:(UITextField *)textField { 
     //method called when the text field resign first responder
}

//and you can add more delegate methods depending on your needs. @end

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top