tags:

views:

94

answers:

2

I have a UITextView sitting on top of a UIView, and if I tap on it to open it for editing, then the keyboard is blocking the bottom of the view and I can not see it even though I can write in this area. Can I tell the UITextView to have a different scroll area or what is the solution?

+1  A: 

Apple has some code samples that deal with this exact situation.

Robot K
I have implemented the example from the link, and it works but the scroll area for my UITextView becomes quite a lot to small (like 50 pixel). Any idea why?
Neigaard
Check the resizing masks in Interface Builder. I'm not sure what the right settings are, but they control how the text view responds to size changes of its parent.
Robot K
When you say resizing mask, then what do you mean?
Neigaard
It's also known as "springs and struts". If you select your view open up the size inspector in Interface Builder (command-3), it's the section labeled "Autosizing".
Robot K
Hm I am really getting a headache here. I can get it to work, as long as I do not rotate the iPhone, then it goes crazy. If I rotate the iPhone, the text gets totally out of sight and is unreachable. Any ideas here? Funny I would have thought that this would be handled by the SDK and easy for me :)
Neigaard
Ok I almost got it working now. I store the keyboard size and orientation when I show the keyboard, and use that to reset the UITextView on change of orientation. I still have one problem though. My problem with the UITextView getting to small can be fixed in portrait mode by disabling the UIViewAutoResizingFlexibleHeight but then it will be all wrong when it is rotated to landscape. Any ideas for this one?
Neigaard
None other than I've found dealing with resizing masks requires a lot of experimentation before you fully understand how the different options interact with view frame changes. If you have your layout in Interface Builder, you can use the little "rotate view" arrow in the upper right corner to see how your view will react to orientation changes. It helps to see exactly what effect changing the "springs and struts" will have.
Robot K
A: 

I finally got it working. Here is my solution, can you guys spot any errors in my design?

@synthesize textView = _textView;
@synthesize callbackViewController = _callbackViewController;


-(void)keyboardWasShown:(NSNotification*)aNotification {
    if(keyboardShown) {
        return;
    }

    NSDictionary *info = [aNotification userInfo];

    // Get the size of the keyboard.
    NSValue *aValue = [info objectForKey:UIKeyboardFrameBeginUserInfoKey];
    keyboardSize = [aValue CGRectValue].size;

    // Resize the scroll view (which is the root view of the window)
    CGRect viewFrame = [self.textView frame];

    orientationAtShown = orientation;

    if(orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) {
        viewFrame.size.height -= keyboardSize.height;
    } else {
        viewFrame.size.height -= keyboardSize.width;
    }

    self.textView.frame = viewFrame;

    // Scroll the active text field into view.
    //CGRect textFieldRect = [activeField frame];
    [self.textView scrollRectToVisible:viewFrame animated:YES];

    keyboardShown = YES;
}

-(void)keyboardWasHidden:(NSNotification*)aNotification {
    if(!keyboardShown) {
        return;
    }

    // Reset the height of the scroll view to its original value
    CGRect viewFrame = [self.textView frame];
    if(orientationAtShown == UIInterfaceOrientationPortrait || orientationAtShown == UIInterfaceOrientationPortraitUpsideDown) {
        viewFrame.size.height += keyboardSize.height;
    } else {
        viewFrame.size.height += keyboardSize.width;
    }

    self.textView.frame = viewFrame;

    keyboardShown = NO;
}

-(void)registerForKeyboardNotifications {
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWasShown:)
                                                 name:UIKeyboardDidShowNotification object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWasHidden:)
                                                 name:UIKeyboardDidHideNotification object:nil];
}

-(void)viewWillAppear:(BOOL)animated {
    keyboardShown = NO;
    [self registerForKeyboardNotifications];
}

-(void)viewWillDisappear:(BOOL)animated {
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
}

// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    if(keyboardShown) {
        [self keyboardWasHidden:nil];
    }

    orientation = interfaceOrientation;

    CGRect viewFrame = [self.textView frame];
    if(orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) {
        if(viewFrame.size.width > viewFrame.size.height) {
            CGRect viewFrameFixed = CGRectMake(viewFrame.origin.x, viewFrame.origin.y, viewFrame.size.height, viewFrame.size.width);
            self.textView.frame = viewFrameFixed;
        }
    } else {
        if(viewFrame.size.width < viewFrame.size.height) {
            CGRect viewFrameFixed = CGRectMake(viewFrame.origin.x, viewFrame.origin.y, viewFrame.size.height, viewFrame.size.width);
            self.textView.frame = viewFrameFixed;
        }
    }


    // Return YES for supported orientations
    return YES;
}
Neigaard