programing

텍스트 필드를 탐색하는 방법([다음]/[완료]

batch 2023. 4. 16. 14:46
반응형

텍스트 필드를 탐색하는 방법([다음]/[완료]

iPhone 키보드의 [다음]버튼을 사용하여 모든 텍스트 필드를 탐색하려면 어떻게 해야 합니까?

마지막 텍스트 필드가 키보드를 닫습니다.

IB의 버튼(Next/Done)을 설정했지만, 막혀 버렸다.

textFieldShouldReturn 액션을 구현했는데 Next 버튼과 Done 버튼을 누르면 키보드가 닫힙니다.

Mac OS X용 코코아에는 다음 응답자 체인이 있으며, 텍스트 필드에는 다음에 어떤 제어에 초점을 두어야 하는지 물어볼 수 있습니다.이것이 텍스트 필드 간의 표 작성을 가능하게 합니다.그러나 iOS 기기에는 키보드가 없고 터치만 있기 때문에 이 개념은 코코아 터치로의 전환에서 살아남지 못했다.

이 작업은 다음 두 가지 전제조건으로 쉽게 수행할 수 있습니다.

  1. 모 " ""UITextField는 같은 부모 뷰에 있습니다.
  2. 이러한 "탭 순서"는 태그 속성에 의해 정의됩니다.

다음과 같이 textFieldShouldReturn:을 덮어쓸 수 있다고 가정합니다.

-(BOOL)textFieldShouldReturn:(UITextField*)textField
{
  NSInteger nextTag = textField.tag + 1;
  // Try to find next responder
  UIResponder* nextResponder = [textField.superview viewWithTag:nextTag];
  if (nextResponder) {
    // Found next responder, so set it.
    [nextResponder becomeFirstResponder];
  } else {
    // Not found, so remove keyboard.
    [textField resignFirstResponder];
  }
  return NO; // We do not want UITextField to insert line-breaks.
}

코드를 더 추가하면 가정도 무시될 수 있습니다.

Swift 4.0

 func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    let nextTag = textField.tag + 1
    // Try to find next responder
    let nextResponder = textField.superview?.viewWithTag(nextTag) as UIResponder!

    if nextResponder != nil {
        // Found next responder, so set it
        nextResponder?.becomeFirstResponder()
    } else {
        // Not found, so remove keyboard
        textField.resignFirstResponder()
    }

    return false
}

텍스트 필드의 슈퍼뷰가 UITableViewCell일 경우 다음 응답자는

let nextResponder = textField.superview?.superview?.superview?.viewWithTag(nextTag) as UIResponder!

내가 그것을 처음 봤을 때 나를 놀라게 했던 훨씬 더 우아한 해결책이 있다.이점:

  • OSX 텍스트 필드 구현에 근접하여 텍스트 필드가 다음에 초점을 맞춰야 할 위치를 파악합니다.
  • 태그 설정 또는 사용에 의존하지 않음 - 즉, IMO는 이 사용 사례에 취약함
  • 하여 두 가지 사용할 수 .UITextField ★★★★★★★★★★★★★★★★★」UITextView UI controls -- UI 컨트롤
  • 보일러 플레이트 UITextField 위임 코드를 사용하여 뷰 컨트롤러를 복잡하게 만들지 않습니다.
  • IB와 잘 통합되어 익숙한 옵션드래그 드롭을 사용하여 콘센트에 접속할 수 있습니다.

서브클래스는 UITextField로 설정합니다.IBOutletnextField라고 .츠키다

@interface SOTextField : UITextField

@property (weak, nonatomic) IBOutlet UITextField *nextField; 

@end

그 실장은 다음과 같습니다.

@implementation SOTextField

@end

낫다'를 만듭니다.-textFieldShouldReturn:임임: :

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    if ([textField isKindOfClass:[SOTextField class]]) {
        UITextField *nextField = [(SOTextField *)textField nextField];

        if (nextField) {
            dispatch_async(dispatch_get_current_queue(), ^{
                [nextField becomeFirstResponder];
            });
        }
        else {
            [textField resignFirstResponder];
        }
    }

    return YES;
}

IB 、 [ UIText ]를 사용하도록 UIText 를 합니다.SOTextFieldclass. IB는 'SOTextFields'를 'SOTextFields'로 지정합니다. 버튼으로 을 다음 필드 아웃렛에 할 수 입니다.SOTextField이치노

IB에서의 nextField 할당

게다가 textFields를 루프 하는 등, 마지막에 포커스를 잃은 후, 처음의 포커스를 다시 받을 수 있도록, 쿨한 조작을 실시할 수 있습니다.

될 수 .returnKeyTypeSOTextField a까지UIReturnKeyNext할당되어 있는 -- nextField는 .

다음은 위임을 받지 않는 예입니다.

