Sunday, July 11, 2010

Wall Paper Editor: editing the text.

I want to edit the text in place as much as possible, but it's quite possible, even likely, that the onscreen keyboard will interfere.  I want to then translate the view that I'm using so that the text field is fully visible, while also maintaining the background.   The approach I choose for this is to move the view so that the
bottom line of the text field is just over the keyboard (If, and only if, the keyboard obscures the text field).  This can result in the text field scrolling over the top if this is a large text field, later I might add an scaling factor, or just allow scrolling in the text field.

For now I modified my KeyboardMover class so that it has two modes:
1) the previous behavior where it changes the size of the view
2) The new behavior so that it will calculate the bounds of the keyboard, and translate the superview of the given view, if there is a conflict:


// The keyboard helper is an object that when given a view will
// resize that view when the keyboard appears or disappears.   
// The dealloc of this will unregister the notification.
@interface KeyboardHelper : NSObject {

@private
UIView *view;
CGRect originalSize;
bool useCenter;


}
@property (nonatomic,retain) UIView *view;
@property (nonatomic) CGRect originalSize;
@property (nonatomic) bool useCenter;
- (id) initWithView:(UIView*) viewToUse;
@end

The new keyboard appearing has two modes based on the boolean.  I will probably clean this up later on, but it's a working first draft.  It took a bit to get the view behavior correct.



- (void)keyboardAppearing:(NSNotification *)notification {
NSDictionary *keys=[notification  userInfo];
CGRect myFrame=[self.view frame];
originalSize=myFrame;

NSValue *value=[keys objectForKey:UIKeyboardBoundsUserInfoKey];
CGRect bounds;
[value getValue:&bounds];
if (!useCenter)
{
view.frame=CGRectMake(myFrame.origin.x,myFrame.origin.y,myFrame.size.width,
  myFrame.size.height-bounds.size.height);
}else {
CGRect myFrame=[self.view.superview frame];
originalSize=myFrame;


NSValue *centervalue=[keys objectForKey:UIKeyboardCenterEndUserInfoKey];
CGPoint keyCenter;
[centervalue getValue:&keyCenter];
NSLog(@"eky center x %f, y %f",keyCenter.x,keyCenter.y);
NSLog(@"Old boudns (%f,%f) -- (%f,%f)",bounds.origin.x,bounds.origin.y,bounds.size.width,bounds.size.height);
bounds.origin.y = view.window.frame.size.height-bounds.size.height;
NSLog(@"New boudns (%f,%f) -- (%f,%f)",bounds.origin.x,
  bounds.origin.y,bounds.size.width,bounds.size.height);
CGRect viewInWindowCoords= [view convertRect:view.bounds toView:view.window];
NSLog(@"View in windowcoords (%f,%f) -- (%f,%f)",viewInWindowCoords.origin.x,
  viewInWindowCoords.origin.y,viewInWindowCoords.size.width,viewInWindowCoords.size.height);

double bottomY=viewInWindowCoords.origin.y+viewInWindowCoords.size.height;
if (bounds.origin.y
{
[UIView beginAnimations:nil context:view.superview];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationDuration:0.15];

CGPoint newCenter=view.superview.center;
newCenter.y -= (bottomY-bounds.origin.y);
view.superview.center=newCenter;
[UIView commitAnimations];
}    
}
}

And on the keyboard disappearing, just reset the view:



if (!useCenter)
view.frame=originalSize;
else {
[UIView beginAnimations:nil context:view.superview];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationDuration:0.15];
view.superview.frame=originalSize;
[UIView commitAnimations];
}
I enclosed the action in a simple animation, it makes it look much more natural.

No comments:

Post a Comment