Объединение текста и изображений в `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;
                               }
                           }];
Другие вопросы по тегам