Метод делегата работает, но ТОЛЬКО, если вложение имеет изображение в атрибуте изображения И если editable = NO! Поэтому, если у вас есть образ, вставленный в атрибутString из другого места, кажется, что данные заканчиваются тем, что они хранятся в файлеWrapper, и в следующий раз, когда вы добавите атрибут attribring в textView, атрибут изображения равен нулю, а менеджер компоновки или что-то еще получает изображение из файла.
Где-то в документах упоминается, что в NSTextAttachment нет методов для сохранения атрибута изображения.
Чтобы протестировать эту попытку, скопируйте фотографию из приложения «Фото» и вставьте ее в свой текстовый рисунок, теперь, если вы удерживаете ее пальцем, вы должны увидеть всплывающее меню по умолчанию. Теперь, если вы сохраните этот богатый текст, скажете в объект Core Data, а затем извлечете его, атрибут изображения будет равен нулю, но данные изображения будут в attachment.fileWrapper.regularFileContents
. Это боль, и я бы с удовольствием знать намерения инженеров. Таким образом, у вас есть два варианта.
Помните о побочном эффекте Это делает недействительным fileWrapper. Я хочу изменить размер изображения, но также сохранить оригинал, чтобы я не потерял полное разрешение. Я думаю, что единственный способ сделать это может заключаться в подклассе NSTextAttachment.
EDIT:
Я выяснил, как создать пользовательские NSTextAttachments - вот ссылка для заинтересованных http://ossh.com.au/design-and- технология / разработка программного обеспечения / реализация-rich-text-with-images-on-os-x-and-ios /
EDIT 2: настройка меню в режиме редактирования см. в разделе следующие документы Apple, проблема «touchEnded» никогда не кажется вызванной, поэтому вам, возможно, придется попробовать использовать touchhesBegan. Однако осторожно, что вы не вмешиваетесь в поведение редактирования по умолчанию.
Обратите внимание, что в приведенном ниже коде вам нужно будет добавить код после комментария // selection management
, чтобы определить, какой символ был затронут, проверьте, является ли это особым текстовым вложением, а затем измените меню редактирования или предпринять некоторые другие действия.
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *theTouch = [touches anyObject];
if ([theTouch tapCount] == 2 && [self becomeFirstResponder]) {
// selection management code goes here...
// bring up edit menu.
UIMenuController *theMenu = [UIMenuController sharedMenuController];
CGRect selectionRect = CGRectMake (currentSelection.x, currentSelection.y, SIDE, SIDE);
[theMenu setTargetRect:selectionRect inView:self];
[theMenu setMenuVisible:YES animated:YES];
}
}
В качестве альтернативы вы можете добавить пользовательское меню, добавив пункт меню, а затем изменив метод canPerformAction.
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
LOG(@"canPerformAction: called");
if (action == @selector(viewImage)) {
// Check the selected character is the special text attachment character
return YES;
}
return NO;
}
Вот код добавления, но его немного суетливый. Второй метод просто отключает меню редактирования по умолчанию, если обнаружено вложение.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
FLOG(@"touchesBegan:withEvent: called");
if (self.selectedRange.location != NSNotFound) {
FLOG(@" selected location is %d", self.selectedRange.location);
int ch;
if (self.selectedRange.location >= self.textStorage.length) {
// Get the character at the location
ch = [[[self textStorage] string] characterAtIndex:self.selectedRange.location-1];
} else {
// Get the character at the location
ch = [[[self textStorage] string] characterAtIndex:self.selectedRange.location];
}
if (ch == NSAttachmentCharacter) {
FLOG(@" selected character is %d, a TextAttachment", ch);
} else {
FLOG(@" selected character is %d", ch);
}
}
}
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
FLOG(@"canPerformAction: called");
FLOG(@" selected location is %d", self.selectedRange.location);
FLOG(@" TextAttachment character is %d", NSAttachmentCharacter);
if (self.selectedRange.location != NSNotFound) {
int ch;
if (self.selectedRange.location >= self.textStorage.length) {
// Get the character at the location
ch = [[[self textStorage] string] characterAtIndex:self.selectedRange.location-1];
} else {
// Get the character at the location
ch = [[[self textStorage] string] characterAtIndex:self.selectedRange.location];
}
if (ch == NSAttachmentCharacter) {
FLOG(@" selected character is %d, a TextAttachment", ch);
return NO;
} else {
FLOG(@" selected character is %d", ch);
}
// Check for an attachment
NSTextAttachment *attachment = [[self textStorage] attribute:NSAttachmentAttributeName atIndex:self.selectedRange.location effectiveRange:NULL];
if (attachment) {
FLOG(@" attachment attribute retrieved at location %d", self.selectedRange.location);
return NO;
}
else
FLOG(@" no attachment at location %d", self.selectedRange.location);
}
return [super canPerformAction:action withSender:sender];
}