(尝试使用)-BOOLtextFieldShouldReturn:(UITextField*)文本框,使键盘消失的子视图 - trying to use -(BOOL) textFieldShouldReturn:(UITextField *)textField; to make the keyboard go away in a subview

- 此内容更新于:2015-12-09
主题:

我一直在试图解决这几个小时。所有的文章我发现任何地方提供了一个解决方案。问题是文本框在子视图,我无法弄清楚如何让它响应返回按钮隐藏键盘。这是我的视图控制器;这是我的自定义类,代码是完美的除了键盘隐藏在每一个方面。

原文:

I have been trying to solve this for many hours. None of the posts I have found anywhere has provided a solution. The problem is the textField is in a subview and I cannot figure out how to make it respond to the Return button to hide the keyboard. Here is my view controller;

    #import <UIKit/UIKit.h>
#import "Combatant.h"
@interface ViewController : UIViewController <CombatantDelegate>


- (IBAction) addView;
- (IBAction) roll;

@end

    #import "ViewController.h"

static int startY = 60;

@interface ViewController ()
{
    NSMutableArray * customViews;
}

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    customViews = [[NSMutableArray alloc] init];
}

- (IBAction) addView
{
    Combatant * thing = [[NSBundle mainBundle] loadNibNamed:@"Combatant" owner:nil options:nil][0];
    [self.view addSubview: thing];
    thing.center = CGPointMake(self.view.center.x, startY + customViews.count * thing.bounds.size.height);
    thing.combatDelegate = self;
    [customViews addObject:thing];
}

- (IBAction) roll
{
    for (Combatant * cust in customViews)
    {
        [cust rollWasTapped];
    }
}
@end

Here is my custom Class;

    #import <UIKit/UIKit.h>

@class Combatant;

@protocol CombatantDelegate <NSObject>

@end



@interface Combatant : UIView <UITextFieldDelegate>
{
    IBOutlet UITextField * name;
    IBOutlet UITextField * base;
    IBOutlet UITextField * die;
    IBOutlet UITextField * mod;
    IBOutlet UILabel * total;
    NSString *value;
    int dRoll;
    int cBase;
    int cMod;
}

@property (nonatomic, strong, readwrite) NSString *value;
@property (nonatomic, strong) IBOutlet UITextField * name;
@property (nonatomic, strong) IBOutlet UITextField * base;
@property (nonatomic, strong) IBOutlet UITextField * die;
@property (nonatomic, strong) IBOutlet UITextField * mod;
@property (nonatomic) IBOutlet UILabel * total;
-(void) rollWasTapped;
-(BOOL) textFieldShouldReturn:(UITextField *)textField;
@property (nonatomic, weak) id<CombatantDelegate> combatDelegate;
-(int) dieRoll;
-(int) convertBase;
-(int) convertMod;
@end

    #import "Combatant.h"

@implementation Combatant

@synthesize value;
@synthesize name;
@synthesize base;
@synthesize die;
@synthesize mod;
@synthesize total;

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {

    }
    return self;
}

-(BOOL) textFieldShouldReturn:(UITextField *)textField{
    [name resignFirstResponder];
    return YES;
}

- (void) rollWasTapped;
{
    int tot;
    tot = [self convertBase] + [self dieRoll] + [self convertMod];
    total.text = [NSString stringWithFormat:@"%i", tot];
    NSLog(@" totaling %i ", tot);
}

 -(int) dieRoll
 {
     int val = [die.text intValue];
     if (val <7 && val >0)
     {
         NSLog(@" %i die", val);
     } else {
         NSLog(@" there are no dice");
         val = 0;    }
     int d = 0;
     for (int i = 0; i < val; i++) {
         d = d + arc4random()%6 + 1;
     }
     dRoll = d;
     NSLog(@"%i die roll result = %i ", val, dRoll);
     return dRoll;
 }

 -(int) convertBase
 {
     cBase = [base.text intValue];
     NSLog(@"base = %i", cBase);
     if (cBase > -1 && cBase < 20)
     {
         return cBase;
     }
     return 0;
}

 -(int) convertMod
 {
    cMod = [mod.text intValue];
    NSLog(@"mod = %i", cMod);
    if (cMod > -20 && cMod < 20)
    {
        return cMod;
    }
    return 0;
 }

