0

메신저 내 전체 코드를 여기에 게시하고 있습니다. 문제는 처음에 app과 viewcontroller를로드 할 때입니다. 그것은 완전히 작동합니다. 두 텍스트 필드를 탭하면 스크롤 뷰가 위로 올라가고 키보드는 현재 텍스트 필드 아래에 있습니다. 그런 다음 텍스트 필드를 두드리는 경우 ..보기를 위로 이동하고 텍스트 필드를 다시 잡아 당기는 것은 더 이상하지 않습니다. 또한 nav 컨트롤러를 통해 돌아가서이 viewcontroller를 다시로드하면 아무 일도하지 않을 것입니다. 그것은 더 이상 스크롤을하지 않습니다. (텍스트 필드를 밀어 넣지 않고 키보드가 더 이상 보이지 않습니다.) ...UiscrollView를 통해 UITextField로 스크롤하면 처음으로 버그가 발생합니다.

import UIKit 
import Parse 
import Alamofire 
import SwiftyJSON 

class VCreservacion: UIViewController,UITextFieldDelegate,UIScrollViewDelegate { 

    var SUCURSALID = 0 
    var EMP_NOMBRE = "" 
    var DIRECCION = "" 
    var PROVINCIA = "" 
    var RESTID = 20556 

    @IBOutlet var lbl_empresa: UILabel! 
    @IBOutlet var lbl_direccion: UILabel! 
    @IBOutlet var lbl_step: UILabel! 
    @IBOutlet var cantidadView: UIView! 
    @IBOutlet var datePicker: UIDatePicker! 
    @IBOutlet var btn_reservar: UIButton! 
    @IBOutlet var stackView: UIStackView! 
    @IBOutlet var scrollView: UIScrollView! 
    @IBOutlet var txtComentario: UITextField! 
    @IBOutlet weak var txtCelular: UITextField! 
    var activeField: UITextField? 

    var steps = 2 


