Объединение текста и изображений в `UITextView`
Прежде чем я начну, позвольте мне признать, что подобные вопросы существуют, некоторые с ответами, другие без. Тем не менее, они не решают мою конкретную проблему. Если вы знаете что-либо, пожалуйста, направьте меня.
Теперь, когда я добавляю изображения в UITextView
Я помещаю изображения в точку, где находится курсор. Я добиваюсь этого, добавляя 5 пробелов каждый раз, чтобы освободить место для изображения. Когда курсор доходит до конца UItextView
, он остается там без автоматического перехода к следующей строке, пока я не наберу клавишу. Даже когда я добавляю пробелы, они все еще остаются там, поэтому мои изображения просто накапливаются там. Я решил добавить разрыв строки "\n"
переместить его на следующую строку вручную. Теперь у меня две проблемы. Во-первых, отображается только часть изображений на углу, хотя у меня есть такое состояние:
if ((cursorPosition.x + 30) >= message.frame.width) {
message.text = message.text.stringByAppendingString("\n");
}
else {
message.text = message.text.stringByAppendingString(" ");
}
Как мне исправить это, чтобы оно не выходило за рамки?
Во-вторых, поскольку я добавляю новую строку вручную, когда я удаляю текст, курсор перемещается в какую-то произвольную позицию, что довольно странно для меня. Например, я мог бы удалить текст в строке 4, но он просто перейдет к строке 2. Любое предложение о том, как решить одну или обе проблемы, будет очень цениться. Ниже как UITextView
похоже:
Отредактировано: я редактирую это, чтобы помочь любому, у кого может быть подобная проблема. Я хотел создать приложение, в котором пользователи будут добавлять текст и изображения вместе, как мы делаем в WhatsApp
например. Я изо всех сил пытался сделать это, пока мне не предложили приведенное ниже решение. Работает отлично. Надеюсь, это поможет кому-то.
3 ответа
Если я понимаю вашу цель, и как вы в настоящее время ее реализовали. Вы должны проверить, если вам нужно вернуться первым.
if ((cursorPosition.x + 30) >= message.frame.width) {
message.text = message.text.stringByAppendingString("\n");
}
Затем вы должны получить текущую позицию курсора и добавить туда свой UIImageView.
let size = CGSize(width: 30, height: 30);
let img = UIImage(named: change_arr[indexPath.row]);
let addImg = UIImageView(image: UIImage(named: change_arr[indexPath.row]));
addImg.frame = CGRect(origin: newCursorPosition, size: size);
message.addSubview(addImg);
затем, если вам нужно добавить пробелы, добавьте их сейчас.
Как указано в предыдущих комментариях, использование NSTextAttachment упростит все это и избавит вас от необходимости создавать UIViews и т. Д.
это будет выглядеть примерно так, и вам не нужно проверять положение курсора, потому что он будет обрабатывать то же самое, что и с текстом.
//create your UIImage
let image = UIImage(named: change_arr[indexPath.row]);
//create and NSTextAttachment and add your image to it.
let attachment = NSTextAttachment()
attachment.image = image
//put your NSTextAttachment into and attributedString
let attString = NSAttributedString(attachment: attachment)
//add this attributed string to the current position.
textView.textStorage.insertAttributedString(attString, atIndex: textView.selectedRange.location)
Теперь изображение встроено и обрабатывается как текст. Если пользователь удаляет его, он удаляется так же, как текст.
На самом деле, я решил эту проблему с помощью класса NSAttributedString. Это позволяет программистам комбинировать изображения в текстовом буфере и обрабатываться так же, как один символ в буфере, что означает нажатие клавиши пробела курсором до того, как это изображение переместит изображение и весь другой текст на один пробел вправо. Аналогично нажатие клавиши удаления до того, как изображение удалит его из буфера. Надеюсь, это поможет кому-то
__block NSTextAttachment *imageAttachment = [NSTextAttachment new];
imageAttachment.bounds = CGRectMake(0, -5, 20, 20);
NSAttributedString *stringWithImage = [NSAttributedString attributedStringWithAttachment:imageAttachment];
[deCodedString replaceCharactersInRange:NSMakeRange(deCodedString.length, 0) withAttributedString:stringWithImage];
incomingMessage.messageAttributedString = deCodedString;
SDWebImageDownloader *downloader = [SDWebImageDownloader sharedDownloader];
imageAttachment.image = [UIImage imageNamed:@"profile_main_placeholder"];
[downloader downloadImageWithURL:aURL
options:0
progress:^(NSInteger receivedSize, NSInteger expectedSize) {
// progression tracking code
}
completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {
if (image && finished) {
[image drawInRect:CGRectMake(0, 0, 20, 20)];
imageAttachment.image = image;
dispatch_async(dispatch_get_main_queue(), ^(void)
{
[self.tbl_Conversation reloadRowsAtIndexPaths:[self.tbl_Conversation indexPathsForVisibleRows]
withRowAnimation:UITableViewRowAnimationNone];
[self.tbl_Conversation reloadData];
});
// NSAttributedString *stringWithImage = [NSAttributedString attributedStringWithAttachment:imageAttachment];
// [deCodedString replaceCharactersInRange:NSMakeRange(deCodedString.length, 0) withAttributedString:stringWithImage];
// incomingMessage.messageAttributedString = deCodedString;
}
}];