2017-02-23 6 views
1

이 문제를 검색 한 결과 & 조각을 발견했지만 실제 복제본은 아닙니다.UIScrollView의 대화 형 해제로 이동하는 UITextView가있는 UIView

UITextView를 만들려고합니다. UIView에 캡슐화되어 있습니다. UITextView는 콘텐츠를 기반으로 키의 높이를 동적으로 변경합니다. 이는 자동 레이아웃과 UITextView에서 스크롤을 사용하지 않도록 설정하면 쉽게 해결됩니다.

그러면 UITextView가 UIScrollView에서 대화 형으로 설정된 속성을 설정하여 해제하거나 해제하지 않을 수도있는 키보드로 대화식으로 이동하려고합니다.

이 일반적인 동작은 텍스트 입력이 iOS 메시지에서 작동하는 방식을 모방합니다. 대화 형 해제 키보드로 멋지게 스크롤하고 필요할 때 높이가 커집니다.

지금까지 전체보기를 차지하는 UITableView와 텍스트보기를 캡슐화하는 다른보기를 만들려고 시도했습니다.이보기는 가로로 구속되어 있으며보기 컨트롤러보기의 맨 아래에 고정되어 있습니다. 높이는 빠져 있지만 자동 레이아웃은 내부의 UITextView를 통해 본질적으로 크기를 결정할 수 있습니다.

와 같이 캡슐보기를 얻을하기위한 시도로, 지금

enter image description here

:

enter image description here

이 키보드를 산란하지 않고 시뮬레이터 지금까지 너무 좋아하면서 작동 키보드에 고정해야합니다.보기 컨트롤러에서 입력 액세서리보기로 사용하려고 시도 했으므로 먼저보기 컨트롤러의보기 계층 구조에서 제거해야합니다. 난 정확히 어디에 (키보드 표시 알림을 표시합니다, 텍스트보기를 대리자 등 편집을 시작해야합니다 확실하지 않아요?) 지금까지 시도한 모든보기로 키보드에 대한 액세서리보기로 누락 된중인 결과 (if 키보드가 실제로 표시됩니다). 이처럼

: 나는 여러 가지 애니메이션/변환을 추가 할 수 있기 때문에 이미 존재하는 뷰에서 새 뷰를 생성 시도 주저

import UIKit 

class ViewController: UIViewController { 

    // MARK: - Outlets 
    @IBOutlet weak var inputTextview: UITextView! 
    @IBOutlet weak var genericInputContainer: UIView! 

    // MARK: - Properites 
    fileprivate var shouldAddInputContainerAsAccessory = false 
    override var inputAccessoryView: UIView? { 
     if shouldAddInputContainerAsAccessory { 
      return genericInputContainer 
     } 
     return nil 
    } 

    // MARK: - Actions 
    @objc fileprivate func keyboardWillShow(sender: Notification) { 
    } 

    fileprivate func observeNotifications() { 
     let keyboardWillShowAction = #selector(keyboardWillShow(sender:)) 
     NotificationCenter.default.addObserver(
      self, 
      selector: keyboardWillShowAction, 
      name: Notification.Name.UIKeyboardWillShow, 
      object: nil) 
    } 

    // MARK: - Lifecycle 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     observeNotifications() 
     inputTextview.delegate = self 
    } 
} 

extension ViewController: UITextViewDelegate { 
    func textViewShouldBeginEditing(_ textView: UITextView) -> Bool { 
     genericInputContainer.removeFromSuperview() 
     shouldAddInputContainerAsAccessory = true 
     return true 
    } 

    func textViewShouldEndEditing(_ textView: UITextView) -> Bool { 
     shouldAddInputContainerAsAccessory = false 
     return true 
    } 
} 

:에서

enter image description here

(텍스트보기 옆에있는) 캡슐화보기 내의 요소로 이동합니다.

+0

나는 다음 뷰 컨트롤러의 뷰 viewDidAppear''에서 첫 번째로 반응하기 위해선, 텍스트 필드 뷰 컨트롤러의 뷰의'inputAccessoryView'와 뷰를 만들 것입니다. 'canBecomeFirstResponder'에서'true'를 리턴하기 위해'UIView'를 서브 클래스해야하고, 스토리 보드에서 뷰 컨트롤러의 루트 뷰의 클래스를 서브 클래스로 설정해야합니다. 뷰가 첫 번째 응답자가 될 때 시스템 자체에서 추가하기 때문에 이렇게하면 뷰 계층에 텍스트 필드가 추가 된 뷰를 추가하지 않을 것입니다. – dan

+0

@Fred 당신은 이것에 대한 해결책을 찾지 못했습니까? 나는 같은 배에 타고있다. – Ricky

답변

0

키보드 입력을 제거한 다음 키보드 액세서리에 지정하는 대신 키보드 관찰자를 사용하여 키보드가 나타날 때 높이를 얻은 다음 텍스트 입력의 하단 구속 조건을 조정하십시오. 이 같은 키보드 높이를 얻을 수 있습니다 :

func keyboardWillShow(notification: NSNotification) { 
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue { 
     self.keyboardHeight = keyboardSize.height 
     //debugPrint(keyboardHeight) 
    } 
} 
+0

내가 알고있는 알림도 키보드와 함께 해고됩니다 (위아래로 움직일 수 있고 전혀 닫히지 않을 수 있음). –

+0

이것은 사용자가 UIKeyboardWillShow 옵저버에 지정하는 기능입니다. 또한 키보드를 숨길 때 UIKeyboardWillHide 옵 저버에 func을 지정하여 맨 아래 구속 조건을 재설정 할 수 있습니다. – rmp

+1

사용자가 대화 형 비헤이비어 동작을 이해하고 있다고 생각하지 않습니다. 사용자가 스크롤보기에서 드래그하여 키보드를 위아래로 움직일 수 있으며, 그 시점에서 입력보기가 함께 이동되도록하고 싶습니다. –