Подтвердить что ты не робот

Попытка найти, какое текстовое поле активно ios

Я пытаюсь найти, какое текстовое поле активно, когда я перемещаю представление, когда клавиатура поднимается. Я пытаюсь установить свойство в myviewcontroller из subview прокрутки.

Это код, который я использую для отображения представления в scrollview

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

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

[viewFrame addSubview: viewController.view];

_currentViewController = viewController;
}

- EDIT -

Я изменил свой образ мышления об этой проблеме. Извините, что вопрос был неоднозначным, когда я опубликовал его. В то время я был измотан, и это имело смысл в моей голове.

Другой, но похожий вопрос: существует ли общий подкласс как UITextArea, так и UITextView, который даст мне начало первогоResponder? Или мне нужно будет также проверить класс первогоResponder, прежде чем я смогу найти происхождение?

4b9b3361

Ответ 1

Вам нужно найти объект, который стал первым ответчиком. Объектом первого ответчика является тот, кто использует клавиатуру (на самом деле, он имеет фокус для ввода пользователем). Чтобы проверить, какое текстовое поле использует клавиатуру, перебирайте текстовые поля (или просто над всеми подзонами) и используйте метод isFirstResponder.

EDIT: В соответствии с запросом пример кода, предполагающий, что все текстовые поля являются подзором представления контроллера вида:

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

Ответ 2

Я сделал расширение для этого.

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 {
    // ...
}

Ответ 3

если ваши текстовые поля одинаковы (т.е. вся валюта или текст) и не требуют специального форматирования, я бы предложил следующее:

Сначала у вас есть необязательная переменная textField. Например:

var currentTextField: UITextField?

Затем добавьте следующее:

func textFieldDidBeginEditing(textField: UITextField) {

        currentTextField = textField

}

Теперь вы можете делать все, что хотите, с "активным" текстовым полем, и вам не нужно отслеживать любые теги, если вам не нужна определенная операция форматирования.

Ответ 4

Почему вы не даете всем UITextfields отдельные теги textfield.tag = 1

тогда вы отвечаете на делегата DidBeginEditing. и проверить, какой textfield.tag активен?

Ответ 5

В swift 3 используйте функцию ниже в ваших операторах if else:

    if (textField.isEditing) 

[iOS] [swift3]

Ответ 6

Сначала я использовал решение 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;
}

Сообщите мне, если у вас есть вопросы, и я уточню. Обратите внимание, что комментарии для меня. Также обратите внимание, что некоторый код или опущен для краткости.

Ответ 7

На основе ответа Xilexio, но повторяя все виды, чтобы найти запрошенный 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];
}