    // MARK: RESERVE ACTION 
    @IBAction func ReserveAction(_ sender: UIButton) { 
     print("Reservando...") 

     // For date formater 
     var dateformated = "" 
     var dateformated2 = "" 
     let formatter = DateFormatter() 
     formatter.dateFormat = "yyyy-MM-dd HH:mm:ss" 
     //formatter.timeZone = NSTimeZone(forSecondsFromGMT: 0) as TimeZone! 


     dateformated = formatter.string(from: datePicker.clampedDate) 
     dateformated2 = formatter.string(from: datePicker.date) 
     print(dateformated) 
     print(dateformated2) 
     let cart = Cart.sharedInstance 

     guard let user = PFUser.current() else { 
      cart.showAlertView("Login", message: "Debes estar logeado para poder reservar.") 
      return 
     } 

     Alamofire.request("URL String", parameters: ["qty": "\(steps)","sucursalid":"\(self.SUCURSALID)","restid":"\(RESTID)","comment":"\(txtComentario.text!)","phone":"\(txtCelular.text!)","datetime":"\(dateformated)","action":"request","userid":"\(user.objectId!)"]).authenticate(usingCredential: cart.credential).responseJSON() { 

      response in 

      if (response.error != nil) { 

       print(response.error.debugDescription) 
       print(response.request) 
       cart.showAlertView("Error", message: "there was an error.") 

      } 

      if(response.result.value != nil) { 

       let json = JSON(response.result.value!); 

       print(json); 


       let success:Bool = json["success"].boolValue 
       let error: Bool = json["error"].boolValue 

       if(success) { 
        print("con exito") 
        let alert = UIAlertController(title: "Reserva Enviada", message: "Tu reserva ha sido enviada y será revisada por el establecimiento", preferredStyle: .alert) 
        let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default) { 
         UIAlertAction in 

         // Get the previous Controller. 
         let targetController: UIViewController = (self.navigationController?.viewControllers[self.navigationController!.viewControllers.count - 3])! 

         // And go to that Controller 
         self.navigationController?.popToViewController(targetController, animated: true) 

        } 

        alert.addAction(okAction) 
        self.present(alert,animated:true) 


       } 
      } 

     } 



    } 



    @IBAction func stepperValue(_ sender: UIStepper) { 

     self.lbl_step.text = Int(sender.value).description 
     steps = Int(sender.value) 

    } 

    override func viewWillAppear(_ animated: Bool) { 
     super.viewWillAppear(animated) 
     registerForKeyboardNotifications() 
     self.scrollView.delegate = self 
    } 

    override func viewWillDisappear(_ animated: Bool) { 
     super.viewWillDisappear(animated) 
     deregisterFromKeyboardNotifications() 
     self.scrollView.delegate = nil 
    } 


    // MARK: Viewdidload 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     // enable scroll on scrollview 
     self.scrollView.isScrollEnabled = true 

     // step label initial value 2 
     self.lbl_step.text = "2" 

     // Get celular or phone 

     if (Cart.sharedInstance.User_celular != "") { 
      txtCelular.text = Cart.sharedInstance.User_celular 
     } else { 
      txtCelular.text = Cart.sharedInstance.User_phone 
     } 


     let nearesthour = Date().nearestHour() 
     self.datePicker.minimumDate = nearesthour 
     self.txtComentario.delegate = self 
     self.txtCelular.delegate = self 
     self.txtCelular.tag = 20 
     self.scrollView.delegate = self 


     // tap gesture recognizer 

     let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:))) 
     self.scrollView.addGestureRecognizer(tap) 


     print("el enarest hour es \(nearesthour as Date?) y el date normal es \(Date())") 

     self.btn_reservar.layer.cornerRadius = 10 
     self.cantidadView.layer.cornerRadius = 10 

     self.lbl_empresa.text = EMP_NOMBRE 
     self.lbl_direccion.text = DIRECCION 

     /* 
     print("VC Reservacion") 
     print("SUCURSAL \(SUCURSALID) ") 
     print("EMP NOMBRE " + EMP_NOMBRE) 
     print("DIRECCION " + DIRECCION) 
     */ 


    } 

    // MARK: TEXTFIELD STUFF 

    func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool { 
     self.activeField = textField 
     return true 
    } 
    /* 
    func textFieldDidBeginEditing(_ textField: UITextField) { 
     self.activeField = textField 
    } 
    */ 


    func textFieldDidEndEditing(_ textField: UITextField) { 

     activeField = nil 

    } 




    func registerForKeyboardNotifications(){ 
     //Adding notifies on keyboard appearing 
     NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), 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) 
    } 

    @objc func keyboardWasShown(notification: NSNotification){ 
     //Need to calculate keyboard exact size due to Apple suggestions 

     print(" Keyboaard shown") 


     var info = notification.userInfo! 
     let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size 
     print(" el keyboardsize is \(keyboardSize)") 
     let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize!.height + 80, 0.0) 

     self.scrollView.contentInset = contentInsets 
     self.scrollView.scrollIndicatorInsets = contentInsets 

     var aRect : CGRect = self.view.frame 
     print("VIEW COMPLETE FRAME IS \(aRect)") 
     print("KEYBOARD FRAME HEIGHT \(keyboardSize!.height)") 
     aRect.size.height -= keyboardSize!.height 
     print("FRAME MENOS KEYBOARD ES \(aRect)") 

     print("SCROLLVIEW CONTENT \(self.scrollView.contentSize)") 
     if let activeField = self.activeField { 

      print("ACTIVEFIELD FRAME ORIGIN \(activeField.frame.origin) ") 
      print("Active field is textfield tag is \(activeField.tag)") 

      // if (!aRect.contains(activeField.frame.origin)){ 
      print("arect Does Not contains activeField") 
      self.scrollView.scrollRectToVisible(activeField.frame, animated: true) 
      print("TEXTFIELD FRAME ES \(activeField.frame)") 
      print(" SCROLLVIEW CONTENT \(self.scrollView.contentSize)") 
      //} 
     } 


    } 

    @objc func keyboardWillBeHidden(notification: NSNotification){ 
     //Once keyboard disappears, restore original positions 
     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 
     self.activeField = nil 
     self.view.endEditing(true) 
     self.scrollView.isScrollEnabled = false 

    } 


    @objc func handleTap(_ sender: UITapGestureRecognizer) { 
     self.view.endEditing(true) 
     print("Tap") 

    } 


    func textFieldShouldReturn(_ textField: UITextField) -> Bool { 
     self.view.endEditing(true) 
     return false 
    } 


    override func viewDidLayoutSubviews() { 
     super.viewDidLayoutSubviews() 
     scrollView.contentSize = CGSize(width: view.frame.width, height: view.frame.height) 
     print(" SCROLLVIEW CONTENT AFTER SUBVIEWS \(self.scrollView.contentSize)") 
    } 


    /* // NOT WORKING BECAUSE OF UISCROLLVIEW IN PLACE, MUST USE UITAPGESTURE RECOGNIZER 
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
    self.view.endEditing(true) 
    self.activeField?.resignFirstResponder() 
    } 
    */ 


} 

답변

1

나는 같은 문제가있었습니다. 외관상으로는 키보드의 크기를 바꾸는 변화가있다. 내가 바꿨다 UIKeyboardFrameBeginUserInfoKey to UIKeyboardFrameEndUserInfoKey 그리고 다시 작동하게했다.

다음은 텍스트 필드가

을 누를 때 뷰를 이동
@objc func keyboardWasShown(notification: NSNotification){ 
    self.scrollView.isScrollEnabled = true 
    var info = notification.userInfo! 
    let keyboardSize = (info[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.size 
    let contentInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize!.height, 0.0) 

    self.scrollView.contentInset = contentInsets 
    self.scrollView.scrollIndicatorInsets = contentInsets 

    var aRect : CGRect = self.view.frame 
    guard let kbHeight = keyboardSize?.height else{return} 
    aRect.size.height -= kbHeight 
    if let activeField = self.activeTextField { 
     if (!aRect.contains(activeField.frame.origin)){ 
      self.scrollView.scrollRectToVisible(activeField.frame, animated: true) 
     } 
    } 
} 
+0

HUMM이 .. 나를 그렇게 해보자 내 정확한 코드입니다! –

+0

완벽한 !!! 고마워요 !!!! IT는 일했다 !!!! –