Căn chỉnh theo chương trình thanh công cụ trên đầu bàn phím iPhone


94

Trong một số trường hợp, tôi muốn thêm một thanh công cụ vào đầu bàn phím iPhone (chẳng hạn như trong iPhone Safari khi bạn đang điều hướng các thành phần biểu mẫu).

Hiện tại, tôi đang chỉ định hình chữ nhật của thanh công cụ với các hằng số nhưng vì các phần tử khác của giao diện nằm trong dòng chảy - thanh công cụ và thanh điều hướng ở đầu màn hình - mỗi khi chúng tôi thực hiện một thay đổi nhỏ về giao diện, thanh công cụ sẽ bị lệch.

Có cách nào để lập trình xác định vị trí của bàn phím so với chế độ xem hiện tại không?

Câu trả lời:


142

Kể từ iOS 3.2, có một cách mới để đạt được hiệu ứng này:

UITextFieldsUITextViewscó một thuộc inputAccessoryViewtính, mà bạn có thể đặt thành bất kỳ chế độ xem nào, được tự động hiển thị ở trên và hoạt ảnh bằng bàn phím.

Lưu ý rằng chế độ xem bạn sử dụng không được nằm trong hệ thống phân cấp chế độ xem ở nơi khác, cũng như bạn không nên thêm nó vào một số chế độ xem siêu cấp, điều này được thực hiện cho bạn.


để tôi thử . Mặc dù nó có vẻ là cách tốt nhất.
harshalb

Chà. Thật là một phát hiện! Cảm ơn (Tôi đã làm nó một cách khó khăn và nó rất lộn xộn)
levous

1
Tôi có một thanh UIToolbar với UITextField bên trong một trong các mục nút thanh của nó nhưng mặc dù tôi đã đặt textFields inputAccessoryView thành thanh công cụ đó trong lần nhấn đầu tiên, thanh công cụ đi lên nhưng không có bàn phím nào xuất hiện. Trong lần nhấn thứ hai, bàn phím xuất hiện với thanh công cụ, bạn có biết gì về nó không?
Ugur Kumru,

Nhưng làm cách nào để thêm thanh công cụ trên UIWebView? :(
Dmitry

Tôi đã thực hiện bằng cách thay thế các nút trên thanh công cụ UIWebView tiêu chuẩn (mã giống như để loại bỏ nó).
Dmitry

72

Nên về cơ bản:

Trong phương thức init:

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

Và sau đó có các phương pháp được đề cập ở trên để điều chỉnh vị trí của thanh:

-(void) keyboardWillShow:(NSNotification *) note
{
    CGRect r  = bar.frame, t;
    [[note.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue: &t];
    r.origin.y -=  t.size.height;
    bar.frame = r;
}

Có thể làm cho nó đẹp bằng cách tạo hoạt ảnh cho sự thay đổi vị trí bằng cách quấn nó vào

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];
//...
    [UIView commitAnimations];

Tôi đã xem xét những thứ cũ của tôi sáng nay và nhận thấy rằng đây là một câu trả lời tốt hơn và toàn diện nhất. Cảm ơn!
Rob Drimmie

Câu trả lời này vẫn còn khá phù hợp hơn một năm sau đó. Nó đã giúp tôi vượt qua cái bướu khi phát triển một cái gì đó liên quan đến điều này.
james_womack

2
Chỉ là một lời cảnh báo cho những người gặp phải câu hỏi này ngay bây giờ: UIKeyboardBoundsUserInfoKey hiện không được chấp nhận trong iPhone OS 3.2. Có những cái khác, tương tự như UIKeyboardFrameBeginUserInfoKeycung cấp cùng một thông tin.
Stephen Darlington

9
Thậm chí còn có một cách mới tốt hơn để làm điều đó trong iOS3.2 là thuộc tính inputAccessoryView trên UITextField và UITextView.
tonklon

6
Câu trả lời này đã giúp ích rất nhiều nhưng hơi cũ. Bạn nên sử dụng UIKeyboardFrameEndUserInfoKeyđể lấy khung hình cuối cùng (trong các dải màn hình) của bàn phím. Bạn cũng có thể sử dụng UIKeyboardAnimationDurationUserInfoKeyUIKeyboardAnimationCurveUserInfoKeyđể lấy phần còn lại của các tham số bạn cần để khớp chính xác với hoạt động của bàn phím.
Dave Peck

60

Điều này dựa trên câu trả lời hiện có từ tonklon - Tôi chỉ thêm một đoạn mã hiển thị thanh công cụ màu đen bán trong suốt ở phía trên bàn phím, cùng với nút "hoàn thành" ở bên phải:

UIToolbar *toolbar = [[[UIToolbar alloc] init] autorelease];
[toolbar setBarStyle:UIBarStyleBlackTranslucent];
[toolbar sizeToFit];

UIBarButtonItem *flexButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *doneButton =[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(resignKeyboard)];

NSArray *itemsArray = [NSArray arrayWithObjects:flexButton, doneButton, nil];

[flexButton release];
[doneButton release];
[toolbar setItems:itemsArray];

[aTextField setInputAccessoryView:toolbar];

-resignKeyboardtrông giống như:

-(void)resignKeyboard {
  [aTextField resignFirstResponder];
}

Hy vọng rằng sẽ giúp một ai đó.


2
Chỉ cần thêm một chút nhận xét về việc đưa phần tiếp theo vào vị trí trước đó. UISegmentedControl * segmentControl = [[UISegmentedControl CẤP] initWithItems: [NSArray arrayWithObjects: @ "Trước", @ "Tiếp theo", nil]]; [segmentControl setSegmentedControlStyle: UISegmentedControlStyleBar]; [segmentControl addTarget: self action: @selector (nextPrevious :) forControlEvents: UIControlEventValueChanged];
Trausti Thor

1
Một bổ sung cho nhận xét của @ TraustiThor: Bạn phải bao bọc điều khiển được phân đoạn trong UIBarButtonItem để thêm nó vào thanh công cụ.
Tim Büthe

Tuyệt vời - đây là tất cả mã tôi cần. Cảm ơn vì đã đăng bài :)
Kéo dài

