【问题标题】:UITextView disabling text selectionUITextView 禁用文本选择
【发布时间】:2010-12-11 00:03:01
【问题描述】:

我很难让UITextView 禁用文本选择。

我试过了:

canCancelContentTouches = YES;

我尝试过子类化和覆盖:

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender   

(但只有在选择之后才会调用)

- (BOOL)touchesShouldCancelInContentView:(UIView *)view;  

(我根本不认为会被解雇)

- (BOOL)touchesShouldBegin:(NSSet *)touches
                 withEvent:(UIEvent *)event
             inContentView:(UIView *)view; 

(我也不认为会被解雇)

我错过了什么?

【问题讨论】:

  • 因为不可能为此添加答案:请注意此处的最佳答案(恕我直言)实际上是 Alexander 的评论:因为 iOS 7 有一个 @property(nonatomic,getter=isSelectable) BOOL 可选 NS_AVAILABLE_IOS (7_0)
  • 我重新打开了这个问题并添加了selectable 作为正确答案。耶!

标签: ios objective-c iphone uitextview


【解决方案1】:

如果你只是想阻止它被编辑,那么将 UITextView 的“可编辑”属性设置为 NO/False。

如果您试图让它可编辑但不可选择,那将是棘手的。您可能需要创建一个用户可以输入的隐藏文本视图,然后让 UITextView 观察隐藏的文本视图并使用文本视图的文本填充自身。

【讨论】:

  • 这是我为不可编辑/选定的文本字段所做的:类
【解决方案2】:

您是否尝试将 UITextView 的 userInteractionEnabled 设置为 NO?但你也会失去滚动。

如果您需要滚动,这可能是您使用 UITextView 而不是 UILabel 的原因,那么您需要做更多的工作。对于您不想允许的操作,您可能必须覆盖 canPerformAction:withSender: 以返回 NO

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
    switch (action) {
        case @selector(paste:):
        case @selector(copy:):
        case @selector(cut:):
        case @selector(cut:):
        case @selector(select:):
        case @selector(selectAll:):
        return NO;
    }
    return [super canPerformAction:action withSender:sender];
}

更多信息,UIResponderStandardEditActions

【讨论】:

  • 我提到我已经尝试过了 :) canPerform 直到你做出选择后才会被调用
  • 投反对票:这不会阻止出现剪切/复制/定义工具栏 - 此页面上列出了更好的解决方案。
【解决方案3】:

听起来你真正想要的是 UIScrollView 中的一个巨大的 UILabel,而不是 UITextView。

更新:如果您使用的是较新版本的 iOS UILabel 现在有一个 lines 属性:

Multiple lines of text in UILabel

【讨论】:

  • 是的,我猜。如果我不明白这一点,我会做下一件事情。
  • thanx 老兄,我不知道 dizy,但我实际上需要一个 UILabel。
  • UILabel 将防止换行符。你想要一个没有启用用户交互的 UITextView……然后你想要一个 UIScrollView 里面。或者,您可以在 UIWebView 的 textView 中显示带有文本的透明 UIWebView(只需使用 loadHTML 将您的文本/代码导入 UIWebView(包括使背景透明的 CSS 代码),然后您可以使用 javascript 使其不可选择但仍可滚动)。
  • @AlbertRenshaw 我不认为你的第一句话是正确的。快速谷歌似乎表明 UILabel 支持换行符就好了。
  • @AlbertRenshaw 不要让它更高 - 将它设置为 0,然后你可以拥有任意多的行。
【解决方案4】:

Issue How disable Copy, Cut, Select, Select All in UITextView 有一个可行的解决方案,我刚刚实施并验证:

子类UITextView并覆盖canBecomeFirstResponder:

- (BOOL)canBecomeFirstResponder {
    return NO;
}

请注意,这会禁用链接和其他可点击的文本内容。

