2015-01-26 4 views
1

나는 여러 시간 동안이 문제를 해결하려고 노력 해왔다. 내가 찾은 게시물 중 어느 것도 해결책을 제공하지 못했습니다. 문제는 textField가 하위보기에 있고 키보드를 숨기려면 Return 단추에 응답하는 방법을 알아낼 수 없다는 것입니다. 다음은 내 View Controller입니다.- (BOOL) textFieldShouldReturn : (UITextField *) textField; 키보드를 하위보기로 옮기려면

#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 

여기 내 맞춤 클래스입니다.

#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 

코드는 키보드 숨기기를 제외한 모든 측면에서 완벽하게 작동합니다.

name.delegate = self; 

또는 당신은 당신의 뷰 컨트롤러에 위임 콘센트를 드래그하여, 연결 Inspector에서 스토리 보드에서이 작업을 수행 할 수 있습니다 :

+0

텍스트 필드가 모두 제대로 작동하고 응용 프로그램이 충돌없이 오류없이 경고없이 모든 데이터를 완벽하게 처리합니다. 키보드를 없애기위한 방법 (K 명령어 제외)을 찾을 수 없습니다. 이것은 결국 장치에있게 될 것이므로 명령 K는 쓸모가 없습니다. textField는 뷰 컨트롤러의 버튼에 의해 동적으로 생성됩니다. 이것은 나에게 계층 구조 문제라고 생각됩니다. 이 응용 프로그램의 다른 모든 측면은 계층 노래와 춤을 잘 않습니다. – Hammerhead96

+0

하위 뷰 xib에서 대리자가 뷰에 연결되지 않았습니다. 첫 번째 응답자에 대한 호출에서도 "이름"은 더 이상 표시되지 않으며 [textField resignFirstResponder]; ... 이제 작동합니다. 문제 해결됨. 모두 감사합니다! – Hammerhead96

답변

0

가장 기본적인 의미에서 현재 활성 텍스트 필드는 resignFirstResponder입니다. 문제는 해당 텍스트 필드에 액세스하는 방법 인 것 같습니다.

편집 : 텍스트 필드에 액세스 : 내가 대신 1

목표의 몇 가지 해결 방법을 자세히 설명하고 있습니다로 아래 단락, 항목을 빠르게 이동합니다. 솔루션 : 1) 사용자 지정 클래스의 텍스트 필드를 노출하는 속성을 만듭니다. 2) 사용자 정의 클래스의 텍스트 필드를 호출하는 함수를 만듭니다.

각보기에 4 개의 텍스트 필드가 있다고 가정 할 때 텍스트 필드를 표시하는 4 가지 속성이 있습니까?

그런 경우에는 함수를 만들고 해당 함수에서보기로 이동하여 self.textField1을 호출 한 다음 blt, self.textField2를 호출하는지 확인하십시오.

현재 콜백에서 resignFirstResponder라는 이름을 호출합니다. 하지만 우선 조금만 돌아 봅시다. 모든 textField는 해당 대리자에서 textFieldShouldReturn을 호출합니다. 따라서 텍스트 필드 4 개 모두가 위임자로 볼 수 있어야합니다. 인터페이스 빌더 또는 코드에서 self.name.delegate (또는 self.name.textFieldDelegate, 정확하게 잊어 버렸습니다) = self; 각 하나씩.

또한 "self"라고 부르십시오. "name"은 다른 것입니다. 사실 자기. 속성 접근 자에 액세스합니다. 그러나 그것이 만드는 보이지 않는 변수는 _name이라고 부릅니다 (처음에는 밑줄이있는 것과 같은 것, 이것은 모든 속성에서 유효합니다).

모든 필드가 올바르게 호출되었다는 것을 알았으므로 이제 대리인에게 돌아가 보겠습니다."현재 활성화 된, 반환하는"텍스트 필드가 응답자를 사퇴하기를 원한다면 델리게이트는 객체보기에서 textField를 전달하므로 현재 반환되는 필드에서 resignFirst ...를 호출하는 것을 잊지 마십시오. 당신의 이름 (self.name, 또는 다른 사람)에 의해 액세스 않도록에 textField, 그렇지 않으면 존재하지 않기 때문에, 대리인 콜백 메소드에 속하는 물론

[textField resignFirstResponder] 

.

마지막으로 중요한 것은 있지만 모든 것을 숨긴 버튼이지만 화면을 가릴만큼 커야 만 함수를 호출 할 수 있습니다. 이 기능에서는 모든 텍스트 필드에 호출을 "표시"할 수 있습니다. 기본적으로이 함수를 "hideTheKeyboard"또는 모든 사용자 정의보기에서 사용자가 지정한 이름 (사용자 정의보기의 모든 필드에서 resignFirst ...를 호출하는 함수)으로 호출합니다.

for (view in customViews)는 사용자 정의 함수를 호출하지만 roll을 호출하는 대신 사용자 정의 함수를 호출합니다. 당신이 말할 수있는이 가능한 솔루션입니다 이유만으로 그 함수 내에서

