2016-10-03 2 views
5

Письмо с нуля растет UITextView в моем swift приложении. я поставил textView на view, как это:странное позиционирование курсора в UITextView

enter image description here

это прямо над клавиатурой.

textView имеет ограничения, прикрепленные к view: leading, bottom, top и trailing, все равны = 4.

view имеет следующие ограничения:

trailing, leading, bottom, top и height

Height это отдушина в моем коде. Я проверяю, сколько строк находятся в textView и на основе этого я модифицирования height:

func textViewDidChange(textView: UITextView) { //Handle the text changes here 
    switch(textView.numberOfLines()) { 
    case 1: 
     heightConstraint.constant = 38 
     break 
    case 2: 
     heightConstraint.constant = 50 
     break 
    case 3: 
     heightConstraint.constant = 70 
     break 
    case 4: 
     heightConstraint.constant = 90 
     break 
    default: 
     heightConstraint.constant = 90 
     break 
    } 
} 

Количество строк выше вычисленных этим расширением:

extension UITextView{ 

    func numberOfLines() -> Int{ 
     if let fontUnwrapped = self.font{ 
      return Int(self.contentSize.height/fontUnwrapped.lineHeight) 
     } 
     return 0 
    } 
} 

Начальная высота textView является 38. Исходный размер шрифта в textView: 15.

Теперь он работает хорошо, когда пользователь начинает вводить новую строку, но textView не задан в пределах полной границы вида. Я имею в виду, что тот факт, что это выглядит следующим образом:

enter image description here

и он должен выглядеть следующим образом:

enter image description here

Почему этот дополнительный пробел добавляется, и как можно Я избавлюсь от этого?

В настоящее время, когда появляется новая строка, это пробел, но когда пользователь прокручивает textView, чтобы центрировать текст и избавиться от пробела - он ушел навсегда, пользователь не может прокручивать его снова, так что белая линия здесь. Так что для меня это выглядит как проблема с освежающим контентом, но, может быть, вы знаете лучше - можете ли вы дать мне несколько советов?

+0

я не знаю точно, по моей догадке меняющегося ** не ScrollingEnabled к NO ** может работать .. – Gokul

+0

хммы @Gokul может быть, это поможет, но мне нужен '' scrollingEnabled' к true', потому что если есть более 4 строк текста, тогда 'textView' больше не растет, и пользователь может прокручивать содержимое внутри него ... – user3766930

+0

Вы создали приложение для чата? –

ответ

3

Вот немного другой подход, который я использую в разделе комментариев одного из приложений, которые я разрабатываю. Это очень похоже на поле ввода приложения Facebook Messenger iOS. Изменены названия продуктов, соответствующие тем, которые указаны в вашем вопросе.

//Height constraint outlet of view which contains textView. 
@IBOutlet weak var heightConstraint: NSLayoutConstraint! 
@IBOutlet weak var textView: UITextView! 

//Maximum number of lines to grow textView before enabling scrolling. 
let maxTextViewLines = 5 
//Minimum height for textViewContainer (when there is no text etc.) 
let minTextViewContainerHeight = 40 

func textViewDidChange(textView: UITextView) { 
    let textViewVerticalInset = textView.textContainerInset.bottom + textView.textContainerInset.top 
    let maxHeight = ((textView.font?.lineHeight)! * maxTextViewLines) + textViewVerticalInset 
    let sizeThatFits = textView.sizeThatFits(CGSizeMake(textView.frame.size.width, CGFloat.max)) 

    if sizeThatFits.height < minTextViewContainerHeight { 
     heightConstraint.constant = minTextViewContainerHeight 
     textView.scrollEnabled = false 
    } else if sizeThatFits.height < maxHeight { 
     heightConstraint.constant = sizeThatFits.height 
     textView.scrollEnabled = false 
    } else { 
     heightConstraint.constant = maxHeight 
     textView.scrollEnabled = true 
    } 
} 

func textViewDidEndEditing(textView: UITextView) { 
    textView.text = "" 
    heightConstraint.constant = minTextViewContainerHeight 
    textView.scrollEnabled = false 
} 
-1

Я пользуюсь ASTextInputAccessoryView.Он обрабатывает все для вас и очень проста в настройке:

enter image description here

import ASTextInputAccessoryView 

class ViewController: UIViewController { 

    var iaView: ASResizeableInputAccessoryView!  
    var messageView = ASTextComponentView() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     let photoComponent = UINib 
      .init(nibName: "PhotosComponentView", bundle: nil) 
      .instantiateWithOwner(self, options: nil) 
      .first as! PhotosComponentView 

