找到了UITextFields
的{{1}}的Apple文档,其中详细说明了如何制作该文档,以便UITextField
内的UIScrollView
可以向上移动,以便用户可以查看他们的输入。但是,每当我尝试实现它时,行为都不会如所描述的那样。无论您选择编辑哪个UITextField
,它都不会执行任何操作或将所有内容向下移动。
这是我的代码,有人可以诊断它吗?:
#import "FourthViewController.h"
@import Firebase;
@import FirebaseAuth;
@import FirebaseDatabase;
@interface FourthViewController ()
{
UITextField *activeField;
}
@property (strong, nonatomic) FIRDatabaseReference *ref;
@property (weak, nonatomic) IBOutlet UIButton *logoutButton;
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property (readonly, nonatomic, nullable) FIRApp *app;
@property (readonly, strong, nonatomic, nullable) FIRUser *currentUser;
@property(weak, nonatomic) NSArray *countryArray;
@property (weak, nonatomic) IBOutlet UITextField *usernameEntry;
@property (weak, nonatomic) IBOutlet UITextField *forenameEntry;
@property (weak, nonatomic) IBOutlet UITextField *surnameEntry;
@property (weak, nonatomic) IBOutlet UITextField *emailAddressEntry;
@property (weak, nonatomic) IBOutlet UITextField *countryEntry;
@property (weak, nonatomic) IBOutlet UITextField *homeAddressEntry;
@property (weak, nonatomic) IBOutlet UIButton *applyChangesButton;
@property (weak, nonatomic) IBOutlet UIImageView *profilePictureEntry;
@property (weak, nonatomic) IBOutlet UILabel *emailValidationCheck;
@property (weak, nonatomic) IBOutlet UIPickerView *countrySelector;
@end
@implementation FourthViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.ref = [[FIRDatabase database] reference];
FIRUser *user = [FIRAuth auth].currentUser;
if (user)
{
[[[[_ref child: @"Users"] child:user.uid] child:@"Username"] observeSingleEventOfType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot *snapshot)
{
if (snapshot.exists)
{
_usernameEntry.text = snapshot.value;
}
}];
_emailAddressEntry.text = user.email;
}
_countrySelector.delegate = self;
_countrySelector.dataSource = self;
self.logoutButton.layer.cornerRadius= 8;
self.logoutButton.layer.borderWidth = 1.5f;
self.logoutButton.layer.borderColor = [UIColor whiteColor].CGColor;
[_logoutButton addTarget:self action:@selector(logoutButtonHighlightBorder) forControlEvents:UIControlEventTouchDown];
[_logoutButton addTarget:self action:@selector(logoutButtonUnhighlightBorder) forControlEvents:UIControlEventTouchUpInside];
[_logoutButton addTarget:self action:@selector(logoutButtonUnhighlightBorder) forControlEvents:UIControlEventTouchDragExit];
self.applyChangesButton.layer.cornerRadius = 8;
_countrySelector.layer.cornerRadius = 8;
NSLocale *locale = [NSLocale currentLocale];
NSArray *countryArray = [NSLocale ISOCountryCodes];
NSMutableArray *sortedCountryArray = [[NSMutableArray alloc] init];
for (NSString *countryCode in countryArray)
{
NSString *displayNameString = [locale displayNameForKey:NSLocaleCountryCode value:countryCode];
[sortedCountryArray addObject:displayNameString];
}
[sortedCountryArray sortUsingSelector:@selector(localizedCompare:)];
}
- (IBAction)applyChanges:(UIButton *)sender
{
NSString *userID = [FIRAuth auth].currentUser.uid;
NSString* username = _usernameEntry.text;
[[[_ref child:@"Users"] child:userID] setValue:@{@"Username": username}];
[[FIRAuth auth].currentUser updateEmail:_emailAddressEntry.text
completion:^(NSError * _Nullable error)
{
if(error)
{
[_emailValidationCheck setTextColor:[UIColor redColor]];
_emailValidationCheck.text = @"Email Address modification was unsuccessful";
}
else
{
[_emailValidationCheck setTextColor:[UIColor greenColor]];
_emailValidationCheck.text = @"Email Address modification was successful";
}
}];
}
- (IBAction)logout:(UIButton *)sender
{
NSError *signOutError;
BOOL status = [[FIRAuth auth] signOut:&signOutError];
if (!status)
{
NSLog(@"Error signing out: %@", signOutError);
}
else
{
NSLog(@"Successfully Signout");
}
}
- (NSInteger)numberOfComponentsInPickerView:(nonnull UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(nonnull UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return _countryArray.count;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return _countryArray[row];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
_countryEntry.text = _countryArray[row];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
- (void)logoutButtonHighlightBorder
{
_logoutButton.layer.borderColor = [UIColor colorWithRed:0.61 green:0.00 blue:0.02 alpha:1.0].CGColor;
}
- (void)logoutButtonUnhighlightBorder
{
_logoutButton.layer.borderColor = [UIColor whiteColor].CGColor;
}
- (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:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
CGRect bkgndRect = activeField.superview.frame;
bkgndRect.size.height += kbSize.height;
[activeField.superview setFrame:bkgndRect];
[_scrollView setContentOffset:CGPointMake(0.0, activeField.frame.origin.y-kbSize.height) animated:YES];
}
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
_scrollView.contentInset = contentInsets;
_scrollView.scrollIndicatorInsets = contentInsets;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
activeField = textField;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
activeField = nil;
}
更新代码:
#import "FourthViewController.h"
@import Firebase;
@import FirebaseAuth;
@import FirebaseDatabase;
@interface FourthViewController ()
{
UITextField *activeField;
}
@property (strong, nonatomic) FIRDatabaseReference *ref;
@property (weak, nonatomic) IBOutlet UIButton *logoutButton;
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property (readonly, nonatomic, nullable) FIRApp *app;
@property (readonly, strong, nonatomic, nullable) FIRUser *currentUser;
@property(weak, nonatomic) NSArray *countryArray;
@property (weak, nonatomic) IBOutlet UITextField *usernameEntry;
@property (weak, nonatomic) IBOutlet UITextField *forenameEntry;
@property (weak, nonatomic) IBOutlet UITextField *surnameEntry;
@property (weak, nonatomic) IBOutlet UITextField *emailAddressEntry;
@property (weak, nonatomic) IBOutlet UITextField *countryEntry;
@property (weak, nonatomic) IBOutlet UITextField *homeAddressEntry;
@property (weak, nonatomic) IBOutlet UIButton *applyChangesButton;
@property (weak, nonatomic) IBOutlet UIImageView *profilePictureEntry;
@property (weak, nonatomic) IBOutlet UILabel *emailValidationCheck;
@property (weak, nonatomic) IBOutlet UIPickerView *countrySelector;
@end
@implementation FourthViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.ref = [[FIRDatabase database] reference];
FIRUser *user = [FIRAuth auth].currentUser;
[self registerForKeyboardNotifications];
if (user)
{
[[[[_ref child: @"Users"] child:user.uid] child:@"Username"] observeSingleEventOfType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot *snapshot)
{
if (snapshot.exists)
{
_usernameEntry.text = snapshot.value;
}
}];
_emailAddressEntry.text = user.email;
}
_countrySelector.delegate = self;
_countrySelector.dataSource = self;
self.logoutButton.layer.cornerRadius= 8;
self.logoutButton.layer.borderWidth = 1.5f;
self.logoutButton.layer.borderColor = [UIColor whiteColor].CGColor;
[_logoutButton addTarget:self action:@selector(logoutButtonHighlightBorder) forControlEvents:UIControlEventTouchDown];
[_logoutButton addTarget:self action:@selector(logoutButtonUnhighlightBorder) forControlEvents:UIControlEventTouchUpInside];
[_logoutButton addTarget:self action:@selector(logoutButtonUnhighlightBorder) forControlEvents:UIControlEventTouchDragExit];
self.applyChangesButton.layer.cornerRadius = 8;
_countrySelector.layer.cornerRadius = 8;
NSLocale *locale = [NSLocale currentLocale];
NSArray *countryArray = [NSLocale ISOCountryCodes];
NSMutableArray *sortedCountryArray = [[NSMutableArray alloc] init];
for (NSString *countryCode in countryArray)
{
NSString *displayNameString = [locale displayNameForKey:NSLocaleCountryCode value:countryCode];
[sortedCountryArray addObject:displayNameString];
}
[sortedCountryArray sortUsingSelector:@selector(localizedCompare:)];
}
- (IBAction)applyChanges:(UIButton *)sender
{
NSString *userID = [FIRAuth auth].currentUser.uid;
NSString* username = _usernameEntry.text;
[[[_ref child:@"Users"] child:userID] setValue:@{@"Username": username}];
[[FIRAuth auth].currentUser updateEmail:_emailAddressEntry.text
completion:^(NSError * _Nullable error)
{
if(error)
{
[_emailValidationCheck setTextColor:[UIColor redColor]];
_emailValidationCheck.text = @"Email Address modification was unsuccessful";
}
else
{
[_emailValidationCheck setTextColor:[UIColor greenColor]];
_emailValidationCheck.text = @"Email Address modification was successful";
}
}];
}
- (IBAction)logout:(UIButton *)sender
{
NSError *signOutError;
BOOL status = [[FIRAuth auth] signOut:&signOutError];
if (!status)
{
NSLog(@"Error signing out: %@", signOutError);
}
else
{
NSLog(@"Successfully Signout");
}
}
- (NSInteger)numberOfComponentsInPickerView:(nonnull UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(nonnull UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return _countryArray.count;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return _countryArray[row];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
_countryEntry.text = _countryArray[row];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
- (void)logoutButtonHighlightBorder
{
_logoutButton.layer.borderColor = [UIColor colorWithRed:0.61 green:0.00 blue:0.02 alpha:1.0].CGColor;
}
- (void)logoutButtonUnhighlightBorder
{
_logoutButton.layer.borderColor = [UIColor whiteColor].CGColor;
}
- (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];
CGRect kbFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGFloat offset = CGRectGetMaxY(activeField.frame) - CGRectGetMinY(kbFrame);
[_scrollView setContentOffset:CGPointMake(0.0, offset) animated:YES];
}
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
_scrollView.contentInset = contentInsets;
_scrollView.scrollIndicatorInsets = contentInsets;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
activeField = textField;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
activeField = nil;
}
@end
答案 0 :(得分:0)
您要做的是将textField的下边缘直接移到键盘上方。这是通过正确调整scrollView的contentOffset来完成的。你已经看到了几乎正确的事情。唯一可能出错的是你改变CGRect bkgndRect = activeField.superview.frame;
不必要的东西。您可以尝试以下方法,其中minY / maxY是frame.origin.y /(frame.origin.y + frame.size.height)。
- (void)keyboardWillShow:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGRect kbFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGFloat offset = CGRectGetMaxY(activeTextField.frame) - CGRectGetMinY(kbFrame)
_scrollView.contentOffset = CGPointMake(0.0, offset);
}
- (void)keyboardWillHide:(NSNotification*)aNotification
{
_scrollView.contentOffset = CGPointZero;
}
此外,您还可以检查计算的偏移量是否> 0,因为在这种情况下,文本字段已经在键盘上方。
当键盘被隐藏时,我想我从来没有更新滚动指示器插图。只需重置滚动视图的内容偏移量即可。
如果有一天你需要这个代码用于Swift 4 ++ - 这里也是一个例子,不使用自动布局。实际上,我测试了这段代码并且有效:
class ViewController: UIViewController {
var willShow: NSObjectProtocol?
var willHide: NSObjectProtocol?
let scroll = UIScrollView()
let txt = UITextField()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
scroll.frame = view.bounds
scroll.translatesAutoresizingMaskIntoConstraints = true
view.addSubview(scroll)
txt.frame = CGRect(x: 0, y: scroll.bounds.height-100, width: scroll.bounds.width, height: 50)
txt.text = "Hello World"
txt.backgroundColor = .lightGray
txt.translatesAutoresizingMaskIntoConstraints = true
scroll.addSubview(txt)
willShow = NotificationCenter.default.addObserver(forName: .UIKeyboardWillShow, object: nil, queue: .main) { (note) in
let kbFrame = note.userInfo?[UIKeyboardFrameEndUserInfoKey] as? CGRect ?? .zero
self.scroll.contentOffset = CGPoint(x: 0, y: self.txt.frame.maxY - kbFrame.minY )
}
willHide = NotificationCenter.default.addObserver(forName: .UIKeyboardWillHide, object: nil, queue: .main) { (note) in
self.scroll.contentOffset = .zero
}
view.addGestureRecognizer(UITapGestureRecognizer(target: txt, action: #selector(resignFirstResponder)))
}
}
希望有所帮助