【问题标题】:Prevent user from setting cursor position on UITextField防止用户在 UITextField 上设置光标位置
【发布时间】:2013-05-07 12:29:45
【问题描述】:

我有一个使用情节提要构建的 UITextField。我不想让用户更改光标的位置,并将其始终保持在文本末尾的文本字段中。

我试图在触摸阵列中更改光标的位置,但在选择文本字段时,然后再次通过触摸文本字段更改光标的位置时,位置会更改:

- (IBAction)amountBoxTouchDown:(id)sender {
    UITextPosition *start = [amountBox positionFromPosition:[amountBox beginningOfDocument] offset:amountBox.text.length];
    UITextPosition *end = [amountBox positionFromPosition:start
                                                   offset:0];
    [amountBox setSelectedTextRange:[amountBox textRangeFromPosition:start toPosition:end]];
}

有人知道解决办法吗?谢谢

【问题讨论】:

  • 请解释为什么要禁用光标位置。也许还有其他解决方案。

标签: iphone ios objective-c


【解决方案1】:

只需创建 UITextField 的子类并重写 closestPositionToPoint 方法:

- (UITextPosition *)closestPositionToPoint:(CGPoint)point{
    UITextPosition *beginning = self.beginningOfDocument;
    UITextPosition *end = [self positionFromPosition:beginning offset:self.text.length];
    return end;
}

现在用户将无法移动光标,它总是在字段的末尾。

SWIFT:

override func closestPosition(to point: CGPoint) -> UITextPosition? {
    let beginning = self.beginningOfDocument
    let end = self.position(from: beginning, offset: self.text?.count ?? 0)
    return end
}

【讨论】:

  • 不错的解决方案。覆盖 funcclosestPosition(to point: CGPoint) -> UITextPosition? { let begin = self.beginningOfDocument let end = self.position(from: begin, offset: (self.text?.characters.count)!) return end }
  • 效果很好。谢谢
  • 成功了,现在如何使用相同的覆盖方法将光标移动到选定位置。
  • @Harsha 在 Stackoverflow 中找到适当的问题,如果没有找到,请创建一个新问题,
  • 这应该是公认的答案。干净整洁的解决方案
【解决方案2】:

在文本字段成为第一响应者后禁用任何手势识别器。这允许它接收初始点击,但阻止用户在它是第一响应者时与该字段交互。这保持了将光标保持在文本末尾而不允许用户覆盖它的系统行为。

在 UITextField 子类中,添加以下内容:

SWIFT 3.1:

override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
    return !isFirstResponder
}

在情节提要中,将文本字段的类更改为 UITextField 子类。

【讨论】:

    【解决方案3】:

    如果您对始终将光标保持在文本末尾感兴趣,请执行以下操作:

    override func closestPosition(to point: CGPoint) -> UITextPosition? {
        return self.endOfDocument
    }
    

    【讨论】:

    • 这应该是公认的答案,因为如果您可以简单地设置endOfDocument,为什么要使用beginningOfDocument 并添加偏移量(就像在最受好评的答案中一样)? :) 更不用说完全禁用交互会阻止您进行其他操作(如选择/粘贴等)。向你致敬,@kotyara!
    • 这也会中断文本选择,并且光标仍然可以使用硬件键盘的光标键移动。
    【解决方案4】:

    将层和控件视为可以组合以实现功能的工具。

    如果您只是在 UITextField 上方放置一个 UIButton 并将按钮类型更改为自定义,则可以阻止文本字段上的所有触摸事件,例如移动光标、选择文本、复制、剪切和粘贴。

    默认情况下,自定义按钮是透明的。

    创建一个动作,以便在触摸按钮时,文本字段成为第一响应者。

    【讨论】:

    • 我尝试在 UITextField 之上使用 UIButton 和 UIView。我禁用了 userInteactionEnable = NO 并使其颜色清晰,但它不起作用。视图层次结构的 UITextField 将是下一个获得触摸事件的人,因此它将允许您定位视图。我使用@purrrminator 解决方案。
    • 当你可以修改你正在使用的文本字段的行为时,我不建议你添加更多的 UI。
    • 但是你如何阻止两指ipad键盘滑动,这也会移动光标而不接触uitextfield
    • iPhone 键盘上的 3D Touch 和 iPad 键盘上的两个手指效果一样
    【解决方案5】:

    好的,你要做的就是隐藏一个 UITextField。

    将隐藏的文本字段添加到视图中,并在其上调用 becomeFirstResponder。来自您的 amountBoxTouchDown: 方法。

    在 Textfield 委托中,获取用户输入的文本并将其添加到 amountBox.text。还要关闭 userInteractionEnabled 以显示可见的 amountBox 文本字段。

    这会产生您想要的效果。

    查看一些示例代码Link

    【讨论】:

    • 我试过这个,但是禁用用户交互后键盘会消失!!
    • 我已经在视图控制器文件下编写了代码。我在 touchDown 函数中设置了 textField.userInteractionEnabled = NO,我无法显示键盘。上面我的问题中提到了代码,我刚刚删除了textField.userInteractionEnabled = NO的调用。
    • 这是一个很好的解决方案,但它不适合我的自定义使用。无论如何谢谢。
    • 我不喜欢这个,因为它看起来像一个 hack 并且读者不清楚
    【解决方案6】:

    @kas-kad 解决方案的扩展。我用这个创建了 UITextView 的子类

    var enableCursorMotion = true
    
    override func closestPosition(to point: CGPoint) -> UITextPosition? {
        if enableCursorMotion {
            return super.closestPosition(to: point)
        }
        else {
            let beginning = self.beginningOfDocument
            let end = self.position(from: beginning, offset: (self.text?.count)!)
            return end
        }
    }
    

    【讨论】:

      【解决方案7】:

      为什么不使用UITextFieldDelegate 中的textFieldDidChangeSelection 方法?

      使用下面的实现,光标总是在最后。

      而且您不必创建 UITextField 的子类

      func textFieldDidChangeSelection(_ textField: UITextField) {
              let position = textField.endOfDocument
              textField.selectedTextRange = textField.textRange(from: position, to: position)
      }
      

      这样做的一个缺点是您无法标记文本,甚至无法查看带有选择、粘贴等选项的菜单。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-16
        • 2020-12-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-13
        • 2016-04-27
        相关资源
        最近更新 更多