如果键盘阻止了文本视图,则移动 UIView
Posted
技术标签:
【中文标题】如果键盘阻止了文本视图,则移动 UIView【英文标题】:Move UIView if keyboard is blocking a textview 【发布时间】:2017-05-10 16:19:39 【问题描述】:您好,我有一个 UIView,它显示为模式。该视图包含一些 UITextView 字段。问题是当我编辑一些较低的视图时,键盘会弹出隐藏它的字段。
我需要一种方法来使视图内容可滚动,或者如果键盘挡住它,则将视图内容向上移动。视图是以编程方式创建的。我尝试移动视图,但无法获得活动的 textview(从未调用过 textViewDidBeginEditing 方法)。这是我的代码..
EditController.m
- (void)editNavPressedEdit:(MapElement *)mapElement
[self dismissViewControllerAnimated:YES completion:^
EditAnnotationController *annotationController = [[EditAnnotationController alloc] init];
annotationController.mapElement = mapElement;
annotationController.delegate = self;
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:annotationController];
navigationController.modalPresentationStyle = UIModalPresentationFormSheet;
navigationController.preferredContentSize = CGSizeMake(500, 500);
navigationController.navigationBar.translucent = NO;
navigationController.navigationBar.barTintColor = [UIColor blackColor];
navigationController.view.backgroundColor = [UIColor blackColor];
[self presentViewController:navigationController animated:YES completion:nil];
];
EditDetailController.h
@class MapElement;
@protocol EditAnnotationDelegate
- (void)editAnnotationSaved:(MapElement *)element;
- (void)editAnnotationCancelled;
@end
@interface EditAnnotationController : UIViewController <NavigationPickerDelegate, EditOverlayDelegate, UITextViewDelegate>
@property(nonatomic, strong) MapElement *mapElement;
@property(nonatomic, weak) id <EditAnnotationDelegate> delegate;
@end
EditDetailController.m
@implementation EditAnnotationController
UIView *_detailView;
NSLayoutConstraint *_detailWidth;
NSArray *_detailHoriz;
NSMutableDictionary *_bindings;
NSMutableArray *_detailObjects;
NSDateFormatter *_dateFormatter;
UIButton *_dateButton;
UISegmentedControl *_segmentedControl;
NSArray *_segments;
NSString *_segmentsBinding;
UITextField *_radiusField;
UITextView *_activeField;
@synthesize mapElement = _mapElement;
@synthesize delegate = _delegate;
- (void)viewDidLoad
[super viewDidLoad];
_detailObjects = [NSMutableArray array];
_bindings = [NSMutableDictionary dictionary];
_dateFormatter = [NSDateFormatter new];
_dateFormatter.dateFormat = @"MM/dd/yyyy hh:mm:ss a";
[self setUpDetailView];
if (_mapElement)
[self setUpMapElement];
UIBarButtonItem *saveButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(save)];
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancel)];
self.navigationItem.rightBarButtonItem = saveButton;
self.navigationItem.leftBarButtonItem = cancelButton;
- (void)viewWillAppear:(BOOL)animated
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
- (void)viewWillDisappear:(BOOL)animated
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
- (void)setUpDetailView
_detailView = [UIView new];
_detailView.backgroundColor = [UIColor blackColor];
_detailView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_detailView];
NSArray *vertical = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view]|" options:0 metrics:nil views:@@"view": _detailView];
_detailHoriz = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view]|" options:0 metrics:nil views:@@"view": _detailView];
[self.view addConstraints:vertical];
[self.view addConstraints:_detailHoriz];
- (void)keyboardWillShow:(NSNotification *)notification
CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
[UIView animateWithDuration:0.3 animations:^
CGRect f = self.view.frame;
f.origin.y = -keyboardSize.height + 250;
self.view.frame = f;
];
- (void)textViewDidBeginEditing:(UITextView *)textView
_activeField = textView;
- (void)textViewDidEndEditing:(UITextView *)textView
_activeField = nil;
- (void)keyboardWillHide:(NSNotification *)notification
[UIView animateWithDuration:0.3 animations:^
CGRect f = self.view.frame;
f.origin.y = 44;
self.view.frame = f;
];
- (void)setUpMapElement
[self setViewWidth:320];
[self addImage:_mapElement.iconImage size:CGSizeMake(30, 30)];
switch ([_mapElement.layerID intValue])
case 1:
[self configureHydrant];
break;
[self addConstraints];
- (void)configureHydrant
[self addTitleLabel:@"Hydrant"];
[self addHeaderLabel:@"Name:"];
_bindings[propertyKeyPathLastComponent(_mapElement.subType)] = [self addTextField:_mapElement.subType];
[self addHeaderLabel:@"Cap Color:"];
_segments = @[@"Red", @"Blue", @"Green", @"Orange"];
_segmentsBinding = propertyKeyPathLastComponent(_mapElement.steamerCapColor);
[self addSegments:_segments selected:_mapElement.steamerCapColor];
[self addHeaderLabel:@"Water line size:"];
_bindings[propertyKeyPathLastComponent(_mapElement.waterLineSize)] = [self addTextField:_mapElement.waterLineSize.stringValue];
[self addHeaderLabel:@"Flow rate:"];
_bindings[propertyKeyPathLastComponent(_mapElement.flowRate)] = [self addTextField:_mapElement.flowRate.stringValue];
[self addHeaderLabel:@"PSI:"];
_bindings[propertyKeyPathLastComponent(_mapElement.psi)] = [self addTextField:_mapElement.psi.stringValue];
[self addHeaderLabel:@"Notes:"];
_bindings[propertyKeyPathLastComponent(_mapElement.description)] = [self addTextView:_mapElement.description];
【问题讨论】:
【参考方案1】:每当您创建相关的 TextView 时,请将您的 ViewController 设置为它们的委托:
UITextField *myTextField = [UITextField alloc] init];
myTextField.delegate = self;
在此之后 textViewDidBeginEditing 应该按预期调用。
【讨论】:
【参考方案2】:首先注册“UIKeyboardWillShowNotification”和“UIKeyboardWillHideNotification”通知,如下所示,
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShown:)
name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil]
然后实现方法,'keyboardWillShown:' 和 'keyboardWillBeHidden:',如下所示,
- (void)keyboardWillShown:(NSNotification*)aNotification
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
if(selectedTextField.origin.y > self.view.size - kbSize.height)
//shift view upwards
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
//set origin of view to (0,0)
【讨论】:
我的问题是我无法触发 textViewDidBeginEditing 方法。我无法获得活动的文本视图,可能是因为它是以编程方式创建的? @nikBhosale以上是关于如果键盘阻止了文本视图,则移动 UIView的主要内容,如果未能解决你的问题,请参考以下文章
React Native:键盘在调整其视图高度时阻止多行文本输入