ios – 在UITextView中选择一个单词

ios – 在UITextView中选择一个单词,第1张

概述编辑:我想我应该使用UILabel而不是UITextView,因为我不希望突出显示使用系统范围的蓝色和’copy / select all / define’popover. 我正在尝试构建自定义文本视图,我正在寻找正确方法的一些帮助.我是一个iOS n00b,所以主要是寻找有关如何最好地解决问题的想法. 我想构建一个自定义文本视图,具有以下行为: >视图从小开始.如果它收到一个点击它会增长(动画 编辑:我想我应该使用UILabel而不是UITextVIEw,因为我不希望突出显示使用系统范围的蓝色和’copy / select all / define’popover.

我正在尝试构建自定义文本视图,我正在寻找正确方法的一些帮助.我是一个iOS n00b,所以主要是寻找有关如何最好地解决问题的想法.

我想构建一个自定义文本视图,具有以下行为:

>视图从小开始.如果它收到一个点击它会增长(动画)为父视图的大小作为模态窗口(左上图,然后右上图)
>在这个大状态中,如果单击一个单词,则单词以某种方式突出显示,并且委托方法称为传递包含被轻敲的字符串的字符串(左下图)

New Text View http://telliott.net/static/NewTextView.png

我怀疑复杂性将在于识别被点击的单词,所以让我们从那里开始.我可以想到几种尝试这种方法:

> UILabel子类.添加触摸手势识别器.识别触摸时,以某种方式获取触摸点的(x.y)坐标,查看视图显示的字符串,并根据位置确定必须按下哪个字.然而,我可以通过自动换行很快看到这变得非常复杂.我不确定如何获得触摸的(x,y)坐标(虽然我认为这很简单),或者如何获得每个角色等设备相关的文本宽度.我宁愿不去这条路线,除非有人可以说服我这不会太可怕!
> UIVIEw子类,并通过为每个单词添加UILabel来伪造句子.测量每个UILabel的宽度并自己铺设.这似乎是一种更明智的方法,虽然我担心以这种方式布置文本也比我开始尝试时的想法更难.

有更明智的方法吗?你可以用其他方式检索UILabel中触及的单词吗?

如果我选择选项2,那么我认为动画来自小 – >大文本可能很复杂,因为单词将以有趣的方式包装.所以我想要另一个子视图 – 这次是UITextVIEw – 将句子保持在小状态.将此动画设置为大,然后将其隐藏,同时以每个单词的一个视图显示我的UIVIEw.

任何想法都赞赏.提前致谢 :)

解决方法 更新

由于在CoreText中添加了NSLayoutManager,因此iOS 7更容易实现.如果您正在处理UITextVIEw,则可以将布局管理器作为视图的属性进行访问.在我的情况下,我想坚持使用UILabel,所以你必须创建一个大小相同的布局管理器,即:

NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:labelText];NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];[textStorage addLayoutManager:layoutManager];CGRect bounds = label.bounds;NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:bounds.size];[layoutManager addTextContainer:textContainer];

现在你只需要找到被点击的字符的索引,这很简单!

NSUInteger characterIndex = [layoutManager characterIndexForPoint:location                                                  inTextContainer:textContainer                         fractionOfdistanceBetweenInsertionPoints:NulL];

这使得找到这个词本身变得微不足道:

if (characterIndex < textStorage.length) {  [labelText.string enumerateSubstringsInRange:NSMakeRange(0,textStorage.length)                                       options:NsstringEnumerationByWords                                    usingBlock:^(Nsstring *substring,NSRange substringRange,NSRange enclosingRange,BOol *stop) {                                      if (NSLocationInRange(characterIndex,enclosingRange)) {                                        // Do your thing with the word,at range 'enclosingRange'                                        *stop = YES;                                      }                                    }];}

原始答案,适用于iOS< 7 感谢@JP Hribovsek提供了一些有关此工作的提示,我设法为我的目的解决了这个问题.它感觉有点Hacky,对于大型文本可能不会很好,但对于一次一段(这是我需要的),它很好. 我创建了一个简单的UILabel子类,允许我设置插入值:

#import "WWLabel.h"#define WWLabelDefaultInset 5@implementation WWLabel@synthesize topInset,leftInset,bottomInset,rightInset;- (ID)initWithFrame:(CGRect)frame{    self = [super initWithFrame:frame];    if (self) {        self.topInset = WWLabelDefaultInset;        self.bottomInset = WWLabelDefaultInset;        self.rightInset = WWLabelDefaultInset;        self.leftInset = WWLabelDefaultInset;    }    return self;}- (voID)drawTextInRect:(CGRect)rect{    UIEdgeInsets insets = {self.topInset,self.leftInset,self.bottomInset,self.rightInset};    return [super drawTextInRect:UIEdgeInsetsInsetRect(rect,insets)];}

然后我创建了一个包含我的自定义标签的UIVIEw子类,然后在标签上构建了标签中每个单词的文本大小,直到大小超过了点击位置的大小 – 这是被点击的单词.这不是完美的,但现在效果还不错.

然后我使用一个简单的NSAttributedString来突出显示文本:

#import "WWPhoneticTextVIEw.h"#import "WWLabel.h"#define WWPhoneticTextVIEwInset 5#define WWPhoneticTextVIEwDefaultcolor [UIcolor blackcolor]#define WWPhoneticTextVIEwHighlightcolor [UIcolor yellowcolor]#define UILabelMagictopmargin 5#define UILabelMagicleftmargin -5@implementation WWPhoneticTextVIEw {    WWLabel *label;    NSMutableAttributedString *labelText;    NSRange tappedRange;}// ... skipped init methods,very simple,just call through to configureVIEw- (voID)configureVIEw{    if(!label) {        tappedRange.location = NSNotFound;        tappedRange.length = 0;        label = [[WWLabel alloc] initWithFrame:[self bounds]];        [label setlineBreakMode:NSlineBreakByWorDWrapPing];        [label setNumberOflines:0];        [label setBackgroundcolor:[UIcolor clearcolor]];        [label settopInset:WWPhoneticTextVIEwInset];        [label setleftInset:WWPhoneticTextVIEwInset];        [label setBottomInset:WWPhoneticTextVIEwInset];        [label setRightInset:WWPhoneticTextVIEwInset];        [self addSubvIEw:label];    }    // Setup tap handling    UITapGestureRecognizer *singleFingerTap = [[UITapGestureRecognizer alloc]                                               initWithTarget:self action:@selector(handleSingleTap:)];    singleFingerTap.numberOfTapsrequired = 1;    [self addGestureRecognizer:singleFingerTap];}- (voID)setText:(Nsstring *)text{    labelText = [[NSMutableAttributedString alloc] initWithString:text];    [label setAttributedText:labelText];}- (voID)handleSingleTap:(UITapGestureRecognizer *)sender{    if (sender.state == UIGestureRecognizerStateEnded)    {        // Get the location of the tap,and normalise for the text vIEw (no margins)        CGPoint tapPoint = [sender locationInVIEw:sender.vIEw];        tapPoint.x = tapPoint.x - WWPhoneticTextVIEwInset - UILabelMagicleftmargin;        tapPoint.y = tapPoint.y - WWPhoneticTextVIEwInset - UILabelMagictopmargin;        // Iterate over each word,and check if the word contains the tap point in the correct line        __block Nsstring *partialString = @"";        __block Nsstring *linestring = @"";        __block int currentlineHeight = label.Font.pointSize;        [label.text enumerateSubstringsInRange:NSMakeRange(0,[label.text length]) options:NsstringEnumerationByWords usingBlock:^(Nsstring* word,NSRange wordRange,BOol* stop){            CGSize sizeforText = CGSizeMake(label.frame.size.wIDth-2*WWPhoneticTextVIEwInset,label.frame.size.height-2*WWPhoneticTextVIEwInset);            partialString = [Nsstring stringWithFormat:@"%@ %@",partialString,word];            // Find the size of the partial string,and stop if we've hit the word            CGSize partialStringSize  = [partialString sizeWithFont:label.Font constrainedToSize:sizeforText lineBreakMode:label.lineBreakMode];            if (partialStringSize.height > currentlineHeight) {                // Text wrapped to new line                currentlineHeight = partialStringSize.height;                linestring = @"";            }            linestring = [Nsstring stringWithFormat:@"%@ %@",linestring,word];            CGSize linestringSize  = [linestring sizeWithFont:label.Font constrainedToSize:label.frame.size lineBreakMode:label.lineBreakMode];            linestringSize.wIDth = linestringSize.wIDth + WWPhoneticTextVIEwInset;            if (tapPoint.x < linestringSize.wIDth && tapPoint.y > (partialStringSize.height-label.Font.pointSize) && tapPoint.y < partialStringSize.height) {                NSLog(@"Tapped word %@",word);                if (tappedRange.location != NSNotFound) {                    [labelText addAttribute:NSForegroundcolorAttributename value:[UIcolor blackcolor] range:tappedRange];                }                tappedRange = wordRange;                [labelText addAttribute:NSForegroundcolorAttributename value:[UIcolor redcolor] range:tappedRange];                [label setAttributedText:labelText];                *stop = YES;            }        }];            }}
总结

以上是内存溢出为你收集整理的ios – 在UITextView中选择一个单词全部内容,希望文章能够帮你解决ios – 在UITextView中选择一个单词所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1114960.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存