【问题标题】:In IOS 7, UITextView offsetFromPosition: toPosition: always return 0 with arguments of UITextPositions returned from UITextView characterRangeAtPoint在 IOS 7 中,UITextView offsetFromPosition: toPosition: 始终返回 0,其中 UITextPositions 的参数从 UITextView characterRangeAtPoint 返回
【发布时间】:2013-09-25 10:25:52
【问题描述】:

我试图在我的代码中使用UITextView characterRangeAtPoint 在文本视图中的某个CGPoints 处获取UITextRanges。然后我使用来自UITextRangesUITextPositions 作为参数,并使用UITextView offsetFromPosition: toPosition: 来获取偏移量。它在 iOS 6 中运行良好。但是当我在 iOS 7 中尝试它时,无论我在 textview 中尝试什么CGPoint,它总是返回给我offset 0

代码如下:

// init the textview
textview = [[UITextView alloc] initWithFrame:CGRectMake(10, 50, 300, 500)];
textview.backgroundColor = [UIColor whiteColor];
[self.view addSubview:textview];

// load the txt file for testing  
NSError *error;
NSString *content = [[NSString alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource:@"test" ofType:@"txt"] encoding:NSUTF8StringEncoding error:&error];
if (error) {
    NSLog(@"load string error:%@", [error localizedFailureReason]);
    return;
}

// set the text and font
textview.text = content;
UIFont *font = [UIFont systemFontOfSize:18];
textview.font = font;

// get text range at point (100, 100) and string offset from the beginning to this point 
UITextRange *textrange = [textview characterRangeAtPoint: CGPointMake(100, 100)];
NSInteger offset = [textview offsetFromPosition:textview.beginningOfDocument toPosition:textrange.start];
NSLog(@"offset = %d", offset);

它返回的offset 始终是0。为了测试是否是因为UITextView offsetFromPosition: toPosition:,我尝试了以下代码:

NSInteger offset1 = [textview offsetFromPosition:textview.beginningOfDocument toPosition:textview.endOfDocument];
NSLog(@"offset1 = %d", offset1);

它给了我offset1 = 5264,根据我使用的test.txt,这是正确的。所以问题是从textview characterRangeAtPoint 返回的UITextRange。在 IOS 7 中,characterRangeAtPoint 似乎没有在给定的CGPoint 处返回正确的文本范围。所以textview offsetFromPosition: toPosition: 无法返回正确的偏移量。

但我在 IOS 6 中使用了相同的代码,并且效果很好。我也查了characterRangeAtPoint的引用,没有找到有用的信息。

有谁知道characterRangeAtPoint 在 IOS 7 中发生了什么?为了让它像在 IOS 6 中一样正常工作,我应该怎么做?

【问题讨论】:

标签: iphone ios ios6 uitextview ios7


【解决方案1】:

我遇到了同样的问题。而且我发现 characterRangeAtPoint 不会返回值,除非在 IOS 7 的 TextView 中至少更改或选择了一次文本。 我无法使此功能正常工作,因此我不得不避免使用它(我也尝试设置 setContentInset 但没有运气)。这是我的解决方法。我相信您可以根据自己的情况制作类似的东西。

// get the beginning position of the current line.
NSRange pos = [textView.text rangeOfString:@"\n" options:NSBackwardsSearch range:NSMakeRange(0,textView.selectedRange.location)];
if (pos.location == NSNotFound) pos.location = 0; // if the text has only one line.
NSLog(@"pos = %d",pos.location);

【讨论】:

  • 非常感谢您的回复!当我搜索这个主题时,我发现了这些信息。那么你介意让我知道你是如何解决你的问题的吗?我还发现closestPositionToPoint 也做与characterRangeAtPoint 类似的事情。即使没有选择文本视图,它也可以返回正确的值。但是,当您传递给此方法的点 y 变大时(在我的测试案例中,点的 y 超过 260pt),返回值变得不正确。太奇怪了……在 iOS 6 中,closestPositionToPoint 运行良好。
  • @boatflag,我希望这会有所帮助:)
  • 抱歉回复晚了!非常感谢您分享您的解决方案!我的情况和你的情况有些不同。我需要在页面中显示文本,因此在绘制文本之前我需要知道一页可以容纳多少个字符。最后我写了一个基于boundingRectWithSize的函数。但是对于与您的情况相似的情况,您的解决方案也是解决此问题的好方法。所以我会选择你的解决方案作为答案。再次感谢!
【解决方案2】:

设置你的 textview 的 setContentInset

试试这个代码

UITextRange *textrange = [textview characterRangeAtPoint: CGPointMake(100, 100)];
NSInteger offset = [textview offsetFromPosition:textview.beginningOfDocument toPosition:textrange.start];

[textview setContentInset:UIEdgeInsetsMake(-45, 0, 5,0)];

NSLog(@"offset = %d", offset);

【讨论】:

  • 感谢您的回复!我试过你的代码,但偏移量仍然是 0。你能解释一下 contentInset 将如何影响 characterRangeAtPoint 吗?谢谢!
  • 此代码在 iOS7 中可以使用,我已经在检查.....请更改 CGPointMake(10000, 10000)
  • 我不知道为什么我的地雷不工作......并将 CGPoint 更改为 (10000, 10000) 使该点位于 textview 之外(我也尝试过,仍然返回 0)。根据我的代码中的文本视图,我认为 (100, 100) 是一个合理的位置,我可以在 iOS 6 设备上获得正确的偏移量。你能告诉我为什么 setContentInset 会影响 characterRangeAtPoint 返回的结果吗?
  • 我在谷歌上搜索了这个主题,发现有人说 characterRangeAtPoint 不会返回值,除非在 IOS 7 的 TextView 中至少选择了一次文本。这是真的吗?如果您能给我更多解释,我将不胜感激。提前非常感谢!
【解决方案3】:

我找到了解决此错误的方法,并发布了解决方案作为对this question 的回复。

这是复制粘贴:


这是一个 iOS 7 错误。 characterRangeAtPoint: 总是返回 nil,除非事先选择了文本。

作为一种解决方法,您可以事先调用setSelectedRange:setSelectedTextRange:,但随后 textView 会突出显示您的选择。我想出了以下解决方案:

[textView select:textView];
[textView setSelectedTextRange:nil];

调用这两个方法后,characterRangeAtPoint: 将按预期开始工作。

请注意,您只需在 textView 初始化后调用一次。

【讨论】:

  • 简单地复制Stack Overflow上另一个答案的内容作为答案并不是特别合适。如果您认为此问题与另一个问题重复,则应将其标记为这样。
  • @Dukeling ,我没有足够的声誉将问题标记为重复,我觉得“链接加粘贴”方法将是一个不错的折衷方案(考虑到我正在粘贴我自己的答案,而不是别人的)。
  • 我添加了一个链接作为对该问题的评论,并且我将这个帖子标记为删除。
【解决方案4】:

我最近在为 7.1.1 开发时遇到了同样的问题(仍然没有解决...),并想分享我的简单解决方案。

我尝试了 Exile.90 的做法,但没有成功。

相反,我在情节提要中启用了文本选择,并在 viewDidLoad 期间禁用了它。没有选择发生,但受影响的功能现在对我来说非常完美。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 2013-12-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-17
    相关资源
    最近更新 更多