는, 당신은 또한, 당신은 당신이 전화를 함수로 캡슐화 된 것을 할 수 있습니다 이유를

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

처럼 뭔가를 할 수 있지만, 단순히 적은 코드 줄/단순함으로. 어떻게 작동하는지 솔루션을 찾는 것보다 어떻게 그리고 왜 그것을 할 수 있는지 이해하는 것이 더 중요합니다. 위에 나열된 3 가지 솔루션이 있습니다 (속성 사용, textField에 액세스하는 함수 사용 또는 대리자 사용).

가장 단순한 것은 대리자이고 가장 컴팩트 한 것은 함수이며 가장 널리 사용되는 것은 속성입니다. (각각에 제한이 있습니다). 나는 당신이 그들을 볼 수 있도록 철저한 이해를주고 싶었다.

+0

문제가 해결되었습니다. 하위보기 xib에서 대리인이보기에 연결되지 않았습니다. 첫 번째 응답자에 대한 호출에서도 "이름"은 더 이상 표시되지 않으며 [textField resignFirstResponder]; ... 이제 작동합니다. 순전히 스티븐 감사합니다 !!! 그것이 놓칠 수있는 작지만 쉬운 단계라는 것이 놀랍습니다. – Hammerhead96

0

하면 textFieldDidEndEditing: 방법에 넣어

- (void)textFieldDidEndEditing:(UITextField *)textField { 
{ 
[textField resignFirstResponder]; 
} 
+0

내 아이폰에서 오타를 입력해서 죄송합니다. – soulshined

+0

위의 SyedAliSalman을 참조하십시오. 작동하지 않습니다. 나는 딸꾹질이 textField가 동적으로 생성 된 하위 뷰에 있다고 생각합니다. 내가 모르는 부도덕 한 방식으로 자녀 부모 관계를 사용해야합니다. – Hammerhead96

+0

문제가 해결되었습니다. 하위보기 xib에서 대리인이보기에 연결되지 않았습니다. 첫 번째 응답자에 대한 호출에서도 "이름"은 더 이상 표시되지 않으며 [textField resignFirstResponder]; ... 이제 작동합니다. 모두 감사합니다! – Hammerhead96

0

의 viewDidLoad에서이 추가 .

추신 :이 경우 textFieldShouldReturn 메소드도보기 컨트롤러에 있어야합니다.

+0

사용자 정의 클래스에는 viewDidLoad가 없습니다. 뷰는 뷰 컨트롤러에 의해 호출되는 xib로 동적으로 생성됩니다. – Hammerhead96

+0

뷰 컨트롤러와 관련하여 "이름"은 존재하지 않습니다. "name"은 사용자 정의 클래스 "Combatant"에 속합니다. 또한, 위임자는 View Controller에게 자랑 할 수 없습니다. 그것을 "파일 소유자"로 드래그하면 충돌이 발생합니다. – Hammerhead96

+0

문제가 해결되었습니다. 하위보기 xib에서 대리인이보기에 연결되지 않았습니다. 첫 번째 응답자에 대한 호출에서도 "이름"은 더 이상 표시되지 않으며 [textField resignFirstResponder]; ... 이제 작동합니다. 모두 감사합니다! – Hammerhead96

-1

반환해야하는지 여부를 설명하는 위임을 사용하고 있습니까? 그리고 심지어 돌아 오기 전에는 텍스트 필드 키보드로 이벤트를 보내서 되돌릴 수 없거나 불가능한 이벤트를 보냅니다. @soulshined에서 언급 한 코드를 시도하십시오.

- (void)textFieldDidEndEditing:(UITextField *)textField { 
{ 
    [textField resignFirstResponder]; 
} 
+0

나는이 4 가지 방법을 구현하려고 시도했지만 아무런 영향을주지 않았다. – Hammerhead96

+1

나는 Syed가 당신이 다른 것을위한 위임 방법을 사용하고 있다고 언급하고 있다고 믿는다. TextFieldShouldReturn은 목적을 가지고 있습니다. 짧은 형식은 리턴 값으로 새 행을 만들지 여부를 결정하는 것입니다. NO를 전달하면 "리턴"하지 않고 새로운 행을 작성합니다. 그러나 Syed가 설명하는 방법이 나올 때까지 키보드를 닫지 않습니다. 아래에서 더 자세히 설명하겠습니다. –

+0

Return 키를 눌렀을 때 TextFieldShouldReturn이 키보드를 닫을 것이라고 생각했습니다. 어떻게 든 잘못 되었나요? ... 검색에 대한 많은 답변 "이 키보드를 iOS에서 사라지게 만드는 방법"- (BOOL) textFieldShouldReturn : (UITextField *) textField; ...이 함수가 이것을하지 않거나하지 말아야한다고 들리는 것 같습니다 ... 혼란 스럽습니다. – Hammerhead96

관련 문제