- (void) dealloc
{
    self.combatDelegate = nil;
}
@end

The code works perfect in every aspect except the keyboard hiding.

楼主:给一些澄清…文本字段所有正常工作,应用程序处理所有数据完美没有崩溃,没有错误和警告。我不能找到一种方法(除了命令K)让键盘消失。这最终将设备上,所以命令K是一文不值。textFields字段是动态创建的视图控制器上的一个按钮。在我看来这是一个层次的问题。这个程序的所有其他方面的层次歌舞不错。

(原文:to give some clarification ... the text fields all work properly, the app handles all data flawlessly with no crashes and no errors and no warning. I just cannot find a way (other than command K) to get the keyboard to go away. This will eventually be on devices, so command K is worthless. The textFields are dynamically created by a button on the view controller. It seems to me this is a Hierarchy problem. All other aspects of this app do the Hierarchy song and dance fine.)

楼主:在子视图xib,委托不是连接到视图。调用第一个回答者也不再说“名字”,只是[textFieldresignFirstResponder];…现在工作。问题解决了。谢谢大家!

(原文:In the subview xib, the delegate was not connected to the view. The call to first responder also no longer says "name", just [textField resignFirstResponder]; ... it now works. Problem solved. Thank you everyone!)

解决方案:
从最基本的意义上说,你想让当前活跃的文本字段resignFirstResponder。你的问题似乎是如何访问文本字段。编辑:以下段落跳转话题很快,当我详细一些可能的解决方案,而不是1。目标:访问文本字段。解决方案:1)创建一个属性公开的文本字段的自定义类。2)创建一个函数,调用自定义类的文本字段。您有4个属性公开的文本字段,假设有4对每个视图文本字段吗?在这种情况下,去创建一个函数,这个函数,在视图上,确保它调用自己。textField1辞职……废话,那么自我。textField2,确保所有的人。目前你叫名字resignFirstResponder回调。但首先让我们回溯一下。所有textFields字段调用textFieldShouldReturn委托。所以确保所有4你的文本字段的视图为委托。在界面构建器或代码,self.name.delegate(或self.name.textFieldDelegate,我忘了)=自我;每一个。同时,记得叫“自我。”、“名称”是别的东西。真正的自我。访问属性访问器。但看不见的变量创建叫做_name(与下划线开头一样,这适用于所有属性)。现在我们知道你所有的字段都被称为正确,让我们回到委派。如果你确实想要“当前活动,返回”文本框辞职响应者,委托传递对象视图文本字段,所以只要记住叫resignFirst……在当前返回的字段。当然,这属于委托回调方法,从文本框不存在否则,免得你访问它的名字(self.name或其他)。最后但并非最不重要,把一个按钮背后的一切,但足够大的屏幕,让它调用一个函数。在这个函数中,您可以调用每一个文本字段“斜面”。基本上,使函数调用“hideTheKeyboard”或不管你叫它(的函数调用resignFirst…所有自定义视图中的字段)每一个自定义视图。它应该看起来像你的函数(customViews视图),而是调用,调用自定义函数。在这个函数,仅仅因为它是一个可能的解决方案,您也可以做一些类似,但可以告诉,原因你可以封装成一个函数,你叫只是少行代码/简单。更重要的是,你明白,为什么你可以做到无论如何比找到一个解决方案。有三个解决方案我上面列出的(使用一个属性,使用一个函数来访问文本字段,或者使用委托)。最简单的是委托,最紧凑的是功能,最普遍的是财产。(每一个也有局限性)。我想给彻底了解一下,这样你就能看到它们。
原文:

