隐藏 UITextField 的游标

我使用 UITextFieldUIPickerView作为它的 inputView,这样当用户点击文本字段时,就会为他们召唤一个选择器来从中选择一个选项。

几乎所有的工作,但我有一个问题: 光标仍然闪烁在文本字段时,它是活动的,这是丑陋和不适当的,因为用户不希望输入到字段,并没有提供一个键盘。我知道我可以通过在文本字段上将 editing设置为 NO并跟踪触摸它来解决这个问题,或者通过用一个自定义样式的按钮替换它,并通过代码召唤选择器来解决这个问题。但是,我希望使用 UITextFieldDelegate方法来处理文本字段上的所有事件,并且使用按钮替换文本字段等技巧不允许这种方法。

如何简单地将光标隐藏在 UITextField上?

73176 次浏览

答案由 OP 提供,从问题主体复制,以帮助清理不断增长的未回答问题的尾巴。

我认为我有正确的解决方案,但是如果可以改进的话,我会很欢迎的:)好的,我创建了 UITextField 的一个子类,并覆盖了返回边界 CGRect 的方法

-(CGRect)textRectForBounds:(CGRect)bounds {
return CGRectZero;
}

问题?文本不显示,因为 rect 为零。但是我添加了一个 UILabel 作为控件的子视图,并覆盖了 setText 方法,因此,当我们像往常一样输入文本时,文本字段文本为 nil,并且是显示文本的标签

- (void)setText:(NSString *)aText {
[super setText:nil];


if (aText == nil) {
textLabel_.text = nil;
}


if (![aText isEqualToString:@""]) {
textLabel_.text = aText;
}
}

有了这个,这个东西就像预期的那样工作。你知道有什么方法可以改进它吗?

答案由 OP 提供,从问题主体复制,以帮助清理不断增长的未回答问题的尾巴。

我找到了另一个解决方案: 子类 UIButton并重写这些方法

- (UIView *)inputView {
return inputView_;
}


- (void)setInputView:(UIView *)anInputView {
if (inputView_ != anInputView) {
[inputView_ release];
inputView_ = [anInputView retain];
}
}


- (BOOL)canBecomeFirstResponder {
return YES;
}

现在,按钮作为 UIResponder具有与 UITextField类似的行为,其实现非常简单。

我只是子类化 UITextField,然后重写 layoutSubviews,如下所示:

- (void)layoutSubviews
{
[super layoutSubviews];
for (UIView *v in self.subviews)
{
if ([[[v class] description] rangeOfString:@"UITextSelectionView"].location != NSNotFound)
{
v.hidden = YES;
}
}
}

这是一个肮脏的黑客行为,将来可能会失败(此时光标将再次可见——您的应用程序不会崩溃) ,但它仍然可以工作。

只需子类化 UITextField 并覆盖 caretRectForposition

- (CGRect)caretRectForPosition:(UITextPosition *)position
{
return CGRectZero;
}

检查 规定 UITextInput财产 selectedTextRange同学们 UITextField符合它。很少!这就是面向对象编程的教训。

把卡雷特藏起来

若要隐藏插入符号,请删除文本字段的选定文本范围。

textField.selectedTextRange = nil; // hides caret

揭开卡利特的面纱

这里有两种方法可以解除插入符号的隐藏。

  1. 将文本字段的选定文本范围设置为文档的末尾。

    UITextPosition *end = textField.endOfDocument;
    textField.selectedTextRange = [textField textRangeFromPosition:end
    toPosition:end];
    
  2. To keep the caret in the same spot, first, store the text field's selected text range to an instance variable.

    _textFieldSelectedTextRange = textField.selectedTextRange;
    textField.selectedTextRange = nil; // hides caret
    

    然后,当您想要取消插入符号隐藏时,只需将文本字段的选定文本范围设置为原来的值:

    textField.selectedTextRange     = _textFieldSelectedTextRange;
    _textFieldLastSelectedTextRange = nil;
    

如果你想隐藏光标,你可以很容易地使用这个! 它为我工作. 。

[[textField valueForKey:@"textInputTraits"] setValue:[UIColor clearColor] forKey:@"insertionPointColor"]

从 iOS7开始,你只需要在 textField 上设置 tintColor = [UIColor clearColor],插入符号就会消失。

可以通过关联对象向类别中的 UITextField添加 BOOL cursorless属性。

@interface UITextField (Cursorless)


@property (nonatomic, assign) BOOL cursorless;


@end

然后使用方法 swizzling 来调整 caretRectForPosition:,该方法使用 cursorlessCGRectZero和它的默认值之间切换。

这通过一个下拉类别导致一个简单的界面。

只要把它们放进去,就可以从这个简单的界面中获益

UITextField类别: Https://github.com/rexmas/rexdk/blob/master/rexdk/ui/uitextfield%2brxcursorless.h Https://github.com/rexmas/rexdk/blob/master/rexdk/ui/uitextfield%2brxcursorless.m

方法: Https://github.com/rexmas/rexdk/blob/master/rexdk/foundation/nsobject%2brxruntimeadditions.h Https://github.com/rexmas/rexdk/blob/master/rexdk/foundation/nsobject%2brxruntimeadditions.m

为了同时禁用光标和菜单,我使用子类和这两个方法:

- (CGRect)caretRectForPosition:(UITextPosition *)position {
return CGRectZero;
}


- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
[UIMenuController sharedMenuController].menuVisible = NO;
self.selectedTextRange = nil;


return NO;
}

您可能还希望阻止用户选择、复制或粘贴任何文本,以便唯一的文本输入来自选择器视图。

- (CGRect) caretRectForPosition:(UITextPosition*) position
{
return CGRectZero;
}


- (NSArray *)selectionRectsForRange:(UITextRange *)range
{
return nil;
}


- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if (action == @selector(copy:) || action == @selector(selectAll:) || action == @selector(paste:))
{
returnNO;
}


return [super canPerformAction:action withSender:sender];
}

Http://b2cloud.com.au/tutorial/disabling-the-caret-and-text-entry-in-uitextfields/

您可以只清除文本字段的 tintColor

self.textField.tintColor = [UIColor clearColor];

Swift 3.0

self.textField.tintColor = .clear

enter image description here

Swift 5版本的 Net’s post

  override func caretRect(for position: UITextPosition) -> CGRect {
return .zero
}
  

override func selectionRects(for range: UITextRange) -> [UITextSelectionRect] {
return []
}
  

override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
return false
}

将 tintColor 设置为 Clear Color

textfield.tintColor = [UIColor clearColor];

你也可以从 Interface Builder 开始设置

如果你喜欢 clean = less 代码,可以使用下面的 Interface Builder:

Clear color

(属性检查员,查看部分。)

在我的情况下,覆盖插入符号 rect 是不够的。在 iOS15上,插入符号没有出现,但是选择句柄出现了。

用 UITextView 子类上的 override var canBecomeFirstResponder: Bool { return false }解决了这个问题。