我在我的UITextView
应用中从头开始编写swift
。
我在textView
上添加view
,如下所示:
它就在键盘的正上方。
textView
附加了约view
:leading
,bottom
,top
和trailing
,所有等于= {{1 }}
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
以使文本居中并摆脱空白区域时 - 它永远消失,用户无法滚动它又一次,所以白线就在那里。所以对我来说,看起来像刷新内容有些问题,但也许你知道的更好 - 你能给我一些提示吗?
答案 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 :(得分:-1)
我正在使用ASTextInputAccessoryView。它为您处理一切,并且非常容易设置:
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()
}
})
}
}
}