In the most basic sense, you want the currently active text field to resignFirstResponder. Your problem seems to be how to access that text field.

edit: the below paragraphs jump topics quickly, as I'm detailing a few possible solutions instead of 1.

Goal: Accessing the Text field. Solutions: 1) Create a property that exposes the text field on the custom class. 2) Create a function that calls the text field on the custom class.

You have 4 properties exposing the text fields, assuming there are 4 text fields on each view?

In that case, go with creating a function, and in that function, on the view, make sure it calls self.textField1 resign... blah, then self.textField2, just make sure it hits all of them.

Currently you call name resignFirstResponder in the callback. But first let's backtrace a little bit. All textFields call textFieldShouldReturn on their delegate. So make sure all 4 of your text fields have the view as the delegate. Either in interface builder or code, self.name.delegate (or self.name.textFieldDelegate, I forgot exactly) = self; for each one.

Also, remember to call "self.", "name" is something else. Actually self. accesses the property accessor. But the invisible variable it creates is called _name (same thing with an underscore at the beginning, this works for all properties).

Now that we know all your fields are being called correctly, let's get back to the delegate. If you really do want the "currently active, returning" text field to resign its responder, the delegate passes in its object view the textField, so just remember to call resignFirst... on the currently returning field.

[textField resignFirstResponder]

Of course, that belongs in the delegate callback method, since textField does not exist otherwise, lest you access it by its name (self.name, or the others).

Last but not least, put a button behind everything, but large enough to cover the screen, make it call a function. In that function, you can "splay" the call to every text field. Basically, make that function call the "hideTheKeyboard" or whatever you named it (the function that calls resignFirst... on all the fields within the custom view) on every custom view.

It should look like your function with for( view in customViews) but instead of calling roll, it calls your custom function.

Within that function, just because it is a possible solution, you can also do something like

- (IBAction) roll
{
    for (Combatant * cust in customViews)
    {
        [cust.name resignFirstResponder];
        [cust.die resignFirstResponder]; 
        // and on for the other 2
    }
}

But, as you can tell, the reason you might want that encapsulated into a function that you call is simply for less lines of code/simplicity. It is more important that you understand how and why you can do it either way than finding a solution that works. There are 3 solutions I've listed above (use a property, use a function to access the textField, or use the delegate).

The simplest is the delegate, the most compact is the function, and the most widespread is the property. (There are also limitations to each one). I wanted to give a thorough understanding so you can see them.

楼主:问题解决了,在子视图xib,委托并不是连接到视图。调用第一个回答者也不再说“名字”,只是[textFieldresignFirstResponder];…现在工作。非常感谢斯蒂芬!!!它是惊人的小姐是一个小而简单的一步。

(原文:Problem solved, In the subview xib, the delegate was not connected to the view. The call to first responder also no longer says "name", just [textField resignFirstResponder]; ... it now works. Thank you so much Stephen!!! It is amazing that it was such a small and easy step to miss.)

解决方案:
把它的方法
原文:

Put it in the textFieldDidEndEditing: method