tf1.addTarget(tf2, action: #selector(becomeFirstResponder), for: .editingDidEndOnExit)
tf2.addTarget(tf3, action: #selector(becomeFirstResponder), for: .editingDidEndOnExit)

ObjC:

[tf1 addTarget:tf2 action:@selector(becomeFirstResponder) forControlEvents:UIControlEventEditingDidEndOnExit];
[tf2 addTarget:tf3 action:@selector(becomeFirstResponder) forControlEvents:UIControlEventEditingDidEndOnExit];

미지의하여 동작합니다.UIControlEventEditingDidEndOnExit UITextField★★★★★★ 。

스토리보드에 쉽게 연결할 수도 있으므로 위임이나 코드가 필요하지 않습니다.

편집: 실제로 스토리보드에 연결하는 방법을 찾을 수 없습니다. becomeFirstResponder이 컨트롤 이벤트에 대해 제안되는 액션이 아닌 것 같습니다만, 유감입니다.수 있습니다.이 액션에서는 어느 에서 "ViewController"의 "TextField"를 "ViewController"의 "TextField"를 "ViewController"의 "TextField"로 할 수 .이 액션은 어느 텍스트필드를 사용할지 결정합니다.becomeFirstResponder으로 합니다, 않기 에, ).viewDidLoad를 참조해 주세요.

여기 이 문제에 대한 저의 해결책이 있습니다.

이 문제를 해결하기 위해(태그에 의존하는 것을 싫어하기 때문에) 사용자 지정 속성을 UITextField 개체에 추가하기로 결정했습니다.즉, UITextField에 다음과 같은 카테고리를 작성했습니다.

UITExtField+Extended.h

@interface UITextField (Extended)

@property(retain, nonatomic)UITextField* nextTextField;

@end

UITextField+Extended.m

#import "UITextField+Extended.h"
#import <objc/runtime.h>

static char defaultHashKey;

@implementation UITextField (Extended)

- (UITextField*) nextTextField { 
    return objc_getAssociatedObject(self, &defaultHashKey); 
}

- (void) setNextTextField:(UITextField *)nextTextField{
    objc_setAssociatedObject(self, &defaultHashKey, nextTextField, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 
}

@end

사용 방법은 다음과 같습니다.

UITextField *textField1 = ...init your textfield
UITextField *textField2 = ...init your textfield
UITextField *textField3 = ...init your textfield

textField1.nextTextField = textField2;
textField2.nextTextField = textField3;
textField3.nextTextField = nil;

textFieldShouldReturn 메서드를 구현합니다.

- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {

    UITextField *next = theTextField.nextTextField;
    if (next) {
        [next becomeFirstResponder];
    } else {
        [theTextField resignFirstResponder];
    }

    return NO; 
}

이제 UITextField의 링크 리스트가 있습니다.각자는 다음 줄에 누가 있는지 알고 있습니다.

도움이 됐으면 좋겠다.

mxcl의 답변을 적용한 신속한 확장 기능(Traveler의 swift 2.3에 적용):

extension UITextField {
    class func connectFields(fields:[UITextField]) -> Void {
        guard let last = fields.last else {
            return
        }
        for i in 0 ..< fields.count - 1 {
            fields[i].returnKeyType = .Next
            fields[i].addTarget(fields[i+1], action: "becomeFirstResponder", forControlEvents: .EditingDidEndOnExit)
        }
        last.returnKeyType = .Done
        last.addTarget(last, action: #selector(UIResponder.resignFirstResponder), forControlEvents: .EditingDidEndOnExit)
    }
}

사용하기 쉽다:

UITextField.connectFields([field1, field2, field3])

내선번호는 마지막 필드를 제외한 모든 필드에 대해 반환 버튼을 "다음"으로 설정하고 마지막 필드에 대해 "완료"로 설정하고 이러한 필드를 누르면 포커스를 전환하거나 키보드를 해제합니다.

신속한 2.3 미만

extension UITextField {
    class func connectFields(fields:[UITextField]) -> Void {
        guard let last = fields.last else {
            return
        }
        for var i = 0; i < fields.count - 1; i += 1 {
            fields[i].returnKeyType = .Next
            fields[i].addTarget(fields[i+1], action: "becomeFirstResponder", forControlEvents: .EditingDidEndOnExit)
        }
        last.returnKeyType = .Done
        last.addTarget(last, action: "resignFirstResponder", forControlEvents: .EditingDidEndOnExit)
    }
}

SWIFT 3: 이렇게 사용 -

UITextField.connectFields(fields: [field1, field2])

Extension:
    extension UITextField {
        class func connectFields(fields:[UITextField]) -> Void {
            guard let last = fields.last else {
                return
            }
            for i in 0 ..< fields.count - 1 {
                fields[i].returnKeyType = .next
                fields[i].addTarget(fields[i+1], action: #selector(UIResponder.becomeFirstResponder), for: .editingDidEndOnExit)
            }
            last.returnKeyType = .go
            last.addTarget(last, action: #selector(UIResponder.resignFirstResponder), for: .editingDidEndOnExit)
        }
    }

보다 일관되고 견고한 방법은 Next Responder를 사용하는 것입니다.TextField 위임자를 설정하거나 사용할 필요 없이 인터페이스 빌더에서 완전히 구성할 수 있습니다.view.tag.

당신이 해야 할 일은

  1. 합니다.UITextFieldNextResponderTextField 여기에 이미지 설명 입력
  2. 에 ' 설정'을 해 주세요.nextResponderField이든 될 수 있습니다.UITextField 임의의 「」를 참조해 주세요.UIResponder수 있으며 UIButton을 트리거할 수 스마트합니다.TouchUpInside활성화되어 있는 경우에만 해당 버튼의 이벤트를 표시합니다. 여기에 이미지 설명 입력 여기에 이미지 설명 입력

동작하고 있는 라이브러리는 다음과 같습니다.

여기에 이미지 설명 입력

Anth0와 Answerbot에서 이미 제안한 OO 솔루션이 마음에 듭니다.다만, 저는 빠르고 작은 POC를 하고 있었기 때문에, 서브 클래스나 카테고리로 어수선하게 하고 싶지 않았습니다.

다른 간단한 해결책은 필드의 NSAray를 만들고 다음을 누를 때 다음 필드를 검색하는 것입니다.OOO 솔루션이 아니라 빠르고 단순하며 쉽게 구현할 수 있습니다.또한 주문을 한눈에 보고 수정할 수 있습니다.

다음은 내 코드입니다(이 스레드의 다른 답변에 기초함).

@property (nonatomic) NSArray *fieldArray;

- (void)viewDidLoad {
    [super viewDidLoad];

    fieldArray = [NSArray arrayWithObjects: firstField, secondField, thirdField, nil];
}

- (BOOL) textFieldShouldReturn:(UITextField *) textField {
    BOOL didResign = [textField resignFirstResponder];
    if (!didResign) return NO;

    NSUInteger index = [self.fieldArray indexOfObject:textField];
    if (index == NSNotFound || index + 1 == fieldArray.count) return NO;

    id nextField = [fieldArray objectAtIndex:index + 1];
    activeField = nextField;
    [nextField becomeFirstResponder];

    return NO;
}
  • 줄 바꿈을 삽입하고 싶지 않기 때문에 항상 NO를 반환합니다.YES를 반환하면 자동으로 다음 필드가 종료되거나 TextView에 줄 바꿈이 삽입되기 때문에 이 점을 지적해야 할 것 같습니다.그걸 알아내는데 시간이 좀 걸렸어요.
  • activeField는 필드를 키보드에서 분리하기 위해 스크롤이 필요한 경우 활성 필드를 추적합니다.유사한 코드가 있는 경우 첫 번째 응답자를 변경하기 전에 activeField를 할당해야 합니다.First Responder를 즉시 변경하면 KeyboardWasShown 이벤트가 즉시 실행됩니다.

UIControl의 카테고리를 사용한 탭 작성의 실장을 다음에 나타냅니다. Michael Ant0뿐만 모든 합니다.UITextField 및와도 원활하게 합니다. Interface Builder interface interface interface interface interface interface 。

소스 및 샘플 앱: UIControls With Tabbing용 GitHub 저장소

사용방법:

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [textField transferFirstResponderToNextControl];
    return NO;
}

인터페이스 빌더에서의 nextControl 할당

머리글:

//
// UIControl+NextControl.h
// UIControlsWithTabbing
//

#import <UIKit/UIKit.h>

@interface UIControl (NextControl)

@property (nonatomic, weak) IBOutlet UIControl *nextControl;

- (BOOL)transferFirstResponderToNextControl;

@end

구현:

#import "UIControl+NextControl.h"
#import <objc/runtime.h>

static char defaultHashKey;

@implementation UIControl (NextControl)

- (UIControl *)nextControl
{
    return objc_getAssociatedObject(self, &defaultHashKey);
}

- (void)setNextControl:(UIControl *)nextControl
{
    objc_setAssociatedObject(self, &defaultHashKey, nextControl, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (BOOL)transferFirstResponderToNextControl
{
    if (self.nextControl)
    {
        [self.nextControl becomeFirstResponder];

        return YES;
    }

    [self resignFirstResponder];

    return NO;
}

@end

많은 코드를 시험해 본 결과, Swift 3.0 Latest [2017년 3월]에서 사용할 수 있었습니다.

ViewController 한다.UITextFieldDelegate이 코드를 작동시키는 데 도움이 됩니다.

class ViewController: UIViewController,UITextFieldDelegate  

[ Text ]필드에 적절한 태그 번호를 추가합니다.이 태그 번호는 할당된 증분 태그 번호를 기반으로 적절한 텍스트필드로 컨트롤을 이동하기 위해 사용됩니다.

override func viewDidLoad() {
    userNameTextField.delegate = self
    userNameTextField.tag = 0
    userNameTextField.returnKeyType = UIReturnKeyType.next
    passwordTextField.delegate = self
    passwordTextField.tag = 1
    passwordTextField.returnKeyType = UIReturnKeyType.go
}

에서는 '''는returnKeyType = UIReturnKeyType.next는 기기음음음음음음음음음음음음음음음음으로 됩니다.Next 선택지가 , 하다, 하다, 하다, 이런 것도 있어요.Join/Go이치노

★★★★★★★★★★★★★★★★★.textFieldShouldReturn[ UIText Field Delegate ] : 。여기에서는 태그 값 증분에 따라 다음 필드를 선택합니다.

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    if let nextField = textField.superview?.viewWithTag(textField.tag + 1) as? UITextField {
        nextField.becomeFirstResponder()
    } else {
        textField.resignFirstResponder()
        return true;
    }
    return false
 }

하나의 텍스트 필드를 종료한 후 [otherTextField be FirstResponder]를 호출하면 다음 필드에 포커스가 표시됩니다.

화면을 스크롤하거나 텍스트 필드의 위치를 조정해야 하는 경우가 많기 때문에 편집 시 쉽게 확인할 수 있기 때문에 이 문제는 실제로 다루기 어려울 수 있습니다.텍스트 필드에 여러 가지 방법으로 드나들거나 일찍 나가거나 하는 많은 테스트를 실시해 주십시오(항상 다음 필드로 이동하지 않고 키보드를 끌 수 있는 옵션이 사용자에게 주어집니다(보통 네비게이션 바에서 "완료"로 표시됨).

 -(BOOL)textFieldShouldReturn:(UITextField *)textField
{
   [[self.view viewWithTag:textField.tag+1] becomeFirstResponder];
   return YES;
}

여기 있는 몇 가지 답변이 하나의 간단한 개념을 이해하지 못하는 것에 놀랐습니다. 앱의 컨트롤을 탐색하는 것은 보기 자체로는 할 수 없는 일입니다.다음 첫 번째 대응자를 어떤 제어기로 만들지는 통제관의 역할입니다.

또한 대부분의 답변은 앞으로 이동에만 적용되지만 사용자는 뒤로 이동하기를 원할 수도 있습니다.

그래서 내가 생각해낸 건 이거야.폼은 뷰 컨트롤러에 의해 관리되어야 하며 뷰 컨트롤러는 응답자 체인의 일부입니다.따라서 다음 방법을 자유롭게 구현할 수 있습니다.

#pragma mark - Key Commands

- (NSArray *)keyCommands
{
    static NSArray *commands;

    static dispatch_once_t once;
    dispatch_once(&once, ^{
        UIKeyCommand *const forward = [UIKeyCommand keyCommandWithInput:@"\t" modifierFlags:0 action:@selector(tabForward:)];
        UIKeyCommand *const backward = [UIKeyCommand keyCommandWithInput:@"\t" modifierFlags:UIKeyModifierShift action:@selector(tabBackward:)];

        commands = @[forward, backward];
    });

    return commands;
}

- (void)tabForward:(UIKeyCommand *)command
{
    NSArray *const controls = self.controls;
    UIResponder *firstResponder = nil;

    for (UIResponder *const responder in controls) {
        if (firstResponder != nil && responder.canBecomeFirstResponder) {
            [responder becomeFirstResponder]; return;
        }
        else if (responder.isFirstResponder) {
            firstResponder = responder;
        }
    }

    [controls.firstObject becomeFirstResponder];
}

- (void)tabBackward:(UIKeyCommand *)command
{
    NSArray *const controls = self.controls;
    UIResponder *firstResponder = nil;

    for (UIResponder *const responder in controls.reverseObjectEnumerator) {
        if (firstResponder != nil && responder.canBecomeFirstResponder) {
            [responder becomeFirstResponder]; return;
        }
        else if (responder.isFirstResponder) {
            firstResponder = responder;
        }
    }

    [controls.lastObject becomeFirstResponder];
}

미리 볼 수 있는 화면 외 응답자를 스크롤하기 위한 추가 논리가 적용될 수 있습니다.

의 또 할 수 모든 을 하위 분류할예 이른른른른른른른른른 you you른 another another another another another another another another another another another another another another another ) 。UITextFields) 대신 컨트롤러 레벨에서 로직을 관리할 수 있습니다.솔직히 말하면, 로직을 관리하는 것이 적절한 장소입니다.

Done(완료) 버튼을 눌렀을 때 키보드를 쉽게 끌 수 있는 방법은 다음과 같습니다.

헤더에 새 IBAtion을 만듭니다.

- (IBAction)textFieldDoneEditing:(id)sender;

구현 파일(.m 파일)에 다음 방법을 추가합니다.

- (IBAction)textFieldDoneEditing:(id)sender 
{ 
  [sender resignFirstResponder];
}

그런 다음 IBAtion을 텍스트 필드에 링크하려면 '종료 시 종료' 이벤트에 링크하십시오.

에 키보드 리턴 않으면 xib로 를 쓸 수 .을 사용하다viewdidload:

passWord.returnKeyType = UIReturnKeyNext;

-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
    if(textField == eMail) {
        [textField resignFirstResponder];
        [userName becomeFirstResponder];
    }
    if (textField==userName) {
        [textField resignFirstResponder];
        [passWord becomeFirstResponder];
    }
    if (textField==passWord) {
        [textField resignFirstResponder];
        [country becomeFirstResponder];
    }
    if (textField==country) {
        [textField resignFirstResponder];
    }
    return YES;
}

이런 걸 원하는 사람이 있다면.이것이 문제의 요구조건에 가장 가까운 것 같습니다.

여기에 이미지 설명 입력

이 기능을 구현한 방법은 다음과 같습니다.

설정할 각 텍스트필드에 대한 액세서리뷰를 추가합니다.

func setAccessoryViewFor(textField : UITextField)    {
    let toolBar = UIToolbar()
    toolBar.barStyle = .default
    toolBar.isTranslucent = true
    toolBar.sizeToFit()

    // Adds the buttons

    // Add previousButton
    let prevButton = UIBarButtonItem(title: "<", style: .plain, target: self, action: #selector(previousPressed(sender:)))
    prevButton.tag = textField.tag
    if getPreviousResponderFor(tag: textField.tag) == nil {
        prevButton.isEnabled = false
    }

    // Add nextButton
    let nextButton = UIBarButtonItem(title: ">", style: .plain, target: self, action: #selector(nextPressed(sender:)))
    nextButton.tag = textField.tag
    if getNextResponderFor(tag: textField.tag) == nil {
        nextButton.title = "Done"
    }

    let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
    toolBar.setItems([prevButton,spaceButton,nextButton], animated: false)
    toolBar.isUserInteractionEnabled = true
    textField.inputAccessoryView = toolBar
}

탭 처리에는 다음 기능을 사용합니다.

func nextPressed(sender : UIBarButtonItem) {
    if let nextResponder = getNextResponderFor(tag: sender.tag) {
        nextResponder.becomeFirstResponder()
    } else {
        self.view.endEditing(true)
    }

}

func previousPressed(sender : UIBarButtonItem) {
    if let previousResponder = getPreviousResponderFor(tag : sender.tag)  {
        previousResponder.becomeFirstResponder()
    }
}

func getNextResponderFor(tag : Int) -> UITextField? {
    return self.view.viewWithTag(tag + 1) as? UITextField
}

func getPreviousResponderFor(tag : Int) -> UITextField? {
    return self.view.viewWithTag(tag - 1) as? UITextField
}

textFields 태그는 다음/프리브버튼이 응답하는 순서로 지정해야 합니다.

Swift 3.1의 솔루션: 텍스트 필드를 연결한 후 IBOutlets는 텍스트 필드 위임자를 viewDidLoad에 설정한 다음 textFieldShouldReturn에서 작업을 탐색합니다.

class YourViewController: UIViewController,UITextFieldDelegate {

        @IBOutlet weak var passwordTextField: UITextField!
        @IBOutlet weak var phoneTextField: UITextField!

        override func viewDidLoad() {
            super.viewDidLoad()
            self.passwordTextField.delegate = self
            self.phoneTextField.delegate = self
            // Set your return type
            self.phoneTextField.returnKeyType = .next
            self.passwordTextField.returnKeyType = .done
        }

        func textFieldShouldReturn(_ textField: UITextField) -> Bool{
            if textField == self.phoneTextField {
                self.passwordTextField.becomeFirstResponder()
            }else if textField == self.passwordTextField{
                // Call login api
                self.login()
            }
            return true
        }

    }

이전/다음 버튼 기능을 구현하려는 경우를 위해 PeyloW의 답변에 추가했습니다.

- (IBAction)moveThroughTextFields:(UIBarButtonItem *)sender 
{
    NSInteger nextTag;
    UITextView *currentTextField = [self.view findFirstResponderAndReturn];

    if (currentTextField != nil) {
        // I assigned tags to the buttons.  0 represent prev & 1 represents next
        if (sender.tag == 0) {
            nextTag = currentTextField.tag - 1;

        } else if (sender.tag == 1) {
            nextTag = currentTextField.tag + 1;
        }
    }
    // Try to find next responder
    UIResponder* nextResponder = [self.view viewWithTag:nextTag];
    if (nextResponder) {
        // Found next responder, so set it.
        // I added the resign here in case there's different keyboards in place.
        [currentTextField resignFirstResponder];
        [nextResponder becomeFirstResponder];
    } else {
        // Not found, so remove keyboard.
        [currentTextField resignFirstResponder];

    }
}

UIView를 다음과 같이 분류할 수 있습니다.

@implementation UIView (FindAndReturnFirstResponder)
- (UITextView *)findFirstResponderAndReturn
{
    for (UITextView *subView in self.subviews) {
        if (subView.isFirstResponder){
            return subView;
        }
    }
    return nil;
}
@end

여러분 안녕하세요 이거 보세요

- (void)nextPrevious:(id)sender
{

  UIView *responder = [self.view findFirstResponder];   

  if (nil == responder || ![responder isKindOfClass:[GroupTextField class]]) {
    return;
  }

  switch([(UISegmentedControl *)sender selectedSegmentIndex]) {
    case 0:
      // previous
      if (nil != ((GroupTextField *)responder).previousControl) {
        [((GroupTextField *)responder).previousControl becomeFirstResponder];
        DebugLog(@"currentControl: %i previousControl: %i",((GroupTextField *)responder).tag,((GroupTextField *)responder).previousControl.tag);
      }
      break;
    case 1:
      // next
      if (nil != ((GroupTextField *)responder).nextControl) {
        [((GroupTextField *)responder).nextControl becomeFirstResponder];
        DebugLog(@"currentControl: %i nextControl: %i",((GroupTextField *)responder).tag,((GroupTextField *)responder).nextControl.tag);
      }     
      break;    
  }
}

이를 각 셀(또는 셀)을 하는 것을 으로 좀 더 하려고 했습니다.UITextField)에서는UITableView나중에 가져올 수 있는 고유한 태그 값: activate-next-uitextfield-in-uitableview-ios

도움이 됐으면 좋겠네요!

GNTextFieldsCollectionManager를 다룰 때 새로운 Pod를 만들었습니다.다음/마지막 textField 문제를 자동으로 처리하고 매우 사용하기 쉽습니다.

[[GNTextFieldsCollectionManager alloc] initWithView:self.view];

뷰 계층(또는 태그)에 표시됨으로써 정렬된 모든 텍스트 필드를 가져오거나 textFields의 배열을 직접 지정할 수 있습니다.

보다 안전하고 직접적인 방법:

  • 텍스트 필드 딜러가 뷰 컨트롤러로 설정됩니다.
  • 모든 텍스트 필드가 동일한 보기의 하위 보기입니다.
  • 텍스트 필드에는 진행하려는 순서대로 태그가 있습니다(예: textField2.tag = 2, textField3.tag = 3 등).
  • 키보드의 되돌리기 버튼을 누르면 다음 텍스트 필드로 이동합니다(다음, 완료 등으로 변경할 수 있습니다).
  • 마지막 텍스트 필드 뒤에 키보드가 닫히도록 합니다.

Swift 4.1:

extension ViewController: UITextFieldDelegate {
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        let nextTag = textField.tag + 1
        guard let nextTextField = textField.superview?.viewWithTag(nextTag) else {
            textField.resignFirstResponder()
            return false
        }

    nextTextField.becomeFirstResponder()

    return false

    }
}

저는 오히려 다음을 선호합니다.

@interface MyViewController : UIViewController
@property (nonatomic, retain) IBOutletCollection(UIView) NSArray *inputFields;
@end

NIB 파일에서 원하는 순서대로 textFields를 이 inputFields 배열에 후크합니다.그런 다음 UITextField 인덱스에 대한 간단한 테스트를 수행하여 사용자가 return을 눌렀다고 보고합니다.

// for UITextField
-(BOOL)textFieldShouldReturn:(UITextField*)textField {
    NSUInteger index = [_inputFields indexOfObject:textField];
    index++;
    if (index < _inputFields.count) {
        UIView *v = [_inputFields objectAtIndex:index];
        [v becomeFirstResponder];
    }
    return NO;
}

// for UITextView
-(BOOL)textView:(UITextView*)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString*)text {
    if ([@"\n" isEqualToString:text]) {
        NSUInteger index = [_inputFields indexOfObject:textView];
        index++;
        if (index < _inputFields.count) {
            UIView *v = [_inputFields objectAtIndex:index];
            [v becomeFirstResponder];
        } else {
            [self.view endEditing:YES];
        }
        return NO;
    }
    return YES;
}
if (셀==영){셀 = [UITableViewCell allocate] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
txt_Input = [[ UITextField allocate ]initWithFrame :CGRectMake(0, 10, 150, 30);
txt_Input.tag = indexPath.row+1;[self.array_]텍스트 필드 addObject:txt_Input];// ViewDidLoad에서 변경 가능한 배열을 초기화합니다.}
- (BOOL) textField ShouldReturn : (UITextField *) textField{
int 태그 = ( int ) textField.tag ;UITextField * txt = [ self . array _ ]텍스트 필드 objectAtIndex:tag ] ;[txt가 First Responder가 된다];YES를 반환한다.}

스토리보드에 10개 이상의 UITextField가 있는데, 다음 기능을 활성화하기 위해서는 UITextField 배열을 만들고 다음 UITextField를 firstResponder로 만들어야 합니다.구현 파일은 다음과 같습니다.

#import "RegistrationTableViewController.h"

@interface RegistrationTableViewController ()
@property (weak, nonatomic) IBOutlet UITextField *fullNameTextField;
@property (weak, nonatomic) IBOutlet UITextField *addressTextField;
@property (weak, nonatomic) IBOutlet UITextField *address2TextField;
@property (weak, nonatomic) IBOutlet UITextField *cityTextField;
@property (weak, nonatomic) IBOutlet UITextField *zipCodeTextField;
@property (weak, nonatomic) IBOutlet UITextField *urlTextField;
@property (weak, nonatomic) IBOutlet UITextField *usernameTextField;
@property (weak, nonatomic) IBOutlet UITextField *emailTextField;
@property (weak, nonatomic) IBOutlet UITextField *passwordTextField;
@property (weak, nonatomic) IBOutlet UITextField *confirmPWTextField;

@end
NSArray *uiTextFieldArray;
@implementation RegistrationTableViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"view did load");
    uiTextFieldArray = @[self.fullNameTextField,self.addressTextField,self.address2TextField,self.cityTextField,self.zipCodeTextField,self.urlTextField,self.usernameTextField,self.emailTextField,self.passwordTextField,self.confirmPWTextField];
    for(UITextField *myField in uiTextFieldArray){
        myField.delegate = self;
    }


}
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
    long index = [uiTextFieldArray indexOfObject:textField];
    NSLog(@"%ld",index);
    if(index < (uiTextFieldArray.count - 1)){
        [uiTextFieldArray[++index] becomeFirstResponder];
    }else{
        [uiTextFieldArray[index] resignFirstResponder];
    }
    return YES;
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

이건 자마린에서 통했어iOS / 모노 터치키보드 버튼을 [Next](다음)으로 변경하고 컨트롤을 다음 [UITextField](UITextField)로 넘겨 마지막 [UITextField](UITextField) 이후 키보드를 숨깁니다.

private void SetShouldReturnDelegates(IEnumerable<UIView> subViewsToScout )
{
  foreach (var item in subViewsToScout.Where(item => item.GetType() == typeof (UITextField)))
  {
    (item as UITextField).ReturnKeyType = UIReturnKeyType.Next;
    (item as UITextField).ShouldReturn += (textField) =>
    {
        nint nextTag = textField.Tag + 1;
        var nextResponder = textField.Superview.ViewWithTag(nextTag);
        if (null != nextResponder)
            nextResponder.BecomeFirstResponder();
        else
            textField.Superview.EndEditing(true); 
            //You could also use textField.ResignFirstResponder(); 

        return false; // We do not want UITextField to insert line-breaks.
    };
  }
}

View Did Load 내에는 다음과 같은 기능이 있습니다.

TextFields에 태그가 설정되어 있지 않은 경우:

txtField1.Tag = 0;
txtField2.Tag = 1;
txtField3.Tag = 2;
//...

전화만 해도

SetShouldReturnDelegates(yourViewWithTxtFields.Subviews.ToList());
//If you are not sure of which view contains your fields you can also call it in a safer way:
SetShouldReturnDelegates(txtField1.Superview.Subviews.ToList());
//You can also reuse the same method with different containerViews in case your UITextField are under different views.

이것은 태그나 스토리보드 트릭을 사용하지 않고 빠르게 해결할 수 있는 심플한 솔루션입니다.

다음 내선번호를 사용합니다.

extension UITextField{

    func nextTextFieldField() -> UITextField?{
        //field to return
        var returnField : UITextField?
        if self.superview != nil{
            //for each view in superview
            for (_, view) in self.superview!.subviews.enumerate(){
                //if subview is a text's field
                if view.isKindOfClass(UITextField){
                    //cast curent view as text field
                    let currentTextField = view as! UITextField
                    //if text field is after the current one
                    if currentTextField.frame.origin.y > self.frame.origin.y{
                        //if there is no text field to return already
                        if returnField == nil {
                            //set as default return
                            returnField = currentTextField
                        }
                            //else if this this less far than the other
                        else if currentTextField.frame.origin.y < returnField!.frame.origin.y{
                            //this is the field to return
                            returnField = currentTextField
                        }
                    }
                }
            }
        }
        //end of the mdethod
        return returnField
    }

}

텍스트 필드 위임자를 사용하여 다음과 같이 호출합니다(예를 들어).

func textFieldShouldReturn(textField: UITextField) -> Bool {
    textField.resignFirstResponder()
    textField.nextTextFieldField()?.becomeFirstResponder()
    return true
}

다음은 Ant0의 Swift 3 버전입니다.빠른 개발자가 그의 훌륭한 답변을 활용할 수 있도록 돕기 위해 이 글을 올렸습니다!연관된 개체를 설정할 때 "Next"라는 리턴 키 유형을 추가했습니다.

extension UITextField {

  @nonobjc static var NextHashKey: UniChar = 0

  var nextTextField: UITextField? {
    get {
      return objc_getAssociatedObject(self, 
        &UITextField.NextHashKey) as? UITextField
    }
    set(next) {
     self.returnKeyType = UIReturnKeyType.next
     objc_setAssociatedObject(self,
      &UITextField.NextHashKey,next,.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }
  }
}

위 코드를 사용하여 UITextField 목록을 순환할 수 있는 가능성을 보여주는 다른 확장자를 다음에 나타냅니다.

extension UIViewController: UITextFieldDelegate {
 public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
   guard let next = textField.nextTextField else {
     textField.resignFirstResponder()
     return true
   }

    next.becomeFirstResponder()
    return false
  }
}

그런 다음 ViewController 또는 다른 곳에서 텍스트 필드를 다음과 같이 설정할 수 있습니다.

@IBOutlet fileprivate weak var textfield1: UITextField!
@IBOutlet fileprivate weak var textfield2: UITextField!
@IBOutlet fileprivate weak var textfield3: UITextField!

...

[textfield1, textfield2, textfield3].forEach{ $0?.delegate = self }

textfield1.nextTextField = textfield2
textfield2.nextTextField = textfield3
// We don't assign a nextTextField to textfield3 because we want 
// textfield3 to be the last one and resignFirstResponder when 
// the return button on the soft keyboard is tapped.

textFieldShouldReturn에서 현재 텍스트 필드가 마지막 필드가 아님을 확인해야 합니다.또, 그 텍스트 필드가 키보드를 해제하지 않는 경우는, 확인해 주세요.

오래된 투고이지만 페이지 순위가 높기 때문에 제 해결책에 대해 설명하겠습니다.

비슷 of of of of of of of of of of of of of of of of of라는 를 만들었습니다.UIToolbar동적 테이블에서 다음/이전/완료된 기능을 관리하려면섹션과 함께 보기:https://github.com/jday001/DataEntryToolbar

툴바를 텍스트필드의 inputAccessoryView로 설정하여 사전에 추가합니다.이것에 의해, 동적인 컨텐츠에서도, 앞뒤로 순환할 수 있습니다.textField 탐색이 발생할 때 자체 기능을 트리거하려는 경우 위임 메서드가 있지만 태그나 최초 응답자 상태를 관리할 필요가 없습니다.

GitHub 링크에는 구현 세부사항을 지원하는 코드 스니펫과 샘플 앱이 있습니다.필드 내의 값을 추적하려면 자체 데이터 모델이 필요합니다.

태그를 사용하지 않고 nextField/nextTextField 속성을 추가하지 않고 Tab을 에뮬레이트할 수 있습니다.여기서 "testInput"은 현재 활성 필드입니다.

if ([textInput isFirstResponder])
    [textInput.superview.subviews enumerateObjectsAtIndexes:
     [NSIndexSet indexSetWithIndexesInRange:
      NSMakeRange([textInput.superview.subviews indexOfObject:textInput]+1,
                  [textInput.superview.subviews count]-[textInput.superview.subviews indexOfObject:textInput]-1)]
                                                    options:0 usingBlock:^(UIView *obj, NSUInteger idx, BOOL *stop) {
                                                        *stop = !obj.hidden && [obj becomeFirstResponder];
                                                    }];
if ([textInput isFirstResponder])
    [textInput.superview.subviews enumerateObjectsAtIndexes:
     [NSIndexSet indexSetWithIndexesInRange:
      NSMakeRange(0,
                  [textInput.superview.subviews indexOfObject:textInput])]
                                                    options:0 usingBlock:^(UIView *obj, NSUInteger idx, BOOL *stop) {
                                                        *stop = !obj.hidden && [obj becomeFirstResponder];
                                                    }];

언급URL : https://stackoverflow.com/questions/1347779/how-to-navigate-through-textfields-next-done-buttons

반응형