我知道这个问题已经被反复提出,但对我来说似乎没有什么解决办法。大部分的解决方案都已经过时了,剩下的则是巨大的代码块,比实际项目编码的大十倍。我有几个垂直排列的UITextFields,但当键盘启动以编辑其中一个文本字段时,它会覆盖文本字段。我想知道是否有一种简单的初学者方法来滚动视图向上,然后在开始和结束编辑时再滚回去?
谢谢。
我知道这个问题已经被反复提出,但对我来说似乎没有什么解决办法。大部分的解决方案都已经过时了,剩下的则是巨大的代码块,比实际项目编码的大十倍。我有几个垂直排列的UITextFields,但当键盘启动以编辑其中一个文本字段时,它会覆盖文本字段。我想知道是否有一种简单的初学者方法来滚动视图向上,然后在开始和结束编辑时再滚回去?
谢谢。
我曾经使用键盘通知和当前第一响应者的检测来处理可滚动及不可滚动视图的问题,但有时我会使用以下简单解决方案:通过文本字段代理的textViewDidBeginEditing:
方法检测键盘的打开,并将整个视图向上移动。最简单的方法是类似于将self.view.bounds.origin.y
更改为-100(或其他值)。使用相应的textViewShouldEndEditing:
方法将其设置为相反的值,在这种情况下是100。更改bounds
是一个相对过程。更改后,框架被移动,但边界原点仍然为零。
CGRect frame = self.view.frame;
frame.origin.y = -100;
[self.view setFrame:frame];
[UIView commitAnimations];
}` 但是我得到了一个警告,说“控制流达到非void函数的结尾”。我不知道该怎么解决,很抱歉我还是个初学者。 - Henry Freturn YES;
以表示您允许编辑。不要忘记将此类设置为该文本视图的委托。如果需要,UITextFieldDelegates还有一个相应的方法称为textFieldDidBeginEditing:
。 - Peter DeWeeseviewDidLoad
中以编程方式在该类中实例化文本视图后完成它,例如 myTextView.delegate = self
。 - Peter DeWeese-textViewDidBeginEditing
和 -textFieldShouldEndEditing
从未被调用。为什么? - Ben Lu [UIView setAnimationDuration:0.35f]; CGRect frame = self.view.frame;
frame.origin.y = 0;
[self.view setFrame:frame];
[UIView commitAnimations];
} - Erhan DemirciUITableViewController
中也有一个满足相同需求的类;只有在支持低于4.3版本的iOS时才需要。 -(void)textFieldDidBeginEditing:(UITextField *)textField
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.35f];
CGRect frame = self.view.frame;
frame.origin.y = -100;
[self.view setFrame:frame];
[UIView commitAnimations];
}
-(void)textFieldDidEndEditing:(UITextField *)textField
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.35f];
CGRect frame = self.view.frame;
frame.origin.y = 100;
[self.view setFrame:frame];
[UIView commitAnimations];
}
void EditingBegin(UITextField sender)
{
// Height of tallest cell, you can ignore this!
float tableMargin = 70.0f;
float tableHeight = _tableView.Frame.Size.Height;
float keyBoardHeight = KeyboardHeight();
NSIndexPath[] paths = this._tableView.IndexPathsForVisibleRows;
RectangleF rectLast = this._tableView.RectForSection(paths[paths.Length - 1].Section);
RectangleF rectFirst = this._tableView.RectForSection(paths[0].Section);
float lastCellY = rectLast.Y - rectFirst.Y;
if (lastCellY > tableHeight - keyBoardHeight)
{
float diff = lastCellY - (tableHeight - tableMargin - keyBoardHeight);
this._tableView.ContentInset = new UIEdgeInsets(0.0f, 0.0f, diff, 0.0f);
}
float cellPosition = this._tableView.RectForSection(this._section).Y;
if (cellPosition > tableHeight - keyBoardHeight)
{
if (this._tableView.ContentInset.Bottom == 0.0f)
{
float diff = cellPosition - (tableHeight - tableMargin - keyBoardHeight);
this._tableView.ContentInset = new UIEdgeInsets(0.0f, 0.0f, diff, 0.0f);
}
else
{
this._tableView.ScrollToRow(NSIndexPath.FromItemSection(0, this._section), UITableViewScrollPosition.Middle, true);
}
}
}
partial void EditingEnd(UITextField sender)
{
UIView.BeginAnimations(null);
UIView.SetAnimationDuration(0.3f);
this._tableView.ContentInset = new UIEdgeInsets(0.0f, 0.0f, 0.0f, 0.0f);
UIView.CommitAnimations();
}
然后在您的视图控制器类中:
public override void WillAnimateRotation(UIInterfaceOrientation toInterfaceOrientation, double duration)
{
base.WillAnimateRotation(toInterfaceOrientation, duration);
float bottom = this.TableView.ContentInset.Bottom;
if (bottom > 0.0f)
{
if (toInterfaceOrientation == UIInterfaceOrientation.Portrait || toInterfaceOrientation == UIInterfaceOrientation.PortraitUpsideDown)
{
bottom = bottom * UIScreen.MainScreen.Bounds.Width / UIScreen.MainScreen.Bounds.Height;
}
else
{
bottom = bottom * UIScreen.MainScreen.Bounds.Height / UIScreen.MainScreen.Bounds.Width;
}
UIEdgeInsets insets = this.TableView.ContentInset;
this.TableView.ContentInset = new UIEdgeInsets(0.0f, 0.0f, bottom, 0.0f);
}
}
从Peter的答案开始,我在iOS 10.1下使用Swift 3.0开发了以下方法。我正在为textView执行此操作,因此我已经实现了UITextViewDelegate函数textViewDidBeginEditing和textViewDidEndEditing,在其中调整视图的边界。正如您所看到的,我将原点Y值设置为一个小正数以向上滚动,然后返回到0以返回到原始位置。
这是来自我的ViewController的相关代码。您不需要进行动画,但它会增加一些美感。
func textViewDidBeginEditing(_ textView: UITextView)
{
if UIScreen.main.bounds.height < 568 {
UIView.animate(withDuration: 0.75, animations: {
self.view.bounds.origin.y = 60
})
}
}
func textViewDidEndEditing(_ textView: UITextView)
{
if UIScreen.main.bounds.height < 568 {
UIView.animate(withDuration: 0.75, animations: {
self.view.bounds.origin.y = 0
})
}
}
- (void)textViewDidBeginEditing:(UITextField *)textField {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.35f];
CGPoint offset = self.tableView.contentOffset;
offset.y += 200; // You can change this, but 200 doesn't create any problems
[self.tableView setContentOffset:offset];
[UIView commitAnimations];
}
就这样,不需要添加textViewDidEndEditing
方法。
UITextField
或UITextView
必须是控制器的代理。我有一个ScrollView和3个文本字段。我有一个来自我的应用程序的简单代码:
.h文件如下:
#import <UIKit/UIKit.h>
@interface AddContactViewController : UIViewController<UITextFieldDelegate, UIScrollViewDelegate>
@property (nonatomic, retain) NSDictionary *dict_contactDetail;
@property (nonatomic, retain) IBOutlet UILabel *lbl_name;
@property (nonatomic, retain) IBOutlet UITextField *txtField_tel;
@property (nonatomic, retain) IBOutlet UITextField *txtField_address;
@property (nonatomic, retain) IBOutlet UITextField *txtField_email;
@property (nonatomic, retain) IBOutlet UIScrollView *scrollView;
@end
.m 文件:
#import "AddContactViewController.h"
@interface AddContactViewController ()
@end
@implementation AddContactViewController
@synthesize dict_contactDetail;
@synthesize lbl_name, txtField_tel, txtField_email, txtField_address, scrollView;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
// NSLog(@"dict_contactDetail : %@", dict_contactDetail);
UIBarButtonItem * rightButton = [[UIBarButtonItem alloc] initWithTitle:@"Add" style:UIBarButtonSystemItemDone target:self action:@selector(addEmergencyContact:)];
self.navigationItem.rightBarButtonItem = rightButton;
lbl_name.text = [NSString stringWithFormat:@"%@ %@", [dict_contactDetail valueForKey:@"fname"], [dict_contactDetail valueForKey:@"lname"]];
txtField_tel.returnKeyType = UIReturnKeyDone;
txtField_email.returnKeyType = UIReturnKeyDone;
txtField_address.returnKeyType = UIReturnKeyDone;
}
-(void)addEmergencyContact:(id)sender
{
scrollView.frame = CGRectMake(0, 0, 320, 460);
}
#pragma mark - text field delegates
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
if([textField isEqual:txtField_tel])
{
[scrollView setContentOffset:CGPointMake(0, 70)];
scrollView.frame = CGRectMake(0, 0, 320, 210);
}
if([textField isEqual:txtField_address])
{
[scrollView setContentOffset:CGPointMake(0, 140)];
scrollView.frame = CGRectMake(0, 0, 320, 210);
}
if([textField isEqual:txtField_email])
{
[scrollView setContentOffset:CGPointMake(0, 210)];
scrollView.frame = CGRectMake(0, 0, 320, 210);
}
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
scrollView.frame = CGRectMake(0, 0, 320, 460);
[textField resignFirstResponder];
return YES;
}
@end