- (void)textFieldDidEndEditing:(UITextField *)textField {
{
[textField resignFirstResponder];
}
网友:抱歉拼写错误,打字我的iPhone

(原文:Sorry for the typos, typing from my iPhone)

楼主:参见上面的SyedAliSalman。不工作。我认为打嗝是textField动态创建的子视图。我需要使用孩子的父母关系在一些卑鄙的方式,我不知道。

(原文:see SyedAliSalman above. does not work. I think the hiccup is the textField is in a dynamically created subview. I need to use child parent relation in some sneaky way that I do not know.)

楼主:问题解决了,在子视图xib,委托并不是连接到视图。调用第一个回答者也不再说“名字”,只是[textFieldresignFirstResponder];…现在工作。谢谢大家!

(原文:Problem solved, In the subview xib, the delegate was not connected to the view. The call to first responder also no longer says "name", just [textField resignFirstResponder]; ... it now works. Thank you everyone!)

解决方案:
在viewDidLoad添加:或者你可以这样做检查员在故事板连接,通过拖动委托出口你的视图控制器。PS:在这种情况下,textFieldShouldReturn方法应该在视图控制器。
原文:

In viewDidLoad add this:

name.delegate = self;

Or you can do this in the storyboard in the Connections Inspector, by dragging delegate outlet to your view controller.

PS: In this case, textFieldShouldReturn method should be in the view controller too.

楼主:没有viewDidLoad自定义类。视图是动态创建与xib,这就是所谓的视图控制器

(原文:the custom class does not have a viewDidLoad. Views are dynamically created with xib, this is called by the view controller)

楼主:一个视图控制器而言,“名字”是不存在的。“名称”属于定制类“作战”。另外,委托不能吹嘘视图控制器。拖动“文件所有者”会导致崩溃。

(原文:As far a view controller is concerned, "name" does not exist. "name" belongs to the custom class "Combatant". Also, the delegate cannot be bragged to the view controller. Dragging it to "files owner" causes a crash.)

楼主:问题解决了,在子视图xib,委托并不是连接到视图。调用第一个回答者也不再说“名字”,只是[textFieldresignFirstResponder];…现在工作。谢谢大家!

(原文:Problem solved, In the subview xib, the delegate was not connected to the view. The call to first responder also no longer says "name", just [textField resignFirstResponder]; ... it now works. Thank you everyone!)

解决方案:
您正在使用委托的描述,如果它应该返回吗?甚至在你返回给你的文本框的键盘事件返回或认为这是不可能的。请按@soulshined提到的代码。
原文:

You are using delegate which describes that if it should return or not? and before even you are returning you are sending event to your text field keyboard to return or dismiss which is not possible. please try the code as per mentioned by @soulshined.

- (void)textFieldDidEndEditing:(UITextField *)textField {
{
    [textField resignFirstResponder];
}
楼主:我试图实现这四种方法,没有任何效果

(原文:I tried to implement this 4 ways, none had any effect)

网友:我相信Syed提及,您正在使用的委托方法是别的东西。TextFieldShouldReturn目的,简单的形式,它决定你是否想要重新创建一个新行。如果你没有通过,它没有“回归”,它会创建一个新行。然而,它才会把键盘之后,赛义德·描述方法。我会给更详细的研究。

(原文:I believe Syed is mentioning that you are using the delegate method that is for something else. TextFieldShouldReturn has a purpose, the short form is that it determines whether you want return to create a new line or not. If you pass NO, it does not "return", it creates a new line. However, it will not dismiss the keyboard until after that, which is the method Syed is describing. I'll give more detail below.)

楼主:我原以为TextFieldShouldReturn关闭键盘当你点击返回。这是错误的吗?…很多答案在网上搜索“我如何使键盘消失在iOS”提供了这个功能……*)-(BOOL)textFieldShouldReturn:(UITextFieldtextField;…听起来你说这个函数不能或不应该做这个…我是困惑的

(原文:I had thought TextFieldShouldReturn was to close keyboard when you hit return. Is this wrong somehow? ... Many answers to the search "how do I make the keyboard go away in iOS" provides this function ... - (BOOL)textFieldShouldReturn:(UITextField *)textField; ... it sounds like you are saying that this function does not or should not do this ... I am confused)

楼主:问题解决了,在子视图xib,委托并不是连接到视图。调用第一个回答者也不再说“名字”,只是[textFieldresignFirstResponder];…现在工作。谢谢大家!

(原文:Problem solved, In the subview xib, the delegate was not connected to the view. The call to first responder also no longer says "name", just [textField resignFirstResponder]; ... it now works. Thank you everyone!)