What am I doing wrong to adjust my view in iOS whe

2019-08-30 11:47发布

问题:

I have 6 Textfields in my viewController. 2 on the first row, 1 on the second, 1 on the third and 2 on the last row. The textfields work fine as far as typing into it. I just have issues scrolling the view up and down when the keyboard appears. The view scrolls up fine but when I "resign responder", the view scrolls down but scrolls down too much. e.g. if the view moved up by y amount, once I resign responder, the view would move down a value greater than y.

I have the following code set up (I've provided extra code just in case but I believe the problem is in setViewMovedUp method, but I may be wrong):

Keyboard showing:

-(void)keyboardWillShow:(NSNotification*)sender {
// Animate the current view out of the way
NSDictionary* info = [sender userInfo];
kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

if (!didViewMove) {

    didViewMove = YES;

    if (self.view.frame.origin.y >= 0)
    {
        [self setViewMovedUp:YES];

    }
    else if (self.view.frame.origin.y < 0)
    {
        [self setViewMovedUp:NO];
    }
}
}

-(void)keyboardWillHide {

[UIView animateWithDuration:0.25 animations:^{
    self.view.frame = CGRectMake(0, _top, 320, self.view.frame.size.height);
}];
return;

didViewMove = NO;

if (self.view.frame.origin.y >= 0)
{
    [self setViewMovedUp:YES];
}
else if (self.view.frame.origin.y < 0)
{
    [self setViewMovedUp:NO];
}
}

Adjusting the View

 -(void)setViewMovedUp:(BOOL)movedUp
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3]; // slide up the view

int desiredHeight = (480 - kbSize.height) / 2;
int requiredHeightAdjustment;

if (didViewMove) {
    requiredHeightAdjustment = abs(desiredHeight - (self.view.frame.origin.y + activeField.frame.origin.y));
} else {
    requiredHeightAdjustment = abs(desiredHeight - (activeField.frame.origin.y ));
 //   requiredHeightAdjustment = abs(desiredHeight - (self.view.frame.origin.y + activeField.frame.origin.y));
}


CGRect rect = self.view.frame;

if (movedUp)
{
    // 1. move the view's origin up so that the text field that will be hidden come above the keyboard
    // 2. increase the size of the view so that the area behind the keyboard is covered up.
    rect.origin.y -= requiredHeightAdjustment;
   rect.size.height += requiredHeightAdjustment;

}
else
{
    // revert back to the normal state.
      rect.origin.y += requiredHeightAdjustment;
 rect.size.height -= requiredHeightAdjustment;
}
self.view.frame = rect;

[UIView commitAnimations];
}

Resigning Responder

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

UITouch *touch = [[event allTouches] anyObject];
if ([_cardnumbertext isFirstResponder] && [touch view] != _cardnumbertext) {
    [_cardnumbertext resignFirstResponder];
}
[super touchesBegan:touches withEvent:event];

UITouch *touch1 = [[event allTouches] anyObject];
if ([_salesamounttext isFirstResponder] && [touch1 view] != _salesamounttext) {
    [_salesamounttext resignFirstResponder];
}
[super touchesBegan:touches withEvent:event];

UITouch *touch2 = [[event allTouches] anyObject];
if ([_referencetext isFirstResponder] && [touch2 view] != _referencetext) {
    [_referencetext resignFirstResponder];
}
[super touchesBegan:touches withEvent:event];

UITouch *touch3 = [[event allTouches] anyObject];
if ([_datetext isFirstResponder] && [touch3 view] != _datetext) {
    [_datetext resignFirstResponder];
}
[super touchesBegan:touches withEvent:event];

UITouch *touch4 = [[event allTouches] anyObject];
if ([_timetext isFirstResponder] && [touch4 view] != _timetext) {
    [_timetext resignFirstResponder];
}
[super touchesBegan:touches withEvent:event];

UITouch *touch5 = [[event allTouches] anyObject];
if ([_reasontext isFirstResponder] && [touch5 view] != _reasontext) {
    [_reasontext resignFirstResponder];
}
[super touchesBegan:touches withEvent:event];
}

and lastly, setting up active fields

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
activeField = textField;
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
previousField = activeField;
}

回答1:

What I do is to make the final amount that I scroll up an instance variable. I also save the duration and timing curve settings from the keyboard notification.

Then, when the user finishes editing and I get notified that the keyboard is going away, I can just move my view by the reverse of the saved amount that I moved the view up in the first place.

I suggest using that approach.

I have a sample project on github that documents this approach in detail:

RandomBlobs project on github

Look in the README for a section titled "Miscellaneous techniques". Look for a link "Sliding your views to make room for the keyboard". It is working code using the technique I describe above.