>我的导航控制器和 2 个视图控制器有问题。当我弹出到其他视图控制器时,一切都很好,但是当我返回第一个视图时,它在导航栏下方显示一个大的白色位置
在第二个控制器上,当我编辑UITextField时,键盘会自动显示和隐藏。当我从显示键盘的第二个视图控制器返回时,此问题就开始了。其他方式(没有编辑UITextField)我对第一个控制器没有这个问题。
我需要做什么?
第一个 .m 文件
#import "OTPTRecordViewController.h"
#import "OTPTAppDelegate.h"
#import "OTPTPractice.h"
@implementation OTPTRecordViewController
@synthesize scrollView, activeField;
- (void)viewDidLoad
{
[super viewDidLoad];
[self registerForKeyboardNotifications];
viewBackgroundTap.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:viewBackgroundTap];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
UIEdgeInsets contentInsets = UIEdgeInsetsMake(-20.0, 0.0, 0.0, 0.0);
//I need it for correct view insets
scrollView.contentInset = contentInsets;
scrollView.scrollIndicatorInsets = contentInsets;
}
#pragma mark Textfields&Keyboard management
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return NO;
}
- (IBAction)backgroundTap:(id)sender
{
[nameTextField resignFirstResponder];
[lengthTextField resignFirstResponder];
}
- (void)registerForKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil];
}
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
if (([holdOutTextField isEditing]) || ([cyclesTextField isEditing])) {
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height+50.0, 0.0);
scrollView.contentInset = contentInsets;
scrollView.scrollIndicatorInsets = contentInsets;
}
CGRect aRect = self.view.frame;
//For scroll view moves
aRect.size.height -= kbSize.height + self.navigationController.navigationBar.frame.size.height + [UIApplication sharedApplication].statusBarFrame.size.height;
CGPoint origin = activeField.frame.origin;
origin.y -= scrollView.contentOffset.y;
if (!CGRectContainsPoint(aRect, origin) ) {
CGPoint scrollPoint = CGPointMake(0.0, activeField.frame.origin.y-(aRect.size.height));
[scrollView setContentOffset:scrollPoint animated:YES];
}
}
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsMake(-20.0, 0.0, 0.0, 0.0);
scrollView.contentInset = contentInsets;
scrollView.scrollIndicatorInsets = contentInsets;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
activeField = textField;
[activeField setSelectedTextRange:[activeField textRangeFromPosition:activeField.beginningOfDocument toPosition:activeField.endOfDocument]];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
activeField = nil;
}
@end
第二个 .m 文件
#import "OTPTSaveViewController.h"
#import "OTPTAppDelegate.h"
#import "OTPTRecordViewController.h"
@interface OTPTSaveViewController () {
UIViewController *parentViewController;
}
@end
@implementation OTPTSaveViewController
@synthesize textField;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
UITapGestureRecognizer *viewBackgroundTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(backgroundTap:)];
viewBackgroundTap.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:viewBackgroundTap];
parentViewController = [self presentingViewController];
}
- (IBAction)cancel:(id)sender {
[[self navigationController] popViewControllerAnimated:YES];
}
- (IBAction)save:(id)sender {
//some saving
}
- (BOOL)textFieldShouldReturn:(UITextField *)tf {
[tf resignFirstResponder];
return NO;
}
- (IBAction)backgroundTap:(id)sender
{
[textField resignFirstResponder];
}
@end
我认为这个问题是因为来自弹出控制器的键盘通知。但是当我添加
[self unregisterForKeyboardNotifications];
查看将消失并制作方法
- (void) unregisterForKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
它没有给我任何效果
从 iOS 7 开始,UIViewController 中添加了一个新属性...
@property(nonatomic, assign) BOOL automaticallyAdjustsScrollViewInsets
根据苹果文档:
默认值为 YES,这允许视图控制器调整其滚动视图内陷,以响应状态栏、导航栏和工具栏或选项卡栏使用的屏幕区域。如果要自行管理滚动视图内陷调整,请设置为 NO,例如当视图层次结构中有多个滚动视图时。
如果手动管理插图,则可能需要将此属性设置为 NO,因为这可能会干扰您尝试执行的操作。
我以某种狡猾的方式解决了这个问题
我在 AppDelegate 中制作了一个名为 isAfterSafe 的 BOOL,在第二个文件中使其成为 YES:
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
OTPTAppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
appDelegate.isAfterSave = YES;
}
并在第一个文件中使用简单的 if
- (void)keyboardWasShown:(NSNotification*)aNotification
{
OTPTAppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
if (!appDelegate.isAfterSave) {
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
if (([holdOutTextField isEditing]) || ([cyclesTextField isEditing])) {
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height+50.0, 0.0);
scrollView.contentInset = contentInsets;
scrollView.scrollIndicatorInsets = contentInsets;
}
CGRect aRect = self.view.frame;
aRect.size.height -= kbSize.height + self.navigationController.navigationBar.frame.size.height + [UIApplication sharedApplication].statusBarFrame.size.height;
CGPoint origin = activeField.frame.origin;
origin.y -= scrollView.contentOffset.y;
if (!CGRectContainsPoint(aRect, origin) ) {
CGPoint scrollPoint = CGPointMake(0.0, activeField.frame.origin.y-(aRect.size.height));
[scrollView setContentOffset:scrollPoint animated:YES];
}
}
else appDelegate.isAfterSave = NO;
}
当然,这不是一个美丽的方式,但它解决了这个问题