【讨论】:

  • 如果您根本不想要任何用户交互,是的。
  • 您是否尝试过使用可选属性? @property(nonatomic,getter=isSelectable) BOOL 可选 NS_AVAILABLE_IOS(7_0); // 切换可选择性,控制用户选择内容以及与 URL 和附件交互的能力
  • 这会禁用链接等
  • 有人知道不禁用链接但禁用突出显示的解决方案吗?我尝试覆盖长按,但这似乎也禁用了链接点击......
  • @TrespassersW 覆盖 - (void)textViewDidChangeSelection:(UITextView *)textView 并设置 textView.selectedRange = NSMakeRange(0, 0);可以做到这一点
【解决方案5】:

我找到了电话

[textView setUserInteractionEnabled:NO];

效果很好。

【讨论】:

  • 这也会禁用 UITextView 的滚动功能
  • 并禁用点击链接的能力
  • 我使用 uitextview 作为自定义 uitableviewcell 中的子视图。它像梦一样工作
【解决方案6】:

UITextViewselectable 属性:

此属性控制用户选择内容和 与 URL 和文本附件交互。默认值为 YES。

【讨论】:

  • objective-C好像没有setter?
  • 这看起来就像get - 我在尝试设置时看到编译器错误? textView.isSelectable = NO;
  • 那是因为-isSelectable 只是getter 的名称。使用-[UITextView setSelectable:] 进行设置。使用属性语法,getter 和 setter 都是selectableBOOL foo = textView.selectable;textView.selectable = bar;
  • 这个也禁用链接
【解决方案7】:

要做到这一点,首先要继承 UITextView

并在实现中执行以下操作

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event
{
    self.selectable = NO;
}

- (void)touchesCancelled:(nullable NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event
{
        self.selectable = YES;
 }

这应该可以正常工作,

【讨论】:

  • 这也会禁用链接
【解决方案8】:

您可以通过子类化UITextView 来禁用文本选择。

下面的解决方案是:

/// Class to disallow text selection
/// while keeping support for loupe/magnifier and scrolling
/// https://stackoverflow.com/a/49428248/1033581
class UnselectableTextView: UITextView {

    override init(frame: CGRect, textContainer: NSTextContainer?) {
        super.init(frame: frame, textContainer: textContainer)
        commonInit()
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }
    private func commonInit() {
        // prevents selection from loupe/magnifier (_UITextSelectionForceGesture), multi tap, tap and a half, etc.
        // without losing the loupe/magnifier or scrolling
        // but we lose taps on links
        addSubview(transparentOverlayView)
    }
    let transparentOverlayView: UIView = {
        $0.backgroundColor = .clear
        $0.autoresizingMask = [.flexibleHeight, .flexibleWidth]
        return $0
    }(UIView())
    override var contentSize: CGSize {
        didSet {
            transparentOverlayView.frame = CGRect(origin: .zero, size: contentSize)
        }
    }

    // required to prevent blue background selection from any situation
    override var selectedTextRange: UITextRange? {
        get { return nil }
        set {}
    }
}

【讨论】:

    【解决方案9】:

    对于 swift,有一个名为 "isSelectable" 的属性,默认赋值为 true

    您可以按如下方式使用它:

    textView.isSelectable = false
    

    【讨论】:

      【解决方案10】:

      Swift 4Xcode 10

      这个解决方案将

      • 禁用突出显示
      • 启用点击链接
      • 允许滚动

      确保将委托设置为 YourViewController

      yourTextView.delegate = yourViewControllerInstance
      

      然后

      extension YourViewController: UITextViewDelegate {
      
          func textViewDidChangeSelection(_ textView: UITextView) {
              view.endEditing(true)
          }
      
      }
      

      【讨论】:

      • 它在 iOS 13 中对我不起作用。而不是 view.endEditing(true) 使用 textView.selectedTextRange = nil
      【解决方案11】:

      Swift 4、Xcode 10:

      如果您想让用户无法选择或编辑文本。

      这使得它不能被编辑:

      textView.isEditable = false
      

      这会禁用所有用户交互:

      textView.isUserInteractionEnabled = false
      

      这使得您无法选择它。这意味着它不会显示编辑或粘贴选项。我想这就是你要找的。​​p>

      textView.isSelectable = false
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-06-27
        • 2014-03-21
        • 1970-01-01
        • 2019-06-18
        • 1970-01-01
        • 2011-03-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多