Nhưng còn UIWebView thì sao? Làm thế nào để thêm một thanh công cụ vào nó?
Dmitry

24

Nếu bạn đăng ký thông báo bàn phím, tức là UIKeyboardWillShowNotification UIKeyboardWillHideNotification, v.v., thông báo bạn nhận được sẽ chứa các giới hạn của bàn phím trong userInfodict ( UIKeyboardBoundsUserInfoKey).

Xem UIWindowtài liệu tham khảo của lớp.


16

Trong phiên bản 3.0 trở lên, bạn có thể lấy thời lượng và đường cong hoạt ảnh từ từ userInfođiển của các thông báo.

ví dụ: để tạo hoạt ảnh cho kích thước của chế độ xem để nhường chỗ cho bàn phím, hãy đăng ký UIKeyboardWillShowNotificationvà thực hiện một số việc như sau:

- (void)keyboardWillShow:(NSNotification *)notification
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
    [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];

    CGRect frame = self.view.frame;
    frame.size.height -= [[[notification userInfo] objectForKey:UIKeyboardBoundsUserInfoKey] CGRectValue].size.height;
    self.view.frame = frame;

    [UIView commitAnimations];
}

Làm một hoạt ảnh tương tự cho UIKeyboardWillHideNotification.


Có vẻ như một cách tốt hơn để làm điều đó trên SDK 3.0, cảm ơn bạn đã đăng!
Hua-Ying

Cảm ơn vì mã. Điều này giúp ích rất nhiều. Nhưng khi tôi đặt UITextView của mình trở thành phản hồi đầu tiên trong viewDidLoad, UIToolBar không di chuyển với việc thay đổi kích thước của self.view. Bạn có bất kỳ ý tưởng tại sao?
RyanJM

1
@RyanJM: BecomeFirstResponder và resignFirstResponder có hành vi kỳ lạ khi chế độ xem ngoài màn hình. Thay vào đó, bạn nên gọi hàm beFirstResponder từ phương thức viewWillAppear của mình.
David Beck

0

Tạo phương thức này và gọi nó trên ViewWillLoad:

        - (void) keyboardToolbarSetup
{
    if(self.keyboardToolbar==nil)
        {
        self.keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)];

        UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:@"Cancel" style:UIBarButtonItemStylePlain target:self action:@selector(anyAction)];

        UIBarButtonItem *extraSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];

        UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(anyOtherAction)];


        NSArray *toolbarButtons = [[NSArray alloc]initWithObjects:cancelButton,extraSpace,doneButton, nil];

        [self.keyboardToolbar setItems:toolbarButtons];

        self.myTextView.inputAccessoryView=self.keyboardToolbar;
        }
}

-3

Không có cách nào (AFAIK) để lấy kích thước của chế độ xem bàn phím. Tuy nhiên, nó không đổi, ít nhất là trong mọi phiên bản iPhone cho đến nay.

Nếu bạn tính toán vị trí thanh công cụ như một độ lệch so với ĐÁY của chế độ xem và tính đến kích thước của chế độ xem, thì bạn sẽ không phải lo lắng liệu thanh điều hướng có hiện diện hay không.

Ví dụ

#define KEYBOARD_HEIGHT 240 // example - can't remember the exact size
#define TOOLBAR_HEIGHT 30

toolBarRect.origin.y = viewRect.size.height - KEYBOARD_HEIGHT - TOOLBAR_HEIGHT;

// move toolbar either directly or with an animation

Thay vì định nghĩa, bạn có thể dễ dàng tạo một keyboardHeighthàm trả về kích thước dựa trên việc bàn phím có được hiển thị hay không và di chuyển vị trí thanh công cụ này thành một chức năng riêng biệt giúp sắp xếp lại bố cục của bạn.

Ngoài ra, nó có thể phụ thuộc vào nơi bạn thực hiện việc định vị này vì có thể kích thước chế độ xem của bạn có thể thay đổi giữa việc được tải và hiển thị dựa trên thiết lập thanh điều hướng của bạn. Tôi tin rằng nơi tốt nhất để làm điều đó là viewWillAppear.


Điều này làm việc tuyệt vời, cảm ơn! Cho đến nay, tôi đã thực hiện phép tính này trong bộ chọn do UIKeyboardDidShowNotification kích hoạt. Tôi chỉ thử nghiệm ở một vài nơi, nhưng nó có vẻ là một nơi tốt.
Rob Drimmie

Kể từ phiên bản 5.0, kích thước bàn phím không còn tĩnh.
Alastair Stuart
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.