จัดแนวแถบเครื่องมือที่ด้านบนของแป้นพิมพ์ iPhone โดยใช้โปรแกรม


94

ในหลาย ๆ กรณีฉันต้องการเพิ่มแถบเครื่องมือที่ด้านบนของแป้นพิมพ์ iPhone (เช่นใน iPhone Safari เมื่อคุณนำทางองค์ประกอบของฟอร์มเป็นต้น)

ขณะนี้ฉันกำลังระบุสี่เหลี่ยมผืนผ้าของแถบเครื่องมือด้วยค่าคงที่ แต่เนื่องจากองค์ประกอบอื่น ๆ ของอินเทอร์เฟซอยู่ในฟลักซ์ - แถบเครื่องมือและแถบนำทางที่ด้านบนของหน้าจอ - ทุกครั้งที่เราทำการเปลี่ยนแปลงอินเทอร์เฟซเล็กน้อยแถบเครื่องมือจึงไม่อยู่ในแนวเดียวกัน

มีวิธีกำหนดตำแหน่งของแป้นพิมพ์โดยทางโปรแกรมให้สัมพันธ์กับมุมมองปัจจุบันหรือไม่?

คำตอบ:


141

สำหรับ iOS 3.2 มีวิธีใหม่ในการบรรลุผลนี้:

UITextFieldsและUITextViewsมีinputAccessoryViewพร็อพเพอร์ตี้ซึ่งคุณสามารถตั้งค่าเป็นมุมมองใดก็ได้ที่จะแสดงด้านบนและเคลื่อนไหวด้วยแป้นพิมพ์โดยอัตโนมัติ

โปรดทราบว่าข้อมูลพร็อพเพอร์ตี้ที่คุณใช้ไม่ควรอยู่ในลำดับชั้นของมุมมองที่อื่นหรือคุณไม่ควรเพิ่มลงในซูเปอร์วิวบางส่วนสิ่งนี้ทำเพื่อคุณ


ให้ฉันพยายาม . แม้ว่าจะดูเป็นวิธีที่ดีที่สุด
harshalb

ว้าว. หาอะไร! ขอบคุณ (ฉันทำมันยากและมันก็ยุ่ง)
levous

1
ฉันมี UIToolbar ที่มี UITextField อยู่ในรายการปุ่มแถบรายการหนึ่ง แต่แม้ว่าฉันจะตั้งค่า inputAccessoryView textFields เป็นแถบเครื่องมือนั้นในครั้งแรกที่กดแถบเครื่องมือจะขึ้น แต่ไม่มีแป้นพิมพ์ปรากฏขึ้น ในการกดครั้งที่สองแป้นพิมพ์ปรากฏขึ้นพร้อมกับแถบเครื่องมือมีความคิดเกี่ยวกับเรื่องนี้หรือไม่?
Ugur Kumru

แต่จะเพิ่มแถบเครื่องมือบน UIWebView ได้อย่างไร :(
Dmitry

ฉันทำได้โดยการเปลี่ยนปุ่มบนแถบเครื่องมือ UIWebView มาตรฐาน (รหัสเดียวกับการลบออก)
Dmitry

72

โดยพื้นฐานแล้ว:

ในวิธีการเริ่มต้น:

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

จากนั้นมีวิธีการที่อ้างถึงด้านบนเพื่อปรับตำแหน่งของแถบ:

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

สามารถทำให้สวยได้ด้วยการทำให้เคลื่อนไหวเปลี่ยนตำแหน่งโดยการใส่เข้าไป

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

เมื่อเช้านี้กำลังพูดคุยกับของเก่าของฉันและสังเกตว่านี่เป็นคำตอบที่ดีและครอบคลุมที่สุด ขอบคุณ!
Rob Drimmie

คำตอบนี้ยังคงมีความเกี่ยวข้องในอีกหนึ่งปีต่อมา มันช่วยให้ฉันข้ามโคกเมื่อพัฒนาบางอย่างที่เกี่ยวข้องกับเรื่องนี้
james_womack

2
คำเตือนสำหรับผู้ที่พบคำถามนี้ตอนนี้: ตอนนี้ UIKeyboardBoundsUserInfoKey เลิกใช้งานแล้วใน iPhone OS 3.2 มีข้อมูลอื่นที่คล้ายคลึงกันเช่นUIKeyboardFrameBeginUserInfoKeyที่ให้ข้อมูลเหมือนกัน
Stephen Darlington

9
ยังมีวิธีใหม่ที่ดีกว่าในการทำเช่นนั้นใน iOS3.2 คุณสมบัติ inputAccessoryView บน UITextField และ UITextView
tonklon

6
คำตอบนี้ช่วยได้มาก แต่ค่อนข้างล้าสมัย คุณควรใช้UIKeyboardFrameEndUserInfoKeyเพื่อรับเฟรมสุดท้าย (ในผู้ประสานงานหน้าจอ) ของแป้นพิมพ์ คุณยังสามารถใช้UIKeyboardAnimationDurationUserInfoKeyและUIKeyboardAnimationCurveUserInfoKeyรับพารามิเตอร์ที่เหลือที่คุณต้องการเพื่อให้ตรงกับลักษณะการทำงานของแป้นพิมพ์
Dave Peck

60

นี่เป็นไปตามคำตอบที่มีอยู่จาก tonklon - ฉันแค่เพิ่มข้อมูลโค้ดที่แสดงแถบเครื่องมือสีดำกึ่งโปร่งใสที่ด้านบนของแป้นพิมพ์พร้อมกับปุ่ม "เสร็จสิ้น" ทางด้านขวา:

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];

