2009-07-12 57 views
6

Tôi đã yêu cầu a question hoặc hai trong vài ngày qua làm việc trên một ứng dụng giữ một thanh công cụ tùy chỉnh được căn chỉnh ở đầu bàn phím iPhone. Tôi đang sử dụng phương pháp được mô tả bởi Josh trong this question; về cơ bản, tôi có bộ điều khiển xem lắng nghe cho UIKeyboardWillShowNotification và thêm thanh công cụ khi cần thiết.iPhone: di chuyển ô xem bảng để hiển thị trên thanh công cụ tùy chỉnh trên bàn phím tùy chỉnh?

Chính trình điều khiển chế độ xem sẽ quản lý chế độ xem bảng có các ô chứa UITextField. Bàn phím và thanh công cụ đang được trình bày đang chỉnh sửa các trường văn bản này. Vấn đề duy nhất tôi vẫn gặp phải là điều này: khi bàn phím và thanh công cụ được hiển thị cho một ô nhiều hơn nửa chừng, nó cuộn để hiển thị phía trên bàn phím, nhưng không nằm trên thanh công cụ.

Các ô và trường văn bản vẫn có thể chỉnh sửa được, nhưng khoảng một nửa ô bị ẩn dưới thanh công cụ. Nếu tôi biến mất thanh công cụ (không thêm nó trong phần trả lời thông báo), toàn bộ ô sẽ hiển thị, nhưng rõ ràng là tôi mất chức năng mà thanh công cụ cung cấp.

Có cách nào để thay đổi vị trí mà trường văn bản được cuộn đến không? Tôi đã thử chơi xung quanh với phương pháp UITableView scrollToRowAtIndexPath:atScrollPosition:animated:, nhưng nó có xu hướng cho kết quả lạ khi chuyển đổi qua một số ô.

Phương pháp tốt nhất để cuộn ô xem bảng đến vị trí hiển thị phía trên thanh công cụ bàn phím tùy chỉnh là gì?

Trả lời

17

Tôi thực hiện chính xác những gì bạn mô tả trong ứng dụng của mình. Đây là mã tôi sử dụng, đúng nguyên văn. Nó hoạt hình rất độc đáo, và dường như làm việc tuyệt vời.

Hai kỹ khuyến cáo:

  1. tôi vượt qua trong parentView như một phần của một khởi tùy chỉnh.
  2. Tôi không viết mã này, tôi không nhận tín dụng cho nó. Tôi lấy nó từ blog thật sự tuyệt vời của Matt Gallagher Cocoa With Love.

static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.3; 
static const CGFloat MINIMUM_SCROLL_FRACTION = 0.2; 
static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8; 
// adjust this following value to account for the height of your toolbar, too 
static const CGFloat PORTRAIT_KEYBOARD_HEIGHT = 216; 


- (void)textFieldDidEndEditing:(UITextField *)textField 
{ 
    CGRect viewFrame = self.parentView.frame; 
    viewFrame.origin.y += animatedDistance; 

    [UIView beginAnimations:nil context:NULL]; 
    [UIView setAnimationBeginsFromCurrentState:YES]; 
    [UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION]; 

    [self.parentView setFrame:viewFrame]; 

    [UIView commitAnimations]; 
} 

- (void) textFieldDidBeginEditing:(UITextField*) textField { 
    CGRect textFieldRect = [self.parentView.window convertRect:textField.bounds fromView:textField]; 
    CGRect viewRect = [self.parentView.window convertRect:self.parentView.bounds fromView:self.parentView]; 
    CGFloat midline = textFieldRect.origin.y + 0.5 * textFieldRect.size.height; 
    CGFloat numerator = midline - viewRect.origin.y - MINIMUM_SCROLL_FRACTION * viewRect.size.height; 
    CGFloat denominator = (MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION) * viewRect.size.height; 
    CGFloat heightFraction = numerator/denominator; 

    if (heightFraction < 0.0) { 
    heightFraction = 0.0; 
    }else if (heightFraction > 1.0) { 
    heightFraction = 1.0; 
    } 

    animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction); 

    CGRect viewFrame = self.parentView.frame; 
    viewFrame.origin.y -= animatedDistance; 

    [UIView beginAnimations:nil context:NULL]; 
    [UIView setAnimationBeginsFromCurrentState:YES]; 
    [UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION]; 

    [self.parentView setFrame:viewFrame]; 

    [UIView commitAnimations]; 
} 
+0

