光标在 UITextView 中的奇怪定位
Posted
技术标签:
【中文标题】光标在 UITextView 中的奇怪定位【英文标题】:weird positioning of the cursor in the UITextView 【发布时间】:2016-10-03 21:38:06 【问题描述】:我正在我的swift
应用程序中从头开始编写UITextView
。
我在view
上放了一个textView
,如下所示:
它就在键盘的正上方。
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
没有设置在视图的完整范围内。我的意思是,它看起来像这样:
它应该是这样的:
为什么要添加这个额外的空白,我该如何摆脱它?
当前当新行出现时有这个空白,但是当用户滚动 textView
以使文本居中并摆脱空白时 - 它永远消失了,用户无法再次向上滚动,所以白色线在那里。所以对我来说,刷新内容似乎有些问题,但也许你知道得更好——你能给我一些提示吗?
【问题讨论】:
我不太清楚,根据我的猜测将 ScrollingEnabled 更改为 NO 可能会起作用.. hmm @Gokul 也许会有所帮助,但我需要scrollingEnabled
到 true
因为如果文本超过 4 行,那么 textView
不再增长,用户可以滚动里面的内容...
您是否为聊天构建了应用程序?
不,否则我很确定有一些已经内置的组件......我创建了这个字段用于添加 cmets
@user3766930 您确认行数正确吗?这意味着,如果您在文本框中的第 3 行输入,您的 numberOfLines()
方法是否返回 3。
【参考方案1】:
这是我在我正在开发的一个应用程序的评论部分使用的一种不同的方法。这与 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
【讨论】:
【参考方案2】:我正在使用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()
)
【讨论】:
downvote 至少在乎评论?我发誓,如果这是同时回答的“战术性否决票”,业力会摧毁你以上是关于光标在 UITextView 中的奇怪定位的主要内容,如果未能解决你的问题,请参考以下文章