在不使用委托方法的情况下检测 UITextView 和/或 UITextField 上的 SELECTION 更改

Posted

技术标签:

【中文标题】在不使用委托方法的情况下检测 UITextView 和/或 UITextField 上的 SELECTION 更改【英文标题】:Detecting SELECTION change on a UITextView and/or UITextField without using the delegate method 【发布时间】:2014-12-15 09:44:43 【问题描述】:

我正在编写自定义 UITextView,但使用 UITextView 本身内部的委托,它不再可以在其他地方使用(例如:在 UIViewController 中)。

那么,有没有办法检测用户何时更改文本视图或文本字段中所选文本的范围,因为我需要插入符号位置。我找不到任何NSNotification 来做这样的事情:

[[NSNotificationCenter defaultCenter] addObserver:self
     selector:@selector(selectionDidChange:) 
      name: ?? // someNotification
       object:textView];

然后用选择器做一些事情

-(void)selectionDidChange:(NSNotification *)notification 
     //do something

我得到了提示here,但不知道如何继续。

感谢任何帮助。谢谢。

【问题讨论】:

【参考方案1】:

我认为您必须为您的自定义 TextField 制定我们自己的协议。在您的自定义文本字段中,您实现了 UItextfieldDelegate 协议,并制作了自己的协议以防止 UIVIewController。

在你的 .h 中

@protocol YourCustomTextFieldDelegate <NSObject>

  - (void) userDidChangeRange:(NSRange*) currentRange;

@end
@interface YourCustomTextField : UIView <UITextFieldDelegate> 
  UITextField *_customTextField;
 

@property(nonatomic, weak) id<YourCustomTextFieldDelegate> delegate

在您的 .m 中

- (void)viewDidLoad
   [super viewDidLoad];
  // Do any additional setup after loading the view.
 //Create your customTextField and add it to the view
 _customTextField.delegate = self;

 

#pragma mark - UItextField Delegate

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:    (NSRange)range replacementString:(NSString *)string

  [self.delegate userDidChangeRange:range]; 
  return YES;

编辑:带有通知帖子 在你的 .h

  interface YourCustomTextField : UIView <UITextFieldDelegate> 
    UITextField *_customTextField;
   

在你的 .m 中

 - (void)viewDidLoad
   [super viewDidLoad];
   // Do any additional setup after loading the view.
   //Create your customTextField and add it to the view
   _customTextField.delegate = self;


#pragma mark - UItextField Delegate

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:       (NSRange)range replacementString:(NSString *)string

   [[[NSNotificationCenter defaultCenter] postNotificationName:@"YourNotificationName" object:self userInfo:@@"range": range, @"textFieldTag" : @"[NSNumber numberWithInt:self.tag]]; 
  return YES;
 

用户将通过

收听您的通知
 - (void) viewWillAppear:(BOOL)animated
 
  [super viewWillAppear:animated];
   [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(rangeDiDChange) name:@"YourNotificationName" object:nil];

我建议您在通知中设置标签以识别您的文本字段,如果您的视图控制器中有许多自定义文本字段,则可以识别它。

希望它会有所帮助。

【讨论】:

该项目是一个库,因此不能对 viewController 进行任何修改,这就是我说“没有委托方法”的原因!! 你可以在你的委托方法中使用@Optional func。或者使用通知,你在 shouldChangeCharactersInRange 中发布通知,用户会或不会听你的通知。许多库使用可选和自定义选项正在使用委托。 我没听懂你。你能给我一个看起来像我的示例代码(在问题中)的示例代码吗?很抱歉给您带来不便,但我是 ios 和 obj C 的新手。 我已经编辑了原始答案,希望它能回答你的问题。【参考方案2】:

UITextViewDelegate 有这个

-(void)textViewDidChangeSelection:(UITextView *)textView 
    //textView.selectedRange

重要的是,关闭键盘(例如,如果您有一个带有完成按钮的工具栏)将不会触发选择更改方法,即使选择现在已更改(为 0),所以我建议在结束编辑方法中调用此方法为好吧,同时还手动将所选范围设置为nil

-(void)textViewDidEndEditing:(UITextView *)textView 
    textView.selectedRange = NSMakeRange(0, 0);
    [self textViewDidChangeSelection:textView];

【讨论】:

以上是关于在不使用委托方法的情况下检测 UITextView 和/或 UITextField 上的 SELECTION 更改的主要内容,如果未能解决你的问题,请参考以下文章

如何在不调整大小的情况下旋转 UITextView?

如何在不传递委托的情况下从 RootViewController 调用 AppDelegate 方法?

是否可以在不隐藏键盘的情况下使 UITextView 处于非活动状态(可编辑 = 否)?

如何在不使用非公共 API 的情况下禁用 UITextView 上的共享并被苹果拒绝?

如何在不阻止 textView 触摸的情况下向所有 UITextView 添加一个 UIGestureRecognizer

有没有办法在不开始滚动的情况下显示 UITextView 的滚动指示器?