Tôi giả sử bạn đang đề cập đến bài viết trên blog này tại http://cocoawithlove.com/2008/10/sliding-uitextfields-around-to-avoid.html - Tôi đã nhìn thấy nó quá, và nó không thực sự đối phó với UITableViews, chỉ xem tĩnh với UITextFields. Vấn đề với phương pháp này là animationDistance có thể thay đổi khi người dùng cuộn qua chế độ xem bảng. – Tim

+0

Tôi đang sử dụng nó bên trong một UITableView mà không có vấn đề gì. – mmc

+0

Tôi đã thực hiện điều này, nhưng khi kiểm tra chặt chẽ hơn về mã và kết quả tất cả những gì nó làm là di chuyển nguồn gốc của chế độ xem bảng lên khỏi màn hình. Nó có hiệu ứng được mô tả trong bài đăng trên blog, nhưng làm cho người dùng không thể nhìn thấy một vài ô xem bảng hàng đầu khi chỉnh sửa ô gần cuối bảng. – Tim

0

Có thể bạn có thể đổi kích thước UITableView làm chiều cao giữa thanh điều hướng và thanh công cụ phía trên bàn phím, sau đó cuộn hàng vào chế độ xem?

+0

Tôi đưa cho rằng một thử - xem bảng dường như thay đổi kích thước OK, sau đó cuộn cảm khá nặng nếu bạn cố gắng để di chuyển một tế bào đó là trong khu vực đó bị thay đổi kích cỡ đi lại trên màn hình. – Tim

0

Vì tất cả UITableView s cũng UIScrollView s, bạn có thể gọi tất cả các phương pháp cuộn tiêu chuẩn trên chúng.

Something như thế này sẽ làm:

- (void)scrollTableView:(UITableView *)tableView toIndexPath:(NSIndexPath *)indexPath withBottomPadding:(CGFloat)bottomPadding 
{ 
    CGRect rectForRow = [tableView rectForRowAtIndexPath:indexPath]; 
    CGRect bounds = [tableView bounds]; 
    CGPoint contentOffset = [tableView contentSize]; 
    if (rectForRow.origin.y + rectForRow.size.height > contentOffset.y + bounds.size.height - bottomPadding) 
     [tableView setContentOffset:rectForRow.origin.y + rectForRow.size.height - bounds.size.height - bottomPadding animated:YES]; 
    else 
     [tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionNone animated:YES]; 
} 

Lưu ý: Tôi không ở một máy Mac với Xcode vào lúc này.Tôi sẽ kiểm tra mã này khi tôi

6

Giả sử rằng bạn biết NSIndexPath mà bạn sẽ hiển thị phía trên bàn phím, bạn có thể sử dụng nhanh chóng và sạch sẽ phương pháp sau đây:

- (void)textFieldDidBeginEditing:(UITextField *)textField { 
    UITableViewCell *aCell = [myTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:6 inSection:0]]; 
    CGSize cellSize = aCell.frame.size; 
    [myTableView setContentOffset:CGPointMake(0, cellSize.height*6) animated:YES]; 
}  

- (void)textFieldDidEndEditing:(UITextField *)textField { 
    [myTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] 
         atScrollPosition:UITableViewScrollPositionTop 
           animated:YES]; 
} 

Kể từ khi UITableView được kế thừa từ UIScrollView bạn có thể điều chỉnh thuộc tính contentOffset để phản ánh khả năng hiển thị hàng mà bạn quan tâm.

Trong phương thức DidEndEditing, bạn phải khôi phục vị trí cuộn ban đầu. Điều này đạt được với một tiêu chuẩn scrollToRowAtIndexPath: atScrollPosition: hoạt cảnh cuộc gọi.

Các vấn đề liên quan