Swift:在 UITextView 中使用占位符文本禁用空白/换行符文本的栏按钮

Posted

技术标签:

【中文标题】Swift:在 UITextView 中使用占位符文本禁用空白/换行符文本的栏按钮【英文标题】:Swift: Disable bar button for whitespace/newline-only text in UITextView with placeholder text 【发布时间】:2016-11-21 03:28:15 【问题描述】:

我在导航栏中有一个ViewController 和一个UITextView 和一个“发送”栏按钮项,用于提交textView 中的文本。由于 UITextView 不支持 UITextField 之类的占位符文本,因此我使用位于 UITextViewDelegate 方法中的以下代码自行处理它,shouldChangeTextInRange

注意:到目前为止,我编写的以下代码也为空格/换行符启用了“发送”按钮。但这是我需要帮助的:

如何在 textView 仅包含空格或换行符时禁用“发送”按钮,但在其他情况下启用它同时还适当地设置/清除占位符文本?

func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool 

    // Combine the postTextView text and the replacement text to
    // create the updated text string
    let currentText : NSString = textView.text
    let updatedText = currentText.stringByReplacingCharactersInRange(range, withString:text)

    // If the updated textView text will be empty, disable the send button,
    // set the placeholder text and color, and set the cursor to the beginning of the text view
    if updatedText.isEmpty 
        sendBarButton.enabled = false
        textView.text = "Write something..."
        textView.textColor = UIColor.lightGrayColor()
        textView.selectedTextRange = textView.textRangeFromPosition(textView.beginningOfDocument, toPosition: textView.beginningOfDocument)
        return false
    

    // If the textView's placeholder is showing (i.e.: the textColor is light gray for placeholder text) 
    // and the length of the replacement string is greater than 0, 
    // clear the text view and set its color to black to prepare for the user to enter text
    else if (textView.textColor == UIColor.lightGrayColor() && !(text.isEmpty)) 
        sendBarButton.enabled = true
        textView.text = nil
        textView.textColor = UIColor.blackColor()
    

    return true

更新:我了解以下代码可用于修剪/识别空白和换行符,但不确定在这种情况下如何在此处应用它:stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()).isEmpty

感谢您的帮助。

【问题讨论】:

【参考方案1】:

我会这样做。我在UITextView 上添加了一个占位符UILabel,我将根据输入的字符数(0 或非零)显示或隐藏它。

这里附上Sample。

这是 Swift 3.x 语法。它仅适用于 Xcode 8.x。

我刚刚使用了更多UITextView 委托方法,如下面的扩展中所示

import UIKit

class ViewController: UIViewController 

    var placeHolderLabel:UILabel!
    @IBOutlet weak var myTextView: UITextView!

    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        placeHolderLabel = UILabel(frame: CGRect(x:5, y:5, width:240, height:22))
        placeHolderLabel.text = "Send Placeholder"

        //Set the font same as your textView font
        placeHolderLabel.font = UIFont.systemFont(ofSize: 15.0)

        //set the placeholder color
        placeHolderLabel.textColor = UIColor.lightGray

        myTextView.addSubview(placeHolderLabel)

        //Initially disable the send button
        sendButton.isEnabled = false
    


// MARK: - TextView Delegates
extension ViewController:UITextViewDelegate 

    // Will handle the case for white spaces and will keep the send button disabled
    func textViewDidChange(_ textView: UITextView) 
        if(textView.text.characters.count != 0) 
            if textView.text.characters.count > 1 
            return
            
            textView.text = textView.text.trimmingCharacters(in: CharacterSet.whitespaces)
            if textView.text.characters.count == 0 
                placeHolderLabel.isHidden = false
                print("Disable Button")
                sendButton.isEnabled = false
             else 
                placeHolderLabel.isHidden = true
                print("Enable Button")
                sendButton.isEnabled = true
            
        
        else 
            placeHolderLabel.isHidden = false
            print("Disable Button")
            sendButton.isEnabled = false
        
    

    // You can modify this, as I just made my keyboard to return whenever return key is pressed.
    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool 
        if(text == "\n") 
            textView.resignFirstResponder()
            return false
        
        return true
    

    func textViewDidBeginEditing(_ textView: UITextView) 
        if(textView.text.characters.count != 0) 
            placeHolderLabel.isHidden = true
        
        else 
            placeHolderLabel.isHidden = false
        
    

    func textViewDidEndEditing(_ textView: UITextView) 
        if(textView.text.characters.count != 0) 
            placeHolderLabel.isHidden = true
        
        else 
            placeHolderLabel.isHidden = false
        
    

【讨论】:

感谢 Rajan,但我相信这仍然会为空白字符启用条形按钮。 为此我们必须编写一些逻辑,只需将字符修剪为空白即可。我马上更新代码 谢谢。是的,我可以使用stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()) 方法来修剪空格和换行符,但我需要为这些字符禁用发送栏按钮,直到输入任何其他字符。 @DiligentDev 根据您的空白要求更新了代码和示例链接 谢谢。尽管您的解决方案对我不起作用,但我能够使用您的部分答案来提出我自己的简单解决方案。请参阅我发布的答案。感谢您的帮助!【参考方案2】:

我能够使用@Rajan Maheshwari 的部分答案来为我自己的问题创建一个简单的解决方案(我认为它甚至可以进一步简化:

var placeholderLabel: UILabel!

func viewDidLoad() 
        placeholderLabel = UILabel(frame: CGRect(x: 5, y: 5, width: 240, height: 18))
        placeholderLabel.text = "Placeholder text..."
        placeholderLabel.textColor = UIColor.lightGrayColor()
        placeholderLabel.sizeToFit()
        postTextView.addSubview(placeholderLabel)


func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool 

        let currentText: NSString = textView.text
        let updatedText = currentText.stringByReplacingCharactersInRange(range, withString:text)
        let trimmedText = updatedText.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())

        if !updatedText.isEmpty 
            // Contains any text: hide placeholder
            placeholderLabel.hidden = true
            if trimmedText.isEmpty 
                // Only whitespace and newline characters: disable button
                sendBarButton.enabled = false
             else 
                // No whitespace- and newline-only characters: enable button
                sendBarButton.enabled = true
            
         else 
            // No text at all: show placeholder, disable button
            placeholderLabel.hidden = false
            sendBarButton.enabled = false
        
        return true
    

致谢:感谢@Rajan Maheshwari 的帮助!

【讨论】:

以上是关于Swift:在 UITextView 中使用占位符文本禁用空白/换行符文本的栏按钮的主要内容,如果未能解决你的问题,请参考以下文章

swift 在UITextView(Swift)中实现占位符的正确方法

当用户在 Swift 中点击 UITextView 时,如何运行一段代码?

如何在 UITextView 中插入占位符? [复制]

具有存储属性的扩展

多个 UITextView 占位符

为啥 UITextview 没有 UITextField 之类的占位符属性 [重复]