     messageView = ASTextComponentView(frame: CGRect(x: 0, y: 0, width: screenSize.width , height: 44)) 
     messageView.backgroundColor = UIColor.uIColorFromHex(0x191919) 
     messageView.defaultSendButton.addTarget(self, action: #selector(buttonAction), forControlEvents: .TouchUpInside) 

     iaView = ASResizeableInputAccessoryView(components: [messageView, photoComponent]) 
     iaView.delegate = self   
    } 
} 

//MARK: Input Accessory View 
extension ViewController { 
    override var inputAccessoryView: UIView? { 
     return iaView 
    } 

    // IMPORTANT Allows input view to stay visible 
    override func canBecomeFirstResponder() -> Bool { 
     return true 
    } 

    // Handle Rotation 
    override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) { 
     super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator) 

     coordinator.animateAlongsideTransition({ (context) in 
      self.messageView.textView.layoutIfNeeded() 
     }) { (context) in 
      self.iaView.reloadHeight() 
     } 
    } 
} 

// MARK: ASResizeableInputAccessoryViewDelegate 
extension ViewController: ASResizeableInputAccessoryViewDelegate { 

    func updateInsets(bottom: CGFloat) { 
     var contentInset = tableView.contentInset 
     contentInset.bottom = bottom 
     tableView.contentInset = contentInset 
     tableView.scrollIndicatorInsets = contentInset 
    } 

    func inputAccessoryViewWillAnimateToHeight(view: ASResizeableInputAccessoryView, height: CGFloat, keyboardHeight: CGFloat) -> (() -> Void)? { 

     return { [weak self] in 
      self?.updateInsets(keyboardHeight) 
      self?.tableView.scrollToBottomContent(false) 
     } 
    } 

    func inputAccessoryViewKeyboardWillPresent(view: ASResizeableInputAccessoryView, height: CGFloat) -> (() -> Void)? { 
     return { [weak self] in 
      self?.updateInsets(height) 
      self?.tableView.scrollToBottomContent(false) 
     } 
    } 

    func inputAccessoryViewKeyboardWillDismiss(view: ASResizeableInputAccessoryView, notification: NSNotification) -> (() -> Void)? { 
     return { [weak self] in 
      self?.updateInsets(view.frame.size.height) 
     } 
    } 

    func inputAccessoryViewKeyboardDidChangeHeight(view: ASResizeableInputAccessoryView, height: CGFloat) { 
     let shouldScroll = tableView.isScrolledToBottom 
     updateInsets(height) 
     if shouldScroll { 
      self.tableView.scrollToBottomContent(false) 
     } 
    } 
} 

Теперь вам просто нужно настроить действия для кнопок на AccessoryView.

// MARK: Actions 
extension ViewController { 

    func buttonAction(sender: UIButton!) { 

     // do whatever you like with the "send" button. for example post stuff to firebase or whatever 
     // messageView.textView.text <- this is the String inside the textField 

     messageView.textView.text = "" 
    } 

    @IBAction func dismissKeyboard(sender: AnyObject) { 
     self.messageView.textView.resignFirstResponder() 
    } 

    func addCameraButton() { 

     let cameraButton = UIButton(type: .Custom) 
     let image = UIImage(named: "camera")?.imageWithRenderingMode(.AlwaysTemplate) 
     cameraButton.setImage(image, forState: .Normal) 
     cameraButton.tintColor = UIColor.grayColor() 

     messageView.leftButton = cameraButton 

     let width = NSLayoutConstraint(
      item: cameraButton, 
      attribute: .Width, 
      relatedBy: .Equal, 
      toItem: nil, 
      attribute: .NotAnAttribute, 
      multiplier: 1, 
      constant: 40 
     ) 
     cameraButton.superview?.addConstraint(width) 

     cameraButton.addTarget(self, action: #selector(self.showPictures), forControlEvents: .TouchUpInside) 
    } 

    func showPictures() { 

     PHPhotoLibrary.requestAuthorization { (status) in 
      NSOperationQueue.mainQueue().addOperationWithBlock({ 
       if let photoComponent = self.iaView.components[1] as? PhotosComponentView { 
        self.iaView.selectedComponent = photoComponent 
        photoComponent.getPhotoLibrary() 
       } 
      }) 
     } 
    } 
} 
+1

downvote, по крайней мере, хочет прокомментировать? я клянусь, если это будет «тактический нисходящий» при одновременном ответе, карма уничтожит вас –

Смежные вопросы