天天看點

iOS中使用textView進行圖文混排的上傳與顯示

在開始之前先看下效果圖,是不是你想要的。

iOS中使用textView進行圖文混排的上傳與顯示

(1)首先在viewDidLoad中設定3個屬性:

self.edgesForExtendedLayout = UIRectEdgeNone;
    self.extendedLayoutIncludesOpaqueBars = NO;
    self.modalPresentationCapturesStatusBarAppearance = NO;
           

    (2)然後擷取圖檔,将圖檔顯示在textView中:

#pragma mark - 相冊代理
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
    
    UIImage *image = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
    //圖檔儲存時每一張圖檔都要由一個名字,而相冊和拍照中傳回的info是不同的,但不管如何,都要想辦法給每張圖檔一個唯一的名字
    if (picker.sourceType ==UIImagePickerControllerSourceTypePhotoLibrary) {
        //擷取每張圖檔的id,用來作為儲存在沙盒中的檔案名
        NSString *getsrc=[NSString stringWithFormat:@"%@",(NSString *)[info objectForKey:@"UIImagePickerControllerReferenceURL"]];
        NSRange range={33,47};
        self.imageName=[NSString stringWithFormat:@"%@.jpg",[getsrc substringWithRange:range]];
    }
    if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
        self.imageName=[NSString stringWithFormat:@"%@.jpg",[[[info objectForKey:@"UIImagePickerControllerMediaMetadata"] objectForKey:@"{Exif}"] objectForKey:@"DateTimeDigitized"]];
        self.imageName = [self.imageName stringByReplacingOccurrencesOfString:@" " withString:@""];
    }
    
    NSString *identifierForVendor = [[UIDevice currentDevice].identifierForVendor UUIDString];
    self.imageName = [NSString stringWithFormat:@"%@%u.jpg",identifierForVendor,BARandomData];
    
    //儲存至沙盒
    [self saveImage:image WithName:self.imageName];
    
    //添加到附件中顯示圖檔
    [self addImageTextAttachmentImage:image];
    
    [self dismissModalViewControllerAnimated:YES];
    
    waitingDialog = [[MBProgressHUD alloc] init];
    [self.view addSubview:waitingDialog];
    [((MBProgressHUD *)waitingDialog) show:YES];
    
    [self dismissViewControllerAnimated:YES completion:^(void){
        [self onPostData];
    }];
    
    [self onPostData];
    [self.messageInputView becomeFirstResponder];
    
}
           

      (3)對選中的圖檔進行截取大小,并重新設定textView的輸入位置

//添加到附件中儲存圖檔
- (void)addImageTextAttachmentImage:(UIImage *)image {
    //适配螢幕寬度
    UIImage *image1 = [image scaleToSize:CGSizeMake(MSW - 20, image.size.height * MSW / image.size.width)];
    image = [self compressImage:image toMaxFileSize:0.2];
    _image_h = image1.size.height;
    _imageTextAttachment = [ImageTextAttachment new];
    
    image=[_imageTextAttachment scaleImage:image withSize:CGSizeMake(MSW - 30,_image_h)];
    //Set tag and image
    _imageTextAttachment.image = image;
    
    //Set image size
    _imageTextAttachment.imageSize = CGSizeMake(MSW - 30,_image_h);
    
    //Insert image image
    [self.messageInputView.textStorage insertAttributedString:[NSAttributedString attributedStringWithAttachment:_imageTextAttachment]
                                                      atIndex:self.messageInputView.selectedRange.location];
    
    
    //Move selection location
    self.messageInputView.selectedRange = NSMakeRange(self.messageInputView.selectedRange.location + 1, self.messageInputView.selectedRange.length);
    
    
    //設定輸入内容的設定
    [self setInitLocation];
    
    _imageTextAttachment.imageTag = ImageTag;
    
    //如果圖檔存在,則添加删除按鈕
    if (image != nil) {
        //将圖檔添加到數組
        [_itemArray addObject:image];
        
        //在圖檔上增加删除按鈕
        UIButton *deleteBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        deleteBtn.frame = CGRectMake(image.size.width - 20, _messageInputView.contentSize.height - _image_h - 10, 30, 30);
        [deleteBtn setImage:[UIImage imageNamed:@"Cricle_Delete"] forState:UIControlStateNormal];
        deleteBtn.imageEdgeInsets = UIEdgeInsetsMake(5, -5, 10, -5);
        deleteBtn.tag = _itemArray.count;
        [deleteBtn addTarget:self action:@selector(deleteImageFromChooseView:) forControlEvents:UIControlEventTouchUpInside];
        [_messageInputView addSubview:deleteBtn];
        
        //把圖檔的位置存在數組
        NSUInteger length = self.messageInputView.textStorage.length;
        [_imageLenthArray addObject:@(length)];
    }
    
    
    
}
           

      (4)最後,就是将所有的屬性字元串轉換成字元串,将圖檔位置周遊屬性字元串,然後用和背景約定好的字元串類型替換掉就好。比如我這裡和背景約定的是:圖檔的Url替換成{{p%lu}}     以下是兩種判斷方式,根據自己的需求即可。

