帶有自己的 UIToolbar 的 UITextView 和 UIPickerView (UITextView and UIPickerView with its own UIToolbar)


問題描述

帶有自己的 UIToolbar 的 UITextView 和 UIPickerView (UITextView and UIPickerView with its own UIToolbar)

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? 


參考解法

方法 1:

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.

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

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.

方法 2:

I'm looking for the solution for this issue too.

I found this was the best solution, you can use this SCKit to add tool bar to dismiss the UIPickerView or the UIDatePicker as you want.

Following is github link: https://github.com/scelis/SCKit/tree/

Have fun!

(by luebkenBluephlameJiejing Zhang)

參考文件

  1. UITextView and UIPickerView with its own UIToolbar (CC BY-SA 3.0/4.0)

#cocoa-touch #iphone #uitextview #uitextfield #uipickerview






相關問題

防止 UITableView 在自定義子視圖處理觸摸時滾動 (Prevent UITableView from scrolling when custom subview is handling touches)

NSMutableArray removeObjectAtIndex 在第二次執行時崩潰 (NSMutableArray removeObjectAtIndex crashes on second execution)

Apakah NSURLConnections termasuk dalam model atau pengontrol saya? (Do NSURLConnections belong in my model or controller?)

Lợi ích của việc sử dụng NSString tĩnh cho CellIdentifier là gì? (Whats the advantage of using a static NSString for CellIdentifier?)

CGContextRef 中的坐標係是什麼樣的? (How does the coordinate system in an CGContextRef look like?)

無法在不崩潰的情況下設置 ABPeoplePickerNavigationController 的 addressBook 屬性 (Can't set the addressBook property of ABPeoplePickerNavigationController without crashing)

tableViewHeader 拒絕多個子視圖 (tableViewHeader rejecting multiple sub-views)

界面生成器添加了一個標籤欄按鈕,但未顯示 (Interface builder added one tab bar button, but not showing up)

iVar getter / 方法同名? (iVar getter / method with same name?)

如何更改主視圖是基於導航的應用程序! (how to change main view is navigation based app!)

捕捉返回按鈕導航事件 (Catching back button navigation event)

如何將對象轉發到單獨的子視圖? (How can i forward objects to separate subviews?)







留言討論