และ-resignKeyboardดูเหมือนว่า:

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

หวังว่าจะช่วยใครบางคน


2
เพียงแค่เพิ่มความคิดเห็นเล็กน้อยในการรับหน้าที่ต่อไป UISegmentedControl * segmentControl = [[UISegmentedControl จัดสรร] initWithItems: [NSArray arrayWithObjects: @ "Previous", @ "Next", nil]]; [segmentControl setSegmentedControlStyle: UISegmentedControlStyleBar]; [segmentControl addTarget: self action: @selector (nextPrevious :) forControlEvents: UIControlEventValueChanged];
Trausti Thor

1
ความคิดเห็นเพิ่มเติมของ @ TraustiThor: คุณต้องรวมตัวควบคุมที่แบ่งส่วนไว้ใน UIBarButtonItem เพื่อเพิ่มลงในแถบเครื่องมือ
Tim Büthe

ยอดเยี่ยม - นี่คือรหัสทั้งหมดที่ฉันต้องการ ขอบคุณสำหรับการโพสต์ :)
ยืด

แล้ว UIWebView ล่ะ? จะเพิ่มแถบเครื่องมือเข้าไปได้อย่างไร?
Dmitry

24

หากคุณลงทะเบียนสำหรับการแจ้งเตือนทางแป้นพิมพ์เช่นUIKeyboardWillShowNotification UIKeyboardWillHideNotificationฯลฯ การแจ้งเตือนที่คุณได้รับจะมีขอบเขตของแป้นพิมพ์อยู่ในuserInfodict ( UIKeyboardBoundsUserInfoKey)

ดูการUIWindowอ้างอิงชั้นเรียน


16

ใน 3.0 ขึ้นไปคุณจะได้รับระยะเวลาและเส้นโค้งของภาพเคลื่อนไหวจากuserInfoพจนานุกรมของการแจ้งเตือน

ตัวอย่างเช่นหากต้องการทำให้ขนาดของมุมมองเคลื่อนไหวเพื่อให้มีที่ว่างสำหรับแป้นพิมพ์ให้ลงทะเบียนUIKeyboardWillShowNotificationและทำสิ่งต่อไปนี้:

- (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];
}

ทำแอนิเมชั่นที่คล้ายกันสำหรับUIKeyboardWillHideNotification.


ดูเหมือนจะเป็นวิธีที่ดีกว่าใน 3.0 SDK ขอบคุณสำหรับการโพสต์!
Hua-Ying

ขอบคุณสำหรับรหัส สิ่งนี้ช่วยได้มาก แต่เมื่อฉันตั้งค่า UITextView ให้เป็นผู้ตอบกลับคนแรกใน viewDidLoad UIToolBar จะไม่ขยับตามการปรับขนาดของ self.view คุณมีความคิดว่าทำไม?
RyanJM

1
@RyanJM: becomeFirstResponder และลาออก FirstResponder มีพฤติกรรมแปลก ๆ เมื่อมุมมองอยู่นอกหน้าจอ คุณควรเรียก becomeFirstResponder จากเมธอด viewWillAppear แทน
David Beck

0

สร้างวิธีนี้และเรียกมันบน 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

ไม่มีทาง (AFAIK) ในการรับขนาดของมุมมองแป้นพิมพ์ อย่างไรก็ตามมันคงที่อย่างน้อยก็ใน iPhone ทุกรุ่นจนถึงตอนนี้

หากคุณคำนวณตำแหน่งแถบเครื่องมือเป็นค่าชดเชยจาก BOTTOM ของมุมมองของคุณและคำนึงถึงขนาดของมุมมองของคุณคุณก็ไม่ต้องกังวลว่าจะมีแถบนำทางอยู่หรือไม่

เช่น

#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

แทนที่จะกำหนดคุณสามารถสร้างkeyboardHeightฟังก์ชันที่ส่งคืนขนาดได้อย่างง่ายดายโดยขึ้นอยู่กับว่าแป้นพิมพ์กำลังแสดงอยู่หรือไม่และย้ายตำแหน่งแถบเครื่องมือนี้ไปไว้ในฟังก์ชันแยกต่างหากที่จัดระเบียบเค้าโครงของคุณใหม่

นอกจากนี้ยังสามารถขึ้นอยู่กับตำแหน่งที่คุณทำตำแหน่งนี้เนื่องจากเป็นไปได้ว่าขนาดของมุมมองของคุณอาจเปลี่ยนแปลงระหว่างการโหลดและการแสดงตามการตั้งค่า navbar ฉันเชื่อว่าสถานที่ที่ดีที่สุดที่จะทำได้คือใน viewWillAppear


มันใช้งานได้ดีขอบคุณ! จนถึงตอนนี้ฉันได้ทำการคำนวณนี้ในตัวเลือกที่เรียกโดย UIKeyboardDidShowNotification ฉันได้ทดสอบเพียงไม่กี่แห่ง แต่ดูเหมือนว่าจะเป็นจุดที่ดี
Rob Drimmie

เมื่อถึง 5.0 ขนาดแป้นพิมพ์จะไม่คงที่อีกต่อไป
Alastair Stuart
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.