Bàn phím iPad sẽ không loại bỏ nếu kiểu trình bày ViewControll theo phương thức là UIModalPftimeationFormSheet


214

Ghi chú:

Xem câu trả lời được chấp nhận (không phải là bình chọn hàng đầu) cho giải pháp kể từ iOS 4.3.

Câu hỏi này là về một hành vi được phát hiện trong bàn phím iPad, nơi nó từ chối bị loại bỏ nếu được hiển thị trong hộp thoại phương thức với bộ điều khiển điều hướng.

Về cơ bản, nếu tôi trình bày bộ điều khiển điều hướng với dòng sau như sau:

navigationController.modalPresentationStyle = UIModalPresentationFormSheet;

Bàn phím từ chối bị loại bỏ. Nếu tôi nhận xét ra dòng này, bàn phím sẽ biến mất.

...

Tôi đã có hai textField, tên người dùng và mật khẩu; Tên người dùng có nút Tiếp theo và mật khẩu có nút Xong. Bàn phím sẽ không biến mất nếu tôi trình bày điều này trong bộ điều khiển điều hướng phương thức.

LÀM

broken *b = [[broken alloc] initWithNibName:@"broken" bundle:nil];
[self.view addSubview:b.view];

KHÔNG HOẠT ĐỘNG

broken *b = [[broken alloc] initWithNibName:@"broken" bundle:nil];
UINavigationController *navigationController = 
[[UINavigationController alloc]
 initWithRootViewController:b];
navigationController.modalPresentationStyle = UIModalPresentationFormSheet;
navigationController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:navigationController animated:YES];
[navigationController release];
[b release];

Nếu tôi loại bỏ phần bộ điều khiển điều hướng và tự hiển thị 'b' dưới dạng bộ điều khiển chế độ xem phương thức, nó sẽ hoạt động. Là bộ điều khiển điều hướng vấn đề?

LÀM

broken *b = [[broken alloc] initWithNibName:@"broken" bundle:nil];
b.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:b animated:YES];
[b release];

LÀM

broken *b = [[broken alloc] initWithNibName:@"broken" bundle:nil];
UINavigationController *navigationController = 
    [[UINavigationController alloc]
         initWithRootViewController:b];
[self presentModalViewController:navigationController animated:YES];
[navigationController release];
[b release];

Câu hỏi SO sau đây dường như có cùng một vấn đề, nhưng không có câu trả lời: stackoverflow.com/questions/3019709/
mẹo

+1 Cảm ơn bạn đã giải thích tuyệt vời của bạn. Nhưng tôi phải đặt phương pháp đó ở đâu? Có vẻ như nó không hoạt động khi tôi tạo mã để trình bày bộ điều khiển mô hình ...
Lorenzo B

1
Nó phải ở trong lớp trình điều khiển khung nhìn chính nó.
Kalle

Cảm ơn. Tôi hiểu rồi. Tôi giải quyết đặt nó trong một thể loại cho UINavigationControllerlớp học. Chúc mừng.
Lorenzo B

Tôi rất mắc nợ bạn vì câu hỏi này. Tôi đã ngạc nhiên khi resignFirstResponderđang thực hiện nhưng bàn phím vẫn được hiển thị. Kịch bản của tôi (PresentFormSheet với navig contrllr) hoàn toàn giống với kịch bản của bạn. Cảm ơn rất nhiều !!
sErVerdevIL

Câu trả lời:


115

Trong trình điều khiển xem được trình bày theo phương thức, chỉ cần ghi đè disablesAutomaticKeyboardDismissalđể trả về NO:

- (BOOL)disablesAutomaticKeyboardDismissal {
    return NO;
}

Đúng, vì 4.3 điều này dường như là trường hợp. Sẽ cập nhật câu hỏi. Cảm ơn!
Kalle

2
Điều này cần phải được thêm vào bộ điều khiển điều hướng
chậu

1
Có, hoạt động khi bạn ghi đè lên nó trong NavigationContoder. Đó là điều duy nhất thực sự làm việc cho tôi.
James Laurenstin

Cứu người! Tại sao Apple làm những thứ như thế này? Chắc chắn nó nên mặc định là KHÔNG & cho phép chúng tôi thay đổi nó nếu chúng tôi thực sự muốn
SomaMan

Không hoạt động trên lớp dẫn xuất UIViewControll, disablesAutomaticPalDismissal không bao giờ được gọi
Jorge Arimany

