【发布时间】:2018-08-20 03:37:56
【问题描述】:
我有一个ViewController,其中有一个ScrollView,ScrollView 内有一个视图。视图由多个TextFields 组成。还有一个NavigationContoller。当我单击TextField 并再次单击屏幕时,键盘会消失,但视图会向上移动,并且一些文本字段会隐藏。请帮我解决这个问题
这是我的代码:
class EODViewController: UIViewController, UIScrollViewDelegate, UITextFieldDelegate {
@IBOutlet weak var views: UIView!
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var inc50: UITextField!
@IBOutlet weak var out50: UITextField!
@IBOutlet weak var dec50: UITextField!
@IBOutlet weak var savebutton: UIButton!
var activeField: UITextField?
let button = UIButton(type: UIButtonType.custom)
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.title = "Before EOD"
//For Back button task
self.navigationItem.hidesBackButton = true
//to dismiss keyboard on click anywhere on screen
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(ViewController.dismissKeyboard))
view.addGestureRecognizer(tap)
// to get keyboard notifications
registerForKeyboardNotifications()
//textfield delegates
self.inc50.delegate = self
self.out50.delegate = self
self.end50.delegate = self
self.dec50.delegate = self
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let allowedCharacters = CharacterSet.decimalDigits
let characterSet = CharacterSet(charactersIn: string)
return allowedCharacters.isSuperset(of: characterSet)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
self.out50.resignFirstResponder()
self.end50.resignFirstResponder()
self.str50.resignFirstResponder()
self.inc50.resignFirstResponder()
self.dec50.resignFirstResponder()
if textField == self.out50 {
if self.out50.text?.isEmpty ?? true
{
self.out50.attributedPlaceholder = NSAttributedString(string: "Enter Value", attributes: [NSForegroundColorAttributeName : UIColor.red])
return false
}
if end50.isUserInteractionEnabled == false
{
if checkValue(textvalue: out50, deno: 50, errorText: error50) == false
{
return false
}
if error50.text != "Enter multiple of 50"
{
editProcessBeforeoneOut(str: str50, inc: inc50, dec: dec50, out: out50, end: end50,terror: error50)
self.out100.becomeFirstResponder()
}
}
else{
self.end50.becomeFirstResponder()
if error50.isHidden == false
{
}
}
}
if textField == self.str50
{
if self.str50.text?.isEmpty ?? true
{
self.str50.attributedPlaceholder = NSAttributedString(string: "Enter Value", attributes: [NSForegroundColorAttributeName : UIColor.red])
return false
}
if checkValue(textvalue: str50, deno: 50, errorText: error50) == false
{
self.str50.becomeFirstResponder()
return false
}
if error50.text != "Enter multiple of 50"
{
editProcessBeforeoneOut(str: str50, inc: inc50, dec: dec50, out: out50, end: end50,terror: error50)
self.inc50.becomeFirstResponder()
}
}
if textField == self.inc50
{
if self.inc50.text?.isEmpty ?? true
{
self.inc50.attributedPlaceholder = NSAttributedString(string: "Enter Value", attributes: [NSForegroundColorAttributeName : UIColor.red])
return false
}
if checkValue(textvalue: str50, deno: 50, errorText: error50) == false
{
return false
}
if error50.text != "Enter multiple of 50"
{
editProcessBeforeoneOut(str: str50, inc: inc50, dec: dec50, out: out50, end: end50,terror: error50)
self.dec50.becomeFirstResponder()
}
}
return true
}
func validate() -> Bool
{
var valid : Bool = true
if self.str50.text?.isEmpty ?? true
{
str50.attributedPlaceholder = NSAttributedString(string: "Enter value", attributes: [NSForegroundColorAttributeName : UIColor.red])
valid = false
}
return valid
}
func registerForKeyboardNotifications(){
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
func deregisterFromKeyboardNotifications(){
//Removing notifies on keyboard appearing
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
func keyboardWasShown(notification: NSNotification){
//Need to calculate keyboard exact size due to Apple suggestions
self.scrollView.isScrollEnabled = true
var info = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize!.height, 0.0)
self.scrollView.contentInset = contentInsets
self.scrollView.scrollIndicatorInsets = contentInsets
var aRect : CGRect = self.view.frame
aRect.size.height -= keyboardSize!.height
if let activeField = self.activeField {
if (!aRect.contains(activeField.frame.origin)){
// self.scrollView.scrollRectToVisible(activeField.frame, animated: true)
}
}
}
func keyboardWillBeHidden(notification: NSNotification){
//Once keyboard disappears, restore original positions
self.view.endEditing(true)
self.scrollView.isScrollEnabled = true
}
func textFieldDidBeginEditing(_ textField: UITextField){
activeField = textField
NotificationCenter.default.addObserver(self, selector: #selector(EODViewController.keyboardWillShow(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
}
func textFieldDidEndEditing(_ textField: UITextField){
activeField = nil
}
func dismissKeyboard() {
view.endEditing(true)
}
func back(sender: UIBarButtonItem) {
// Perform your custom actions
// ...
// Go back to the previous ViewController
_ = navigationController?.popViewController(animated: true)
}
override func viewWillAppear(_ animated: Bool) {
button.setTitle("Return", for: UIControlState())
button.setTitleColor(UIColor.black, for: UIControlState())
button.frame = CGRect(x: 0, y: 163, width: 106, height: 53)
button.adjustsImageWhenHighlighted = false
button.addTarget(self, action: #selector(ViewController.Done(_:)), for: UIControlEvents.touchUpInside)
}
func keyboardWillShow(_ note : Notification) -> Void{
DispatchQueue.main.async { () -> Void in
self.button.isHidden = false
self.scrollView.isScrollEnabled = true
var info = note.userInfo!
let keyBoardWindow = UIApplication.shared.windows.last
self.button.frame = CGRect(x: 0, y: (keyBoardWindow?.frame.size.height)!-53, width: 106, height: 53)
keyBoardWindow?.addSubview(self.button)
keyBoardWindow?.bringSubview(toFront: self.button)
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize!.height, 0.0)
self.scrollView.contentInset = contentInsets
self.scrollView.scrollIndicatorInsets = contentInsets
var aRect : CGRect = self.view.frame
aRect.size.height -= keyboardSize!.height
if let activeField = self.activeField {
if (!aRect.contains(activeField.frame.origin)){
self.scrollView.scrollRectToVisible(activeField.frame, animated: true)
}
}
UIView.animate(withDuration: (((note.userInfo! as NSDictionary).object(forKey: UIKeyboardAnimationCurveUserInfoKey) as AnyObject).doubleValue)!, delay: 0, options: UIViewAnimationOptions.curveEaseIn, animations: { () -> Void in
self.view.frame = self.view.frame.offsetBy(dx: 0, dy: 0)
}, completion: { (complete) -> Void in
})
}
}
func Done(_ sender : UIButton){
DispatchQueue.main.async { () -> Void in
self.textFieldShouldReturn(self.activeField!)
}
}
}
【问题讨论】:
-
提供一些截图
-
向我们展示您的代码逻辑。
-
把你的概念从ScrollView换成uitableview,很容易搞定
-
显示你尝试过的代码
-
@Anbu.karthik 我添加了代码
标签: ios swift3 uiscrollview