Почему объекты продолжают становиться первыми респондентами в цикле?
У меня есть представление, которое содержит около 50 небольших текстовых полей. При редактировании этих textFields в какой-то момент все textFields становятся первыми респондентами и вызывают делегат - textFieldDidBeginEditing. textFieldDidBeginEditing вызывается для всех textFields в цикле, а приложение является стеком. (также вызывается уведомление клавиатуры DidShow прямо перед textFieldDidBeginEditing) Я не смог найти конкретный триггер для этого странного события, это просто произошло примерно через минуту редактирования. Это происходит только на iPhone, а не на iPad.
Что может быть причиной того, что объект респондента стал первым респондентом в цикле?
Я добавляю код, который кажется актуальным. Идея этих TextField заключается в том, что каждый из них может нести одну букву. Каждый раз, когда textField получает свое письмо, он подает в отставку firstResponder и позволяет следующему TextField стать FirstResponder.
Моя реализация UITextFieldDelegate:
-(void)textFieldDidBeginEditing:(UIOneLetterTextField *)iTextField {
lastTextField = iTextField;
if (iTextField.didPressed)
{
iTextField.didPressed = NO;
[self setDefaultArrow];
[self hideAllCellsFill];
}
[iTextField performSelector:@selector(selectAll:) withObject:iTextField afterDelay:0.0];
[self createInputAccessoryView];
[iTextField setInputAccessoryView:inputAccView];
CGRect stvRect = CGRectMake(iTextField.frame.origin.x*lastScaleFactor, iTextField.frame.origin.y*lastScaleFactor, iTextField.frame.size.width*lastScaleFactor, iTextField.frame.size.height*lastScaleFactor);
lastTextFrame.origin.x = stvRect.origin.x - scrollView.contentOffset.x;
lastTextFrame.origin.y = stvRect.origin.y- scrollView.contentOffset.y;
lastTextFrame.size.width = stvRect.size.width;
lastTextFrame.size.height = stvRect.size.height;
[scrollView scrollRectToVisible:stvRect animated:YES];
}
- (BOOL)textField:(UIOneLetterTextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSLog(@"Key Pressed %@", string);
[[multiplayersModel multiplayersModelSharedInstance] localKeyPressedOnLocation:textField.cellLoc withText:string];
NSLog(@"resignFirstResponder (%u,%u)", textField.cellLoc.locationX, textField.cellLoc.locationY);
[textField resignFirstResponder];
UITapGestureRecognizer * ges = [[UITapGestureRecognizer alloc] initWithTarget:textField action:@selector(pressed:)];
[textField addGestureRecognizer:ges];
[self gotoNextTextfield:textField.cellLoc];
return NO;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
UIOneLetterTextField* tf =(UIOneLetterTextField*)(textField);
NSLog(@"resignFirstResponder (%u,%u)", tf.cellLoc.locationX, tf.cellLoc.locationY);
[textField resignFirstResponder];
return NO;
}
Реализацию клавиатуры NSNotifications я зарегистрировал для:
// avoid text behind keyboard.
-(void) keyboardDidShow: (NSNotification *)notif
{
NSLog(@"keyboardDidShow");
self.navigationController.navigationBar.hidden = YES;
CGRect keyboardRect = [[[notif userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
UIWindow *window = [[[UIApplication sharedApplication] windows]objectAtIndex:0];
UIView *mainSubviewOfWindow = window.rootViewController.view;
CGRect keyboardFrameConverted = [mainSubviewOfWindow convertRect:keyboardRect fromView:window];
CGFloat buriedUnderKeboard;
if ([self isPhone])
{
buriedUnderKeboard = lastTextFrame.origin.y + lastTextFrame.size.height + 35.0 - keyboardFrameConverted.origin.y;
}
else{
buriedUnderKeboard = lastTextFrame.origin.y + lastTextFrame.size.height + 65.0 - keyboardFrameConverted.origin.y;
}
if (buriedUnderKeboard > 0)
{
CGPoint offset = {scrollView.contentOffset.x, scrollView.contentOffset.y+buriedUnderKeboard};
[scrollView setContentOffset:offset animated:YES];
}
}
-(void) keyboardWillHide: (NSNotification *)notif
{
self.navigationController.navigationBar.hidden = NO;
[self hideAllCellsFill];
}
Реализация UIOneLetterTextField (наследуется от UITextField) - класс, представляющий однобуквенный TestField (initCellCharachter:withContentScaleFactor: является назначенным инициализатором):
#import "UIOneLetterTextField.h"
@interface UIOneLetterTextField()
@property CGFloat myoriginx;
@property CGFloat myoriginy;
@property CGFloat mywidth;
@property CGFloat myheight;
@property (nonatomic, strong) UITapGestureRecognizer * tapGes;
@end
@implementation UIOneLetterTextField
@synthesize cellLoc;
@synthesize didPressed;
@synthesize myoriginx;
@synthesize myoriginy;
@synthesize mywidth;
@synthesize myheight;
@synthesize tapGes;
-(void)myAddGesture
{
NSLog(@"resignFirstResponder (%u,%u)", self.cellLoc.locationX, self.cellLoc.locationY);
[self resignFirstResponder];
[tapGes setEnabled:YES];
UITapGestureRecognizer * ges = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(pressed:)];
[self addGestureRecognizer:ges];
}
-(void)internalInit
{
UITapGestureRecognizer * ges = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(pressed:)];
[self addGestureRecognizer:ges];
tapGes = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(pressed:)];
[self addGestureRecognizer:tapGes];
self.textAlignment = NSTextAlignmentCenter;
self.font = [UIFont systemFontOfSize:MIN(self.mywidth,self.myheight)*3/4];
self.textColor = [UIColor blueColor];
self.backgroundColor = [UIColor clearColor];
self.opaque = NO;
self.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
self.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
[self setReturnKeyType:UIReturnKeyDone];
}
-(void)pressed:(id)sender
{
didPressed = YES;
NSLog(@"becomeFirstResponder (%u,%u)", self.cellLoc.locationX, self.cellLoc.locationY);
[self becomeFirstResponder];
}
- (id)initCellCharachter:(cellCharachter *)c
withContentScaleFactor:(CGFloat)csf{
didPressed = NO;
c.tlx/=csf;
c.tly/=csf;
c.blx/=csf;
c.bly/=csf;
c.trx/=csf;
c.try/=csf;
c.brx/=csf;
c.bry/=csf;
self.cellLoc = c.cellLoc;
CGFloat width = MIN(c.trx,c.brx) - MAX(c.tlx,c.blx);
CGFloat height = MIN(c.bly, c.bry) - MAX(c.try,c.tly);
CGRect rct = CGRectMake(MAX(c.tlx,c.blx),MAX(c.tly,c.try),width,height);
self = [super initWithFrame:rct];
if (self) {
myoriginx =MIN(c.tlx,c.blx);
myoriginy =MIN(c.tly,c.try);
mywidth =width;
myheight =height;
[self internalInit];
}
return self;
}
//Disabling copy|paste|select popup menu
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
return NO;
}
@end
1 ответ
Я заметил, что если вы соедините MITLIPLE UITextField со значением становления FirstResponder, когда вы отклоните последнее текстовое поле, которое украло первого респондента, второе последнее текстовое поле снова получит статус первого респондента, как если бы оно возобновляло статус первого респондента.
Не уверен, если это поможет вам в любом случае.