172

Điều này đã được các kỹ sư của Apple phân loại là "hoạt động như dự định". Tôi đã nộp một lỗi cho điều này một thời gian trở lại. Lý do của họ là người dùng thường nhập dữ liệu ở dạng phương thức để họ cố gắng "hữu ích" và giữ cho bàn phím hiển thị khi các chuyển đổi khác nhau trong chế độ xem theo chế độ có thể khiến bàn phím hiển thị / ẩn nhiều lần.

chỉnh sửa: đây là phản hồi của một kỹ sư Apple trên các diễn đàn nhà phát triển:

Quan điểm của bạn có bất kỳ cơ hội nào được trình bày với kiểu UIModalPftimeationFormSheet không? Để tránh các hình ảnh động ra vào thường xuyên, đôi khi bàn phím sẽ vẫn ở trên màn hình ngay cả khi không có phản hồi đầu tiên. Đây không phải là một lỗi.

Điều này đang gây ra nhiều vấn đề cho mọi người (bao gồm cả bản thân tôi) nhưng hiện tại dường như không có cách nào để giải quyết.

CẬP NHẬT:

Trong iOS 4.3 trở lên, giờ đây bạn có thể triển khai `-disablesAutomaticPalDismissal 'trên trình điều khiển chế độ xem của mình để trả về NO:

- (BOOL)disablesAutomaticKeyboardDismissal {
    return NO;
}

Điều này khắc phục vấn đề.


7
Tạm dừng Wow, được thôi. Cảm ơn rất nhiều cho những người đứng đầu. Apple chết tiệt .. :(
Kalle

Bạn đã gửi báo cáo lỗi cho Apple? Tôi đã làm như vậy theo ID # 8384423. Tôi cũng đã gửi đơn đăng ký mẫu để tái tạo hành vi.
Ếch Shaggy

3
Kể từ iOS 4.3, giờ đây đã có một phương thức disablesAutomaticPalDismissal giúp khắc phục vấn đề này.
Kalle

5
Tôi thử phương pháp vô hiệu hóaAutomaticPalDismissal, nhưng nó vẫn không giải quyết được vấn đề, làm thế nào để giải quyết nó?
R. Dewi

3
@Snips: Bạn cần tạo một UINavigationControllerlớp con ghi đè disablesAutomaticKeyboardDismissalđể trả về NOvà sử dụng lớp này làm trình điều khiển điều hướng khi bạn trình bày một biểu mẫu phương thức. Xem câu trả lời từ @ miha-hribar bên dưới.
Pascal

149

Hãy cẩn thận nếu bạn đang hiển thị phương thức với a UINavigationController. Sau đó, bạn phải thiết lậpdisablesAutomaticKeyboardDismissal trên bộ điều khiển điều hướng chứ không phải trên bộ điều khiển xem. Bạn có thể dễ dàng làm điều này với các thể loại.

Tập tin: UINavestionControll + KeyboardDismiss.h

#import <Foundation/Foundation.h>

@interface UINavigationController (KeyboardDismiss)

- (BOOL)disablesAutomaticKeyboardDismissal;

@end

Tập tin: UINavestionControll + KeyboardDismiss.m

#import "UINavigationController+KeyboardDismiss.h"

@implementation UINavigationController(KeyboardDismiss)

- (BOOL)disablesAutomaticKeyboardDismissal
{
    return NO;
}

@end

Đừng quên nhập danh mục trong tệp nơi bạn sử dụng UINavestionControll.


19
+1, cuối cùng tôi nhìn thấy các mảnh còn thiếu thông tin cho vấn đề này nhấn mạnh: đó là một nhu cầu để ghi đè lên disablesAutomaticKeyboardDismissalcác UINavigationController, chứ không phải điều khiển điểm riêng, để khắc phục vấn đề này.
DarkDust

Đẹp! Đúng thứ tôi cần. Cảm ơn bạn.
Justin

Hoàn hảo. Không rõ ràng từ các tài liệu chính thức nhưng có ý nghĩa do UINavestionControll nằm trong chuỗi phản hồi. Câu trả lời tuyệt vời. Cảm ơn bạn!
imnk

1
Tôi đang trình bày một hộp thoại phương thức từ UISplitViewControll. Tôi đã thử đoạn mã trên, nhưng thay thế UISplitViewControll cho UINavestionControll, nhưng nó vẫn không hoạt động. Phương pháp này có nên hoạt động trên UISplitViewControll không?
Snips

6
Đó không phải là một ý tưởng tốt để thực hiện một phương pháp trùng lặp trong một thể loại. Bạn không bao giờ có thể chắc chắn việc thực hiện nào sẽ được gọi, vì vậy tốt nhất bạn có thể mong đợi hành vi không nhất quán. Tốt hơn để kế thừa từ UINavestionControll và ghi đè phương thức trong lớp tùy chỉnh của bạn.
sean woodward

51

Tôi đã giải quyết điều này bằng cách sử dụng UIModalPresentationPageSheetphong cách trình bày và thay đổi kích thước nó ngay lập tức sau khi tôi trình bày nó. Thích như vậy:

viewController.modalPresentationStyle = UIModalPresentationPageSheet;
viewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:viewController animated:YES];
viewController.view.superview.autoresizingMask = 
    UIViewAutoresizingFlexibleTopMargin | 
    UIViewAutoresizingFlexibleBottomMargin;    
viewController.view.superview.frame = CGRectMake(
    viewController.view.superview.frame.origin.x,
    viewController.view.superview.frame.origin.y,
    540.0f,
    529.0f
);
viewController.view.superview.center = self.view.center;
[viewController release];

Hmmm ... điều này không hoàn toàn đúng ... thay đổi kích thước khiến cho phương thức vẽ buồn cười ... nó giống như nó làm giảm nội dung xuống để vừa với hộp kích thước mới hoặc một cái gì đó ... mọi thứ trông thật buồn cười. :(
toofah

Ngoài ra còn có vấn đề xoay vòng với cái này ... nếu bạn xoay trong khi phương thức này hoạt động, nó sẽ co lại / phát triển như thể nó là một lượt xem toàn trang
toofah

2
toofah, tôi đã chỉnh sửa mã để xử lý vấn đề thu hẹp / tăng trưởng khi xoay; chỉ là vấn đề mang lại cho giám sát một lề trên và dưới linh hoạt. Tôi không chắc chắn tôi đang nhìn thấy hành vi khác.
azdev

1
cái này chỉ hoạt động miễn là bạn không đẩy một cái nhìn khác lên trên cái này. Bởi vì khi bạn đóng chế độ xem được đẩy lên trên chế độ xem được trình bày UIModalPftimeationPageSheet, nó sẽ trở về kích thước ban đầu.
V1ru8

Nó đã làm việc. Nhưng từ trong chế độ xem có vẻ hơi mờ. Tôi không biết tại sao.
jeswang

1

Nếu bạn bật một màn hình phương thức khác, bạn có thể biến bàn phím biến mất. Nó không đẹp và nó không hoạt động, nhưng bạn có thể biến nó đi.

Sẽ thật tuyệt nếu có một bản sửa lỗi, nhưng bây giờ nó đã hoạt động. Bạn có thể nêm nó trong một danh mục UIViewControllervà gọi nó khi bạn muốn bàn phím biến mất:

@interface _TempUIVC : UIViewController
@end

@implementation _TempUIVC
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return YES;
}
@end

@implementation UIViewController (Helpers)

- (void)_dismissModalViewController {
    [self dismissModalViewControllerAnimated:NO];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidHideNotification object:nil];
    [self release];
}

- (void)forceKeyboardDismissUsingModalToggle:(BOOL)animated {
    [self retain];
    _TempUIVC *tuivc = [[_TempUIVC alloc] init];
    tuivc.modalPresentationStyle = UIModalPresentationCurrentContext;
    [self presentModalViewController:tuivc animated:animated];
    if (animated) {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_dismissModalViewController) name:UIKeyboardDidHideNotification object:nil];
    } else
        [self _dismissModalViewController];
    [tuivc release];
}

@end

Hãy cẩn thận với điều này mặc dù khi bạn xemDidAppear / viewDidDisappear và tất cả các phương thức đó được gọi. Như tôi đã nói, nó không đẹp, nhưng hoạt động được.

-Adam


1

Bạn cũng có thể giải quyết vấn đề này trong một ứng dụng phổ quát bằng cách kiểm tra thành ngữ và nếu đó là iPad, đừng tự động bật bàn phím lên và để người dùng chạm vào bất cứ thứ gì họ muốn chỉnh sửa.

Có thể không phải là giải pháp tốt nhất nhưng nó rất đơn giản và không cần bất kỳ bản hack ưa thích nào sẽ phá vỡ với phiên bản iOS lớn tiếp theo :)


1

Đặt mã này trong viewWillDisappear: phương thức của bộ điều khiển hiện tại là một cách khác để khắc phục điều này:

Class UIKeyboardImpl = NSClassFromString(@"UIKeyboardImpl");
id activeInstance = [UIKeyboardImpl performSelector:@selector(activeInstance)];
[activeInstance performSelector:@selector(dismissKeyboard)];

1

Tôi thấy rằng disablesAutomaticKeyboardDismissalvà thêm một disablesAutomaticKeyboardDismissalchức năng không làm việc cho tôiUITextField trong một hộp thoại phương thức.

Bàn phím trên màn hình sẽ không biến mất.

Giải pháp của tôi là vô hiệu hóa tất cả các điều khiển nhập văn bản trong hộp thoại của tôi, sau đó kích hoạt lại các điều khiển có liên quan một phần giây sau đó.

Có vẻ như khi iOS thấy rằng không có UITextFieldđiều khiển nào được bật, thì nó sẽ thoát khỏi bàn phím.


0

Tôi chắc chắn rằng bạn đã xem xét điều này, nhưng bạn chắc chắn rằng lớp trình điều khiển của bạn được nối đúng với tư cách là đại biểu UITextField, phải không?


Tôi tự đặt nó bằng tay và các phương thức ủy nhiệm được gọi, vì vậy, vâng.
Kalle

0

có thể không trả về KHÔNG, nhưng CÓ. Vì vậy, nó có thể biến mất.

Và bạn có một textFieldShouldEndEditingCÓ trở lại là tốt?

tại sao bạn lại bắn [nextResponder becomeFirstResponder]?! xin lỗi tôi thấy bây giờ

Tôi cũng có một số UITextViews mà tất cả đều có thuộc tính "có thể chỉnh sửa" được đặt thành FALSE.

Chúng ta có thể cho rằng không ai trong số họ, trong bất kỳ cơ hội nào, có taggiá trị secondField.tag+1không? Nếu vậy, bạn đang bảo họ trở thành người trả lời đầu tiên, thay vì từ chức người trả lời đầu tiên. Có thể đặt một số NSLog () trong đó nếu cấu trúc.


1
KHÔNG = không chèn dòng mới, từ những gì tôi có thể nói. Và đặt nó thành CÓ đã không sửa nó.
Kalle

1
Một UITextField, theo một định nghĩa, không làm được gì nhiều với các dòng mới, tôi nghĩ vậy. Vì vậy, đó là thêm về việc xử lý nhấn nút Trả về / Hoàn thành, như đã nêu trong các tài liệu.
mvds

Bạn có chắc chắn rằng bạn đã nối mọi thứ đúng cách? Bạn đã đặt một NSLog("tf %x / method ...",textField);trong tất cả các chức năng đại biểu?
mvds

Chà, các chức năng của đại biểu được gọi một cách thích hợp, và chúng sẽ không xảy ra nếu đại biểu không được thiết lập phù hợp. Và NSLog cung cấp EXC_BAD_ACCESS. Cũng cảnh báo tôi về nó là loại không tương thích trong XCode.
Kalle

Cô ơi. Xin lỗi, tôi đã nhìn thấy điều đó bản thân mình. Tôi đã cập nhật câu trả lời ở trên với kết quả của các NSLog này vì định dạng sẽ xuất hiện trong comm ..
Kalle

0

Đối với những người gặp rắc rối với UINavestionControll, hãy xem câu trả lời của tôi cho một câu hỏi tương tự tại đây: https://stackoverflow.com/a/10507689/321785

Chỉnh sửa: Tôi coi đây là một cải tiến cho giải pháp của Miha Hribar (vì quyết định đang diễn ra ở nơi cần thiết) và trái ngược với nhận xét của Pascal về một danh mục trên UIViewControll


0

có thể không phải là một giải pháp hoàn hảo, nhưng hoạt động
[self.view endEditing: YES];
từ bất cứ nơi nào nút hoặc cử chỉ của bạn được thực hiện để trình bày phương thức


0
Swift 4.1:
extension UINavigationController {
   override open var disablesAutomaticKeyboardDismissal: Bool {
      return false
   }
}
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.