#pragma mark - 将屬性字元串轉換成字元串
- (NSString *)textString
{
    NSAttributedString *attStr = _messageInputView.attributedText;
    
    NSMutableAttributedString *resutlAtt = [[NSMutableAttributedString alloc] initWithAttributedString:attStr];
    
    __block NSUInteger index = 1;
    __weak __typeof(self) weakSelf = self;
    //枚舉出所有的附件字元串
     __block NSUInteger base = 0;
    
    [attStr enumerateAttribute:NSAttachmentAttributeName inRange:NSMakeRange(0, attStr.length)
                     options:0
                  usingBlock:^(id value, NSRange range, BOOL *stop) {
                      if (value && [value isKindOfClass:[ImageTextAttachment class]]) {
                           NSString *p = [NSString stringWithFormat:@"{{p%lu}}", (unsigned long)index];
                          [resutlAtt replaceCharactersInRange:NSMakeRange(range.location + base, range.length)
                                                     withString:p];
                          if ([weakSelf.url isEqualToString:@""] || weakSelf.url == nil) {
                              
                              weakSelf.url = [NSString stringWithFormat:@"%@=%@", p, _imgUrlArray[index - 1]];
                          } else {
                              weakSelf.url = [NSString stringWithFormat:@"%@,%@=%@", weakSelf.url, p, _imgUrlArray[index - 1]];
                              
                          }
                          
                          base += p.length - 1;
                          index++;
                      }
                  }];

    
//    [attStr enumerateAttributesInRange:NSMakeRange(0, attStr.length) options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:^(NSDictionary *attrs, NSRange range, BOOL *stop) {
//        
//        //NSTextAttachment value類型 key-NSAttachment 從字典中取得那一個圖檔
//        //擷取目前替換字元串的長度
//        __block NSUInteger base = 0;
//        NSTextAttachment *textAtt = attrs[@"NSAttachment"];
//        if (textAtt)
//        {
//            NSString *p = [NSString stringWithFormat:@"{{p%lu}}", (unsigned long)index];
//            [resutlAtt replaceCharactersInRange:NSMakeRange(range.location + base, range.length)
//                                     withString:p];
//            if ([weakSelf.url isEqualToString:@""] || weakSelf.url == nil) {
//                
//                weakSelf.url = [NSString stringWithFormat:@"%@=%@", p, _imgUrlArray[index]];
//            } else {
//                weakSelf.url = [NSString stringWithFormat:@"%@,%@=%@", weakSelf.url, p, _imgUrlArray[index]];
//                
//            }
//            
//            base += p.length;
//            index++;
//            
//        }
//        
//    }];
    
    DLog(@"---resutlAtt.string----- %@", resutlAtt.string)
    return resutlAtt.string;
    
}
           

       (5)最後就大功告成了,你隻需要将最後拼接好的哪一個字元串傳給背景就好,然後在你需要顯示這個内容的地方。将所擷取的字元串轉換成屬性字元串就好,然後指派給textView的attributeText就好。

繼續閱讀