2016-10-03 92 views
5

我在swift應用程序中從頭開始編寫UITextView。 我把textViewview這樣的:光標在UITextView中的奇怪定位

enter image description here

它是正確的鍵盤上方。

textView具有附接到view約束:leadingbottomtoptrailing,所有等於= 4

view具有以下限制:

trailingleadingbottomtopheight

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 
    } 
} 

的初始高度textView38textView的初始字體大小爲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至少關心評論?我發誓如果這是一個「戰術downvote」並行的答案,業力會摧毀你 –