如何在iOS中为标签文本输入创建文本字段?

时间:2015-05-26 21:35:47

标签: ios cocoa-touch uitextfield

我正在创建一个应用程序,用户可以通过按几个按钮输入文本(单词或短语)。

文本被插入到UITextField中,用户可以在其中输入自己的其他文本。为了简化与已插入文本的互动,我希望有一种行为类似于标准消息应用在搜索新会话的联系人时的行为方式,或者Evernote如何处理标记。

这意味着,在插入它们之后,单词或短语只能作为一个整体进行选择,按下键盘上的删除按钮可选择整个"标记"首先在下次按下时删除它。

有没有办法让标准的UITextField表现得像这样,还是有UITextField的开源实现呢?

2 个答案:

答案 0 :(得分:2)

我在OS X应用程序上需要类似的东西。他们正在使用名为NSTokenField的东西,但不幸的是在iOS平台上没有相应的东西。因此,您基本上不得不创建自己的令牌或使用现有的第三方库。如果您需要有关如何创建自定义令牌的详细信息,请与我们联系。

P.S。创建自定义令牌需要覆盖drawRect方法和贝塞尔路径的一些用法。

扩展答案: 我将向您展示如何在NSTextView上创建令牌(其中包含文本,但也可以包含NSTextAttachment。此外,代码适用于Cocoa(但在Cocoa中可以实现相同的调整)触摸。

1。)创建扩展NSTextAttachmentCell

的类

2。)覆盖方法-(void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView

- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
    [self drawWithFrame:cellFrame inView:controlView characterIndex:NSNotFound layoutManager:nil];
}

- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView characterIndex:(NSUInteger)charIndex layoutManager:(NSLayoutManager *)layoutManager的实施是这样的:

- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView     characterIndex:(NSUInteger)charIndex layoutManager:(NSLayoutManager *)layoutManager
{
   NSColor* bgColor = [NSColor redColor];
   NSColor* borderColor = [NSColor blackColor];
   NSRect frame = cellFrame;
   CGFloat radius = ceilf([self cellSize].height / 2.f);
   NSBezierPath* roundedRectanglePath = [NSBezierPath bezierPathWithRoundedRect: NSMakeRect(NSMinX(frame) + 0.5, NSMinY(frame) + 3.5, NSWidth(frame) - 1, NSHeight(frame) - 1) xRadius: radius yRadius: radius];
   [bgColor setFill];
   [roundedRectanglePath fill];
   [borderColor setStroke];
   [roundedRectanglePath setLineWidth: 1];
   [roundedRectanglePath stroke];
   CGSize size = [[self stringValue] sizeWithAttributes:@{NSFontAttributeName:defaultFont}];
CGRect textFrame = CGRectMake(cellFrame.origin.x + (cellFrame.size.width - size.width)/2,
                              cellFrame.origin.y + 2.f,
                              size.width,
                              size.height);
   [[self stringValue] drawInRect:textFrame withAttributes:@{NSFontAttributeName:defaultFont, NSForegroundColorAttributeName:     [NSColor whiteColor]}];

}

所有代码都应该是自我解释的,但如果您有任何疑问,请询问。希望它有所帮助。

答案 1 :(得分:0)

我在OS X上需要一些更混合的东西,允许混合使用类似Facebook的标签以及普通文本。所以我构建了自己的实现https://github.com/aiman86/ANTaggedTextView,它只负责视图渲染,而不是自动完成或选择(很快就计划到后者):

  1. 子类NSTextView并覆盖drawRect

    - (void)drawRect:(NSRect)dirtyRect {
        [super drawRect:dirtyRect];
        [self.attributedString enumerateAttributesInRange:(NSRange){0, self.string.length} options:NSAttributedStringEnumerationReverse usingBlock:
         ^(NSDictionary *attributes, NSRange range, BOOL *stop) {
             if ([attributes objectForKey:@"Tag"] != nil)
             {
                 NSDictionary* tagAttributes = [self.attributedString attributesAtIndex:range.location effectiveRange:nil];
                 NSSize oneCharSize = [@"a" sizeWithAttributes:tagAttributes];
                 NSRange activeRange = [self.layoutManager glyphRangeForCharacterRange:range actualCharacterRange:NULL];
                 NSRect tagRect = [self.layoutManager boundingRectForGlyphRange:activeRange inTextContainer:self.textContainer];
                 tagRect.origin.x += self.textContainerOrigin.x;
                 tagRect.origin.y += self.textContainerOrigin.y;
                 tagRect = [self convertRectToLayer:tagRect];
                 NSRect tagBorderRect = (NSRect){ (NSPoint){tagRect.origin.x-oneCharSize.width*0.25, tagRect.origin.y+1}, (NSSize){tagRect.size.width+oneCharSize.width*0.5, tagRect.size.height} };
    
                 [NSGraphicsContext saveGraphicsState];
                 NSBezierPath* path = [NSBezierPath bezierPathWithRoundedRect:tagBorderRect xRadius:3.0f yRadius:3.0f];
                 NSColor* fillColor = [NSColor colorWithCalibratedRed:237.0/255.0 green:243.0/255.0 blue:252.0/255.0 alpha:1];
                 NSColor* strokeColor = [NSColor colorWithCalibratedRed:163.0/255.0 green:188.0/255.0 blue:234.0/255.0 alpha:1];             
                 NSColor* textColor = [NSColor colorWithCalibratedRed:37.0/255.0 green:62.0/255.0 blue:112.0/255.0 alpha:1];
    
                 [path addClip];
                 [fillColor setFill];
                 [strokeColor setStroke];
                 NSRectFillUsingOperation(tagBorderRect, NSCompositeSourceOver);
                 NSAffineTransform *transform = [NSAffineTransform transform];
                 [transform translateXBy: 0.5 yBy: 0.5];
                 [path transformUsingAffineTransform: transform];
                 [path stroke];
                 [transform translateXBy: -1.5 yBy: -1.5];
                 [path transformUsingAffineTransform: transform];
                 [path stroke];
    
                 NSMutableDictionary* attrs = [NSMutableDictionary dictionaryWithDictionary:tagAttributes];
                 NSFont* font = [tagAttributes valueForKey:NSFontAttributeName];
                 font = [[NSFontManager sharedFontManager] convertFont:font toSize:[font pointSize] - 0.25];
                 [attrs addEntriesFromDictionary:@{NSFontAttributeName: font, NSForegroundColorAttributeName: textColor}];
                 [[self.attributedString.string substringWithRange:range] drawInRect:tagRect withAttributes:attrs];
    
                 [NSGraphicsContext restoreGraphicsState];
             }
         }];
    }
    
    1. 现在,您只需在NSAttributedString(具有任意值)中使用属性“Tag”,文本视图将呈现与类似Facebook的标签具有相似外观的标记文本。
  2. 如果您对在表视图中使用它感兴趣,我在github上的实现还提供了NSTextField和NSTextFieldCell实现:

    enter image description here

    希望能帮助处于类似情况的人,如果您发现缺点,请随时发表评论,我对Cocoa应用程序的开发还很陌生。