views:

4237

answers:

1

I like to replicate the form behavior of Safari on the iPhone in my own app. If you enter data in an web form you get a separate UIToolbar (previous, next, done) just above the UIKeyboardView. Same for choosing an option: you get the same UIToolbar just above an UIPickerView.

I am looking for demos / sourcode / ideas how to implement this. Would I create my own subview with that toolbar and textview / pickerview? Is there a more elegant way? Especially something that leverages becomeFirstResponder of UITextfield?

+6  A: 

So i created a UIViewCOntroller subclass to manage this.

on that i wrote this function to add.

-(void) addToViewWithAnimation:(UIView *) theView
{
    UIView* myview = self.view;
    CGRect frame = myview.frame;
    frame.origin.y = 420;
    myview.frame = frame;

    UIView* bgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 420)];
    bgView.backgroundColor = [UIColor blackColor];
    bgView.alpha = 0.6;
    backgroundView = bgView;
    [theView addSubview: bgView];  // this adds in the dark background

    [theView addSubview:self.view]; // this adds in the pickerView with toolbar.
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.5]; 
    frame = myview.frame;
    frame.origin.y = 420 - frame.size.height;
    myview.frame = frame;

    [UIView commitAnimations];
 }

I then created the view in IB, here is what my class Header looked like at the end of that. (there is also a UItoolbar on the view i just do not have a reference to it in my Controller)

@interface PropertyPickerController : UIViewController {
    IBOutlet UIPickerView* Picker;
    IBOutlet UIButton* DoneButton;
    IBOutlet UIButton* CancelButton;
    UIView* backgroundView;
    NSArray* SimpleObjects;
    id PickerObjectDelegate;
    SEL PickerObjectSelector;
}

To then hide the view i use.

-(void) removeFromSuperviewWithAnimation
{

    UIView* myview = self.view;
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(AnimationDidStop:)];
    [UIView setAnimationDuration:0.5]; 
    // set fram below window. 
    CGRect frame = myview.frame;
    frame.origin.y = 420;
    myview.frame = frame;
    backgroundView.alpha = 0;  //fades shade to nothing
    [UIView commitAnimations];
}

-(void) AnimationDidStop:(id) object
{
    [self.view removeFromSuperview];  //removes view after animations.
    [backgroundView removeFromSuperview];
}

And last but not least all the delegate functions for the picker.

    - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
    {
        FBSimpleObject* object = (FBSimpleObject*)[SimpleObjects objectAtIndex:row];
        return object.Name;
    }

    - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
    {   
    }
    - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
    { return 1;}

    - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
    {
        return [SimpleObjects count];
    }

    - (IBAction)CancelButtonClick
    {
         [self removeFromSuperviewWithAnimation];
    }
    - (IBAction)DoneButtonClick
    {   
//This performs a selector when the done button is clicked, makes the controller more versatile.
if(PickerObjectDelegate && PickerObjectSelector)
     {
      NSMethodSignature* signature = [PickerObjectDelegate methodSignatureForSelector:PickerObjectSelector]; 
      NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
      [invocation setTarget:PickerObjectDelegate];
      [invocation setSelector:PickerObjectSelector];
      [invocation setArgument:&object atIndex:2];
      [invocation retainArguments];
      [invocation invoke];
     }
    }

This is how you do the ToolBar. Basically i use the same concept with a ViewController subclass, and i dont use the standard push view or modal display options. (the example here actually places a Textbox and a toolbar on top of the keyboard.

@interface BugEditCommentController : UIViewController { UITextView* Comment; UIToolbar* Toolbar; } -(void) addToViewWithAnimation:(UIView*) theView;

To activate this view usually you would call [object becomeFirstResponder]; so if you add this to your view Controller constructor, all you need to do is call [object becomeFirstResponder];

 NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
     [nc addObserver:self selector:@selector(keyboardWillShow:) name: UIKeyboardWillShowNotification object:nil];
     [nc addObserver:self selector:@selector(keyboardWillHide:) name: UIKeyboardWillHideNotification object:nil];

abd if you implement this method on your controller (defined in the above code)

-(void) keyboardWillShow:(NSNotification *) note
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];

    CGRect toolbarFrame  = Toolbar.frame;
    CGRect keyboardFrame;
    CGPoint keyboardCenter;
    [[note.userInfo valueForKey:UIKeyboardCenterEndUserInfoKey] getValue:&keyboardCenter];
    [[note.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue: &keyboardFrame];

    //CGRect toolbarRect = Toolbar.center;
    toolbarFrame.origin.y= keyboardCenter.y - ((keyboardFrame.size.height/2) + (toolbarFrame.size.height));
    Toolbar.frame = toolbarFrame;
    [UIView commitAnimations];

}

-(void) keyboardWillHide:(id) object
{

//you could call [self removeFromSuperviewHere];
}

-(void) removeFromsuperViewWithAnimation
{
    [Comment resignFirstResponder];
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(AnimationDidStop:)];

    CGRect frame = Toolbar.frame;
    frame.origin.y = 480;
    Toolbar.frame = frame;

    [self.view viewWithTag:1].alpha = 0;  //fade transparent black background to clear.
    [UIView commitAnimations];

}
-(void)AnimationDidStop:(id) object
{
    [self.view removeFromSuperview];
}

hope the additional info helps.

Bluephlame
Thanks. But the UITextView is missing. I'm not sure how to integrate that with the 'firstResponder' mechanism.
Steilpass
Sorry yes, that example is just the UIPickerView.I'll post the code for the UITextView when i get a chance.
Bluephlame