试图找到哪个文本字段是活动的ios

时间:2012-08-29 08:33:11

标签: ios

我试图在键盘上升时移动视图时找到哪个文本字段处于活动状态。我正在尝试从scrollview的子视图中设置我的viewcontroller中的属性。

这是我用来在滚动视图中显示视图的代码

-(void)displayView:(UIViewController *)viewController{

[[viewFrame subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)]; 
[viewFrame scrollRectToVisible:CGRectMake(0, 0, 1, 1)
                        animated:NO];

[viewFrame addSubview: viewController.view];

_currentViewController = viewController;
}

- 编辑 -

我改变了对这个问题的思考方式。对不起,我发布时问题含糊不清。我当时很累,这在我脑海里是有意义的。

一个不同但相似的问题:UITextArea和UITextView的公共子类是否会给我firstResponder的起源?或者,在找到原点之前,还需要检查firstResponder的类吗?

7 个答案:

答案 0 :(得分:35)

您需要搜索已成为第一响应者的对象。第一响应者对象是使用键盘的对象(实际上,他是一个具有用户输入焦点的对象)。要检查哪个文本字段使用键盘,请迭代文本字段(或仅覆盖所有子视图)并使用isFirstResponder方法。

编辑: 根据要求,示例代码,假设所有文本字段都是视图控制器视图的子视图:

for (UIView *view in self.view.subviews) {
    if (view.isFirstResponder) {
        [self doSomethingCleverWithView:view];
    }
}

答案 1 :(得分:22)

我做了一个扩展。

public extension UIResponder {

    private struct Static {
        static weak var responder: UIResponder?
    }

    public static func currentFirst() -> UIResponder? {
        Static.responder = nil
        UIApplication.shared.sendAction(#selector(UIResponder._trap), to: nil, from: nil, for: nil)
        return Static.responder
    }

    @objc private func _trap() {
        Static.responder = self
    }
}

使用:

if let activeTextField = UIResponder.currentFirst() as? UITextField {
    // ...
}

答案 2 :(得分:2)

为什么不给所有UITextfields单独的标签textfield.tag = 1

然后你回复代表DidBeginEditing。并检查哪个textfield.tag是活动的?

答案 3 :(得分:2)

我第一次使用Xilexio的解决方案,但速度很慢。我最终使用标签。这是我的代码并设置为一个例子。

@property (nonatomic) NSInteger currentFormField;

typedef NS_ENUM(NSInteger, IOUFormField) {
    IOUFormFieldName,
    IOUFormFieldAmount,
    IOUFormFieldDescription,
    IOUFormFieldDate
};

...

self.nameField.tag = IOUFormFieldName;
self.amountField.tag = IOUFormFieldAmount;
self.descriptionField.tag = IOUFormFieldDescription;
self.dateField.tag = IOUFormFieldDate;

-(void)keyboardWillShow:(NSNotification *)notification {
    // Move the scroll view to a position where the user can see the top and bottom form fields
    // For example, if the user is on the description field, they should be able to see the date field and the amount field.

    // The keyboard rect value comes as a NSValue * (a wrapped NSRect) with origin and size.
    // The origin is using screen coordinates which is pixel based so don't use it.
    // Use the size. Seems like it is density based.
    CGFloat viewableScreenHeight = self.view.frame.size.height - keyboardFrameBeginRect.size.height;

    // When the user is on a form field, get the current form field y position to where the scroll view should move to
    CGFloat currentFormFieldYPosition = 0;
    switch (self.currentFormField) {
        case IOUFormFieldName:
        {
            currentFormFieldYPosition = self.nameField.frame.origin.y;

            // If the scroll view is at the bottom and the user taps on the name field, move the scroll view to the top.
            // This is so that users can see the give/get segments.
            [self.scrollView setContentOffset:CGPointMake(0, 0) animated:YES];

            break;
        }
        case IOUFormFieldAmount:
        {
            currentFormFieldYPosition = self.amountField.frame.origin.y;
            break;
        }
        case IOUFormFieldDescription:
        {
            currentFormFieldYPosition = self.descriptionField.frame.origin.y;
            break;
        }
        case IOUFormFieldDate:
        {
            currentFormFieldYPosition = self.dateField.frame.origin.y;
            break;
        }
        default:
            break;
    }

    // I want the current form field y position to be 100dp from the keyboard y position.
    // 50dp for the current form field to be visible and another 50dp for the next form field so users can see it.
    CGFloat leftoverTopHeight = viewableScreenHeight - 100;

    // If the current form field y position is greater than the left over top height, that means that the current form field is hidden
    // We make the calculations and then move the scroll view to the right position
    if (currentFormFieldYPosition > leftoverTopHeight) {
        CGFloat movedScreenPosition = currentFormFieldYPosition - leftoverTopHeight;
        [self.scrollView setContentOffset:CGPointMake(0, movedScreenPosition) animated:YES];
    }   
}

#pragma mark - UITextFieldDelegate

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
    switch (textField.tag) {
        case IOUFormFieldName:
            self.currentFormField = IOUFormFieldName;
            break;
        case IOUFormFieldAmount:
            self.currentFormField = IOUFormFieldAmount;
            break;
        case IOUFormFieldDescription:
            self.currentFormField = IOUFormFieldDescription;
            break;
        case IOUFormFieldDate:
            self.currentFormField = IOUFormFieldDate;
        default:
            break;
    }

    return true;
}

如果您有任何问题,请告诉我,我会澄清。请注意,评论适合我。还要注意一些代码或为简洁而省略。

答案 4 :(得分:2)

假设您的文本字段完全相同(即所有货币或文本)并且不需要任何特殊格式,我建议如下:

首先,有一个可选的textField变量。例如:

C2 -> =COUNTIF($B$2:B2;B2)
D2 -> =B2&"|"&C2
G2 -> =IFERROR(INDEX($A:$A;MATCH($F2&"|"&COLUMN(A1);$D:$D;0));"")

然后添加以下内容:

var currentTextField: UITextField?

现在,您可以通过“活跃”来做任何您想做的事情。文本字段,除非您需要某些特定的格式化操作,否则无需跟踪任何标记。

答案 5 :(得分:1)

在swift 3中,在if else语句中使用以下函数:

    if (textField.isEditing) 

[iOS] [swift3]

答案 6 :(得分:0)

基于Xilexio's answer但迭代所有视图以查找请求的FirstResponder视图

-(UIView*)getFirstResponderInView:(UIView*)parentView{
    UIView* requestedView = nil;
    for (UIView *view in parentView.subviews) {
        if (view.isFirstResponder) {
            [view resignFirstResponder];
        } else if (view.subviews.count > 0) {
            requestedView = [self getFirstResponderInView:view];
        }
        if (requestedView != nil) {
            return requestedView;
        }
    }
    return nil;
}

像这样使用:

UIView *view = [self getFirstResponderInView:self.view];
if(view != nil){
    [self doSomethingCleverWithView:view];
}