2015-05-26 2 views
0

Я создаю приложение, в котором пользователь может вводить текст (слова или короткие фразы), нажимая несколько кнопок.Как создать текстовое поле для ввода тегов в iOS?

Текст вводится в UITextField, где пользователь может вводить свой собственный текст. Чтобы упростить взаимодействие с уже вставленным текстом, мне бы хотелось, чтобы поведение было похоже на то, как работает стандартное сообщение-приложение при поиске контактов для нового разговора или как Evernote обрабатывает теги.

Это означает, что после того, как они вставлены, слова или фразы можно выбрать только в целом, а нажатие кнопки Delete на клавиатуре сначала выбирает весь «тег» и удаляет его при следующем нажатии.

Есть ли способ заставить стандартный UITextField вести себя так, или существует ли реализация UITextField с открытым исходным кодом?

+1

Возможно, что-то вроде этого: github.com/venmo/VENTokenField? – benhameen

+1

@benhameen, Большое вам спасибо! То, что я искал;) (Я бы поднял вас, но я не могу, поскольку у меня еще нет достаточной репутации: \) – Luke35

+0

Уверенная вещь! И не стоит беспокоиться, комментарии с правом голоса просто эстетичны. Счастливое кодирование! – benhameen

ответ

2

Мне было нужно что-то подобное в моем приложении OS X. Там они используют что-то под названием NSTokenField, но, к сожалению, на платформе iOS нет эквивалента. Таким образом, вы в основном придерживаетесь создания собственных жетонов или использования существующих сторонних библиотек. Если вам нужна информация о том, как создавать пользовательские токены, сообщите мне.

P.S. создание пользовательских токенов требует переопределения метода drawRect и некоторого использования путей Безье.

развернутый ответ: я покажу вам, как создать маркеры на NSTextView (который содержит текст, но может также содержит NSTextAttachment Кроме того, код работает на какао (но с небольшой настройки то же самое может быть достигнуто в какао. Нажмите.

1.) Создать класс, который расширяет NSTextAttachmentCell

2.) Override метод -(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]}]; 

}

Весь код должен быть сам объяснительный, но если у вас есть какие-либо вопросы, пожалуйста, спрашивайте. Надеюсь, поможет.

+0

Спасибо за указание drawRect, это будет полезно для нескольких других вещей, которые делает мое приложение. Очень жаль, что системного решения нет, но я думаю, что я буду использовать [VENTokenField] (http://github.com/venmo/VENTokenField), как это было предложено @benhameen в комментариях. Еще раз спасибо;) – Luke35

+0

Кроме того, я бы хотел поддержать этот ответ, но пока у меня недостаточно репутации. – Luke35

+0

Да, я бы предложил то же самое. Но я не мог найти подобную библиотеку для OS X, поэтому я должен был сделать это сам :) Я продолжу ответ, может быть, кто-то найдет это полезным :) – markich

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 (с любым значением), и текстовое представление будет отображать тегированный текст с похожим внешним видом и похожими на Facebook тегами.

Моя реализация на GitHub также обеспечивает реализацию NSTextField и NSTextFieldCell, если вы заинтересованы в использовании его в просмотрах таблицы:

enter image description here

Надежда, что помогает кому-то, кто находится в подобной ситуации , пожалуйста, не стесняйтесь комментировать, если вы видите недостатки, я совершенно новый для разработки приложений Cocoa.

Смежные вопросы