Tôi có một UITextView đang ngồi trên đầu UIView, và nếu tôi chạm vào nó để mở nó để chỉnh sửa, thì bàn phím sẽ chặn phần dưới cùng của khung nhìn và Tôi không thể nhìn thấy nó mặc dù tôi có thể viết trong lĩnh vực này. Tôi có thể yêu cầu UITextView có một vùng cuộn khác hoặc giải pháp là gì?Làm thế nào để có được UITextView di chuyển đúng cách khi bàn phím hiển thị
Trả lời
Cuối cùng tôi đã làm việc đó. Đây là giải pháp của tôi, các bạn có thể phát hiện ra bất kỳ lỗi nào trong thiết kế của tôi không?
@synthesize textView = _textView;
@synthesize callbackViewController = _callbackViewController;
-(void)keyboardWasShown:(NSNotification*)aNotification {
if(keyboardShown) {
return;
}
NSDictionary *info = [aNotification userInfo];
// Get the size of the keyboard.
NSValue *aValue = [info objectForKey:UIKeyboardFrameBeginUserInfoKey];
keyboardSize = [aValue CGRectValue].size;
// Resize the scroll view (which is the root view of the window)
CGRect viewFrame = [self.textView frame];
orientationAtShown = orientation;
if(orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) {
viewFrame.size.height -= keyboardSize.height;
} else {
viewFrame.size.height -= keyboardSize.width;
}
self.textView.frame = viewFrame;
// Scroll the active text field into view.
//CGRect textFieldRect = [activeField frame];
[self.textView scrollRectToVisible:viewFrame animated:YES];
keyboardShown = YES;
}
-(void)keyboardWasHidden:(NSNotification*)aNotification {
if(!keyboardShown) {
return;
}
// Reset the height of the scroll view to its original value
CGRect viewFrame = [self.textView frame];
if(orientationAtShown == UIInterfaceOrientationPortrait || orientationAtShown == UIInterfaceOrientationPortraitUpsideDown) {
viewFrame.size.height += keyboardSize.height;
} else {
viewFrame.size.height += keyboardSize.width;
}
self.textView.frame = viewFrame;
keyboardShown = NO;
}
-(void)registerForKeyboardNotifications {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWasHidden:)
name:UIKeyboardDidHideNotification object:nil];
}
-(void)viewWillAppear:(BOOL)animated {
keyboardShown = NO;
[self registerForKeyboardNotifications];
}
-(void)viewWillDisappear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if(keyboardShown) {
[self keyboardWasHidden:nil];
}
orientation = interfaceOrientation;
CGRect viewFrame = [self.textView frame];
if(orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) {
if(viewFrame.size.width > viewFrame.size.height) {
CGRect viewFrameFixed = CGRectMake(viewFrame.origin.x, viewFrame.origin.y, viewFrame.size.height, viewFrame.size.width);
self.textView.frame = viewFrameFixed;
}
} else {
if(viewFrame.size.width < viewFrame.size.height) {
CGRect viewFrameFixed = CGRectMake(viewFrame.origin.x, viewFrame.origin.y, viewFrame.size.height, viewFrame.size.width);
self.textView.frame = viewFrameFixed;
}
}
// Return YES for supported orientations
return YES;
}
orientationAtShown ???? bạn đã có danh sách các thành viên dữ liệu ở đây mà không có khai báo hoặc giải thích – iOSProgrammingIsFun
Apple có một số code samples đối phó với tình huống chính xác này.
Tôi đã thực hiện ví dụ từ liên kết, và nó hoạt động nhưng khu vực cuộn cho UITextView của tôi trở nên khá nhiều nhỏ (như 50 pixel). Bất kỳ ý tưởng tại sao? – Neigaard
Kiểm tra các mặt nạ thay đổi kích thước trong Trình tạo giao diện. Tôi không chắc cài đặt phù hợp là gì, nhưng họ kiểm soát cách chế độ xem văn bản đáp ứng với các thay đổi về kích thước của cha mẹ. –
Khi bạn nói thay đổi kích thước mặt nạ, sau đó bạn có ý nghĩa gì? – Neigaard
Một giải pháp dễ dàng là để thực hiện các UITextViewDelegate
Phương pháp
- (void)textViewDidBeginEditing:(UITextView *)textView
và
- (void)textViewDidEndEditing:(UITextView *)textView
Bạn có thể làm cho UITextView Khung nhỏ hơn khi bàn phím xuất hiện và làm cho nó kích thước đầy đủ một lần nữa khi bàn phím biến mất ... như sau:
- (void)textViewDidBeginEditing:(UITextView *)textView {
self.textView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height/1.8);
}
- (void)textViewDidEndEditing:(UITextView *)textView {
self.textView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
}
EDIT
Giải pháp trên không tốt ... không sử dụng !!!
Bây giờ tôi nghĩ nên thay đổi kích thước UITextView theo kích thước bàn phím và không phải với giá trị cố định ... vì kích thước bàn phím có thể thay đổi khi một ngôn ngữ khác được chọn hoặc thiết bị trở nên xoay vòng. ..of nhiên -.-
Lúc đầu, bạn phải đăng ký UIViewController
của bạn hiển thị UITextView
bạn nhận Keyboard Notifications:
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil];
}
Sau đó, bạn phải thực hiện hai phương pháp -keyboardWasShown:
và -keyboardWillBeHidden:
.
Kích thước bàn phím thực được chứa trong đối tượng NSNotification
.
- (void)keyboardWasShown:(NSNotification*)notification {
NSDictionary* info = [notification userInfo];
CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
self.textView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height - keyboardSize.height);
}
- (void)keyboardWillBeHidden:(NSNotification*)notification {
self.textView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
}
đây là câu trả lời đúng! –
Không. Điều chỉnh contentInsets, không phải khung. – Linasses
Một giải pháp tốt hơn, đặc biệt dành cho iOS 7, sẽ được điều chỉnh thuộc tính nội dung inset của TextView thay vì khung của nó, theo cách này, bàn phím sẽ mờ văn bản mà rơi behinds nó giống như trong bất kỳ iOS khác 7 ứng dụng. Bạn cũng sẽ phải điều chỉnh các chỉ báo cuộn để khớp.
Mở rộng câu trả lời Lindemann của,
- (void)keyboardWasShown:(NSNotification*)notification {
NSDictionary* info = [notification userInfo];
CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
self.textView.contentInset = UIEdgeInsetsMake(0, 0, keyboardSize.height, 0);
self.textView.scrollIndicatorInsets = self.textView.contentInset;
}
- (void)keyboardWillBeHidden:(NSNotification*)notification {
self.textView.contentInset = UIEdgeInsetsZero;
self.textView.scrollIndicatorInsets = UIEdgeInsetsZero;
}
@Alejandro trên có ý tưởng đúng, nhưng mã của ông không hoạt động trong chế độ phong cảnh.Tôi đã sửa đổi phương pháp keyboardWasShown:
của mình để làm việc một cách chính xác trong tất cả các định hướng:
- (void)keyboardWasShown:(NSNotification *)notification {
if (self.textView != nil) {
NSDictionary* info = [notification userInfo];
CGRect keyboardRect = [self.textView convertRect:[[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue] fromView:nil];
CGSize keyboardSize = keyboardRect.size;
self.textView.contentInset = UIEdgeInsetsMake(0, 0, keyboardSize.height, 0);
self.textView.scrollIndicatorInsets = self.textView.contentInset;
}
}
Mở rộng @alejandro & @Mani:
Th câu trả lời cuối cùng:
- (void)keyboardWasShown:(NSNotification *)notification {
if (self.textView != nil) {
NSDictionary* info = [notification userInfo];
CGRect keyboardRect = [self.textNote convertRect:[[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue] fromView:nil];
CGSize keyboardSize = keyboardRect.size;
self.textView.contentInset = UIEdgeInsetsMake(0, 0, keyboardSize.height, 0);
self.textView.scrollIndicatorInsets = self.textView.contentInset;
}
}
- (void)keyboardWillBeHidden:(NSNotification*)notification {
self.textView.scrollIndicatorInsets = UIEdgeInsetsZero;
self.textView.scrollIndicatorInsets = UIEdgeInsetsZero;
}
điều này không hoạt động tốt, có thể là vấn đề UIKeyboardFrameEndUserInfoKey? – slboat
Thêm Observer đầu tiên trong viewDidLoad
.
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWasHidden:)
name:UIKeyboardWillHideNotification object:nil];
}
Gọi phương pháp
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
self.textView.contentInset = contentInsets;
self.textView.scrollIndicatorInsets = contentInsets;
// If active text field is hidden by keyboard, scroll it so it's visible
// Your app might not need or want this behavior.
CGRect aRect = self.view.frame;
aRect.size.height -= kbSize.height;
if (!CGRectContainsPoint(aRect, self.textView.frame.origin)) {
[self.textView scrollRectToVisible:self.textView.frame animated:YES];
}
}
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWasHidden:(NSNotification*)aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
self.textView.contentInset = contentInsets;
self.textView.scrollIndicatorInsets = contentInsets;
}
nếu bạn có nhiều thì 1 trường văn bản hoặc bạn muốn giảm bớt mã của bạn sau đó thử mã này
- (void)textFieldDidBeginEditing:(UITextField *)textField{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.35f];
CGRect frame = self.view.frame;
frame.origin.y = (self.view.frame.size.height - textField.frame.origin.y) - self.view.frame.size.height+60;
if (frame.origin.y<-162) {
frame.origin.y = -162;
}
[self.view setFrame:frame];
[UIView commitAnimations];
}
-(BOOL)textFieldShouldEndEditing:(UITextField *)textField{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.35f];
CGRect frame = self.view.frame;
frame.origin.y = 0;
[self.view setFrame:frame];
[UIView commitAnimations];
return YES;
}
Nếu bạn muốn có một đầu vào Messages App phong cách , bạn có thể sử dụng một UITextView lồng nhau (cho phép nhiều dòng văn bản). Nó sẽ giống như thế này cuối cùng:
Bạn bắt đầu bằng cách đặt ra một cái nhìn để giữ tất cả các quan điểm con. Ở đây màu nền của bottomView được thiết lập để phù hợp với UIKeyboardAppearanceDark. Nó nằm ở dưới cùng của màn hình.
bottomView = [UIView new];
bottomView.frame = CGRectMake(0, h-45, w, 45);
bottomView.backgroundColor = [UIColor colorWithRed:0.078 green:0.078 blue:0.078 alpha:1];
[self.view addSubview:bottomView];
Sau đó, thêm vào chế độ xem nền đơn giản được tạo kiểu như UITextField điển hình và thêm UITextView làm tiểu sử cho điều đó. InputTV (UITextView) lấy chiều cao dựa trên kích thước của phông chữ. Ngoài ra, tất cả các padding được lấy ra từ inputTV sử dụng các biến textContainer.
inputTVBG = [UIImageView new];
inputTVBG.frame = CGRectMake(10, 8, w-90, 29);
inputTVBG.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.1f];
inputTVBG.layer.cornerRadius = 4.0f;
inputTVBG.userInteractionEnabled = true;
inputTVBG.clipsToBounds = true;
[bottomView addSubview:inputTVBG];
inputTV = [UITextView new];
inputTV.font = [UIFont systemFontOfSize:14.0f];
inputTV.frame = CGRectMake(5, 6, w-100, inputTV.font.lineHeight);
inputTV.backgroundColor = [UIColor clearColor];
inputTV.keyboardAppearance = UIKeyboardAppearanceDark;
inputTV.delegate = self;
inputTV.autocorrectionType = UITextAutocorrectionTypeNo;
inputTV.tintColor = [UIColor whiteColor];
inputTV.textColor = [UIColor whiteColor];
inputTV.textContainer.lineFragmentPadding = 0;
inputTV.textContainerInset = UIEdgeInsetsZero;
[inputTVBG addSubview:inputTV];
Trong ví dụ trên, tôi đã bao gồm nhãn cho biết có bao nhiêu chữ cái (tối đa/ký tự) và nút gửi.
lettersLeftLabel = [UILabel new];
lettersLeftLabel.frame = CGRectMake(w-70, 8, 60, 16);
lettersLeftLabel.font = [UIFont systemFontOfSize:12.0f];
lettersLeftLabel.textColor = [[UIColor whiteColor] colorWithAlphaComponent:0.5f];
lettersLeftLabel.alpha = 0.0f;
[bottomView addSubview:lettersLeftLabel];
submitButton = [UIButton new];
submitButton.frame = CGRectMake(w-70, 0, 60, 45);
[submitButton setTitle:@"SUBMIT" forState:UIControlStateNormal];
[submitButton setTitleColor:[_peacock.applePink colorWithAlphaComponent:0.5f] forState:UIControlStateNormal];
[submitButton addTarget:self action:@selector(submit) forControlEvents:UIControlEventTouchUpInside];
[submitButton.titleLabel setFont:[UIFont boldSystemFontOfSize:14.0f]];
[bottomView addSubview:submitButton];
Thêm dòng này sớm trong mã của bạn, vì vậy bạn sẽ có được cập nhật thay đổi bàn phím:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
Nó gọi phương thức dưới đây khi người dùng nhấp vào inputTV. Ở đây nó đặt biến 'keyboardHeight' được sử dụng sau này.
-(void)keyboardWillShow:(NSNotification *)n {
CGRect rect = [n.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect keyboardFrame = [self.view convertRect:rect fromView:nil];
keyboardHeight = keyboardFrame.size.height;
[self textViewDidChange:inputTV];
}
Đây là đoạn mã chính đảm nhiệm mọi chuyển động và thay đổi kích thước của inputTV.
-(void)textViewDidChange:(UITextView *)textView {
//1. letters and submit button vars
int numberOfCharacters = (int)textView.text.length;
int minCharacters = 50;
int maxCharacters = 400;
int remainingCharacters = maxCharacters-numberOfCharacters;
//2. if entered letters exceeds maximum, reset text and return
if (remainingCharacters <= 0){
textView.text = [textView.text substringToIndex:maxCharacters];
numberOfCharacters = maxCharacters;
}
//3. set height vars
inputTV.scrollEnabled = true;
float textHeight = textView.contentSize.height;
float lineHeight = roundf(textView.font.lineHeight);
float additionalHeight = textHeight - lineHeight;
float moveUpHeight = keyboardHeight + additionalHeight;
//4. default letter colour is weak white
UIColor * letterColour = [[UIColor whiteColor] colorWithAlphaComponent:0.5f];
if (numberOfCharacters < minCharacters){ //minimum threshold not met
lettersLeftLabel.text = [NSString stringWithFormat:@"%i", minCharacters-numberOfCharacters];
letterColour = [_peacock.applePink colorWithAlphaComponent:0.5f];
} else { //within range
lettersLeftLabel.text = [NSString stringWithFormat:@"%i/%i", numberOfCharacters, maxCharacters];
if (remainingCharacters<5){ //increase alpha towards the end of range
letterColour = [[UIColor whiteColor] colorWithAlphaComponent:1.0f - ((float)remainingCharacters/10)];
}
}
//5. hide/show letter label based on textView height
float letterAlpha = 0.0f; //default hide
if (additionalHeight > 0){ letterAlpha = 1.0f; } //if multiline, show
[UIView animateWithDuration:0.3f
delay:0.0f
options:UIViewAnimationOptionCurveEaseOut
animations:^{
lettersLeftLabel.alpha = letterAlpha;
lettersLeftLabel.textColor = letterColour;
}
completion:^(BOOL finished){
}];
//6. update submit colour based on minimum threshold
UIColor * submitColour = [_peacock.applePink colorWithAlphaComponent:0.5f];
bool enableSubmit = false;
if (numberOfCharacters >= minCharacters){
submitColour = _peacock.applePink;
enableSubmit = true;
}
[submitButton setEnabled:enableSubmit];
[UIView animateWithDuration:0.3f
delay:0.0f
options:UIViewAnimationOptionCurveEaseOut
animations:^{
[submitButton setTitleColor:submitColour forState:UIControlStateNormal];
}
completion:^(BOOL finished){
}];
//7. special case if you want to limit the frame size of the input TV to a specific number of lines
bool shouldEnableScroll = false;
int maxNumberOfLines = 5; //anything above this triggers the input TV to stay stationary and update its scroll
int actualNumberOfLines = textHeight/textView.font.lineHeight;
if (actualNumberOfLines >= maxNumberOfLines){ //recalculate vars for frames
textHeight = maxNumberOfLines * lineHeight;
additionalHeight = textHeight - lineHeight;
moveUpHeight = keyboardHeight + additionalHeight;
shouldEnableScroll = true;
}
//8. adjust frames of views
inputTV.frame = CGRectMake(5, 6, w-100, textHeight); //update immediately (parent view clips to bounds)
[UIView animateWithDuration:0.3f
delay:0.0f
options:UIViewAnimationOptionCurveEaseOut
animations:^{
bottomView.frame = CGRectMake(0, h-45-moveUpHeight, w, 45+additionalHeight);
inputTVBG.frame = CGRectMake(10, 8, w-90, lineHeight+additionalHeight+13);
submitButton.frame = CGRectMake(w-70, additionalHeight, 60, 45);
}
completion:^(BOOL finished){
inputTV.scrollEnabled = shouldEnableScroll; //default disable scroll here to avoid bouncing
}];
}
Trong các phương pháp trên, đây là những gì đang xảy ra:
Nếu bạn muốn thiết lập ở mức tối thiểu hoặc số ký tự tối đa, bạn có thể làm như vậy ở đây. Bạn kéo số lượng ký tự và lưu trữ dưới dạng số nguyên và tính số lượng ký tự còn lại.
Nếu người dùng đã đạt đến số ký tự tối đa, hãy đặt lại văn bản textView bằng cách rút gọn về giá thầu CPC
Những vars này được sử dụng để tính toán số tiền bạn cần để di chuyển BottomView của mình và cũng để thay đổi kích thước các bản xem trước của nó.
Phương pháp này chỉ để thay đổi màu/văn bản của một số yếu tố giao diện người dùng. Nó không hoàn toàn cần thiết.
Phương pháp này sẽ đưa các chữ cáiLeftLabel vào chế độ xem nếu bạn đang sử dụng. Nó cũng không cần thiết.
Điều này chỉ cho phép nút gửi nếu đạt đến số ký tự tối thiểu. Nó thay đổi màu như một chỉ báo cho người dùng.
Nếu bạn muốn giới hạn sự tăng trưởng của inputTV và các yếu tố xung quanh, bạn có thể bao gồm mã bit này. Nó đòi hỏi bạn phải thiết lập số lượng tối đa của dòng bạn muốn hiển thị. Nếu người dùng vượt quá mức tối đa, cuộn được bật lại cho inputTV, nếu không thì nó sẽ mặc định là false (quan trọng là dừng nó lại).
Đây là logic thay đổi kích thước chính, di chuyển bottomView lên và thay đổi kích thước chế độ xem con của nó. Nút gửi cần phải ở trong cùng một vị trí, vì vậy hãy di chuyển xuống dưới khi phần dưới cùng phát triển.
Chú ý: Nếu bạn chỉ muốn mã barebones, bạn chỉ cần thực hiện bước 3 và 8.
- 1. Cách di chuyển UITextView khi bàn phím hiện diện
- 2. Làm cách nào để hiển thị bàn phím theo mặc định trong UITextView?
- 3. UITextView bên trong UIScrollView bên trong Popover không hiển thị đầy đủ khi bàn phím được hiển thị
- 4. iOS: Tắt hoạt ảnh UITableView khi bàn phím hiển thị
- 5. bố trí của màn hình di chuyển lên khi bàn phím được hiển thị
- 6. Hiển thị bàn phím vào đúng thời điểm iOS7
- 7. Làm cách nào để buộc bàn phím hiển thị/ẩn?
- 8. Có cách nào để tránh hiển thị bàn phím điện thoại di động trong safari
- 9. Cách hiển thị bàn phím cho UIView
- 10. UIPopoverView bị méo khi bàn phím được hiển thị + iPad
- 11. Buộc trên bàn phím màn hình hiển thị khi bàn phím bluetooth được kết nối
- 12. Làm cách nào để buộc hiển thị và ẩn Bàn phím ảo nếu không có bàn phím phần cứng?
- 13. Cách hiển thị bàn phím sau khi sử dụng inputView
- 14. Ngăn UIWebView di chuyển khi bàn phím xuất hiện
- 15. Nút để hiển thị bàn phím ảo?
- 16. Di chuyển UIScrollView khi bàn phím đi vào vị trí
- 17. Làm cách nào để hiển thị UIDatePicker thay vì bàn phím khi người dùng chọn UITextField?
- 18. Làm cách nào để tránh hiển thị và ẩn bàn phím khi thay đổi tiêu điểm từ UITextField và UIWebView?
- 19. cách hiển thị bàn phím số
- 20. Cách hiển thị bàn phím số
- 21. Làm thế nào để ẩn bàn phím - của - UITextView iPhone - bằng cách trả lại chính
- 22. Làm thế nào để tôi có được bàn tay trên bàn phím Dvorak?
- 23. Phát triển Iphone - Cách hiển thị bàn phím số?
- 24. Làm thế nào để hiển thị Bàn Phím Mềm từ một Dịch Vụ?
- 25. NSTextView không được làm mới đúng cách khi di chuyển
- 26. ActionBar sẽ tắt màn hình khi bàn phím hiển thị
- 27. Làm cách nào để hiển thị bàn phím số trên EditText trong Android?
- 28. Android: Cách làm cho bàn phím luôn hiển thị?
- 29. Làm thế nào để ẩn bàn phím trên hộp thoại hiển thị?
- 30. Buộc bàn phím hiển thị qua nút (iOS)
trùng lặp tìm kiếm ở đây cho câu trả lời http://stackoverflow.com/questions/1126726/how-to -make-a-uitextfield-di-up-khi-bàn phím-là-hiện tại –