真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

iOS開(kāi)發(fā)之微信聊天頁(yè)面怎么實(shí)現(xiàn)-創(chuàng)新互聯(lián)

這篇文章主要介紹iOS開(kāi)發(fā)之微信聊天頁(yè)面怎么實(shí)現(xiàn) ,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

成都創(chuàng)新互聯(lián)是一家專業(yè)提供雙城企業(yè)網(wǎng)站建設(shè),專注與網(wǎng)站建設(shè)、成都網(wǎng)站建設(shè)、HTML5、小程序制作等業(yè)務(wù)。10年已為雙城眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)絡(luò)公司優(yōu)惠進(jìn)行中。

聊天界面的效果圖如下:在下面的聊天界面中中用到了3類cell,一類是顯示文字和表情的,一類是顯示錄音的,一類是顯示圖片的。當(dāng)點(diǎn)擊圖片時(shí)會(huì)跳轉(zhuǎn)到另一個(gè)Controller中來(lái)進(jìn)行圖片顯示,在圖片顯示頁(yè)面中添加了一個(gè)捏合的手勢(shì)。點(diǎn)擊播放按鈕,會(huì)播放錄制的音頻,cell的大學(xué)會(huì)根據(jù)內(nèi)容的多少來(lái)調(diào)整,而cell中textView的高度是通過(guò)約束來(lái)設(shè)置的。

iOS開(kāi)發(fā)之微信聊天頁(yè)面怎么實(shí)現(xiàn)

一,定義我們要用的cell,代碼如下:

  1,顯示表情和text的cell,代碼如下,需要根據(jù)NSMutableAttributedString求出bound,然后改變cell上的ImageView和TextView的寬度的約束值,動(dòng)態(tài)的調(diào)整氣泡的大小,具體代碼如下:

#import "TextCell.h"

@interface TextCell()

@property (strong, nonatomic) IBOutlet UIImageView *headImageView;
@property (strong, nonatomic) IBOutlet UIImageView *chatBgImageView;
@property (strong, nonatomic) IBOutlet UITextView *chatTextView;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *chatBgImageWidthConstraint;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *chatTextWidthConstaint;
@property (strong, nonatomic) NSMutableAttributedString *attrString;

@end

@implementation TextCell

-(void)setCellValue:(NSMutableAttributedString *)str
{
    //移除約束
    [self removeConstraint:_chatBgImageWidthConstraint];
    [self removeConstraint:_chatTextWidthConstaint];
    
    self.attrString = str;
    NSLog(@"%@",self.attrString);
    
    //由text計(jì)算出text的寬高
      CGRect bound = [self.attrString boundingRectWithSize:CGSizeMake(150, 1000) options:NSStringDrawingUsesLineFragmentOrigin context:nil];
   
    //根據(jù)text的寬高來(lái)重新設(shè)置新的約束
    //背景的寬
    NSString *widthImageString;
    NSArray *tempArray;
    
    widthImageString = [NSString stringWithFormat:@"H:[_chatBgImageView(%f)]", bound.size.width+45];
    tempArray = [NSLayoutConstraint constraintsWithVisualFormat:widthImageString options:0 metrics:0 views:NSDictionaryOfVariableBindings(_chatBgImageView)];
    _chatBgImageWidthConstraint = tempArray[0];
    [self addConstraint:self.chatBgImageWidthConstraint];
    
    widthImageString = [NSString stringWithFormat:@"H:[_chatTextView(%f)]", bound.size.width+20];
    tempArray = [NSLayoutConstraint constraintsWithVisualFormat:widthImageString options:0 metrics:0 views:NSDictionaryOfVariableBindings(_chatTextView)];
    _chatBgImageWidthConstraint = tempArray[0];
    [self addConstraint:self.chatBgImageWidthConstraint];
    
    //設(shè)置圖片
    UIImage *image = [UIImage imageNamed:@"chatfrom_bg_normal.png"];
    image = [image resizableImageWithCapInsets:(UIEdgeInsetsMake(image.size.height * 0.6, image.size.width * 0.4, image.size.height * 0.3, image.size.width * 0.4))];
    
    //image = [image stretchableImageWithLeftCapWidth:image.size.width * 0.5 topCapHeight:image.size.height * 0.5];
    
    
    
    [self.chatBgImageView setImage:image];
    
    self.chatTextView.attributedText = str;
    
    
}

@end

2.顯示圖片的cell,通過(guò)block回調(diào)把圖片傳到Controller中,用于放大圖片使用。

#import "MyImageCell.h"

@interface MyImageCell()
@property (strong, nonatomic) IBOutlet UIImageView *bgImageView;
@property (strong, nonatomic) IBOutlet UIButton *imageButton;
@property (strong, nonatomic) ButtonImageBlock imageBlock;
@property (strong, nonatomic) UIImage *buttonImage;

@end

@implementation MyImageCell

-(void)setCellValue:(UIImage *)sendImage
{
    self.buttonImage = sendImage;
    UIImage *image = [UIImage imageNamed:@"chatto_bg_normal.png"];
    image = [image resizableImageWithCapInsets:(UIEdgeInsetsMake(image.size.height * 0.6, image.size.width * 0.4, image.size.height * 0.3, image.size.width * 0.4))];
    [self.bgImageView setImage:image];
    [self.imageButton setImage:sendImage forState:UIControlStateNormal];

}

-(void)setButtonImageBlock:(ButtonImageBlock)block
{
    self.imageBlock = block;
}

- (IBAction)tapImageButton:(id)sender {
    self.imageBlock(self.buttonImage);
}

@end

3.顯示錄音的cell,點(diǎn)擊cell上的button,播放對(duì)應(yīng)的錄音,代碼如下:

#import "VoiceCellTableViewCell.h"

@interface VoiceCellTableViewCell()

@property (strong, nonatomic) NSURL *playURL;
@property (strong, nonatomic) AVAudioPlayer *audioPlayer;

@end

@implementation VoiceCellTableViewCell

-(void)setCellValue:(NSDictionary *)dic
{
    _playURL = dic[@"body"][@"content"];
}

- (IBAction)tapVoiceButton:(id)sender {
    
    
    NSError *error = nil;
    AVAudioPlayer *player = [[AVAudioPlayer alloc]initWithContentsOfURL:_playURL error:&error];
    if (error) {
        NSLog(@"播放錯(cuò)誤:%@",[error description]);
    }
    self.audioPlayer = player;
    [self.audioPlayer play];
}
@end

二,cell搞定后要實(shí)現(xiàn)我們的ChatController部分    

ChatController.m中的延展和枚舉代碼如下:

//枚舉Cell類型
typedef enum : NSUInteger {
    SendText,
    SendVoice,
    SendImage
} MySendContentType;


//枚舉用戶類型
typedef enum : NSUInteger {
    MySelf,
    MyFriend
} UserType;

@interface ChatViewController ()

//工具欄
@property (nonatomic,strong) ToolView *toolView;

//音量圖片
@property (strong, nonatomic) UIImageView *volumeImageView;

//工具欄的高約束,用于當(dāng)輸入文字過(guò)多時(shí)改變工具欄的約束
@property (strong, nonatomic) NSLayoutConstraint *tooViewConstraintHeight;

//存放所有的cell中的內(nèi)容
@property (strong, nonatomic) NSMutableArray *dataSource;

//storyBoard上的控件
@property (strong, nonatomic) IBOutlet UITableView *myTableView;

//用戶類型
@property (assign, nonatomic) UserType userType;

//從相冊(cè)獲取圖片
@property (strong, nonatomic) UIImagePickerController *imagePiceker;

@end

實(shí)現(xiàn)工具欄中的回調(diào)的代碼如下,通過(guò)Block,工具欄和ViewController交互

//實(shí)現(xiàn)工具欄的回調(diào)
-(void)setToolViewBlock
{
    __weak __block ChatViewController *copy_self = self;
    //通過(guò)block回調(diào)接收到toolView中的text
    [self.toolView setMyTextBlock:^(NSString *myText) {
        NSLog(@"%@",myText);
        
        [copy_self sendMessage:SendText Content:myText];
    }];
    
    
    //回調(diào)輸入框的contentSize,改變工具欄的高度
    [self.toolView setContentSizeBlock:^(CGSize contentSize) {
         [copy_self updateHeight:contentSize];
    }];
    
    
    //獲取錄音聲量,用于聲音音量的提示
    [self.toolView setAudioVolumeBlock:^(CGFloat volume) {
        
        copy_self.volumeImageView.hidden = NO;
        int index = (int)(volume*100)%6+1;
        [copy_self.volumeImageView setImage:[UIImage imageNamed:[NSString stringWithFormat:@"record_animate_%02d.png",index]]];
    }];
    
    //獲取錄音地址(用于錄音播放方法)
    [self.toolView setAudioURLBlock:^(NSURL *audioURL) {
        copy_self.volumeImageView.hidden = YES;
        
        [copy_self sendMessage:SendVoice Content:audioURL];
    }];
    
    //錄音取消(錄音取消后,把音量圖片進(jìn)行隱藏)
    [self.toolView setCancelRecordBlock:^(int flag) {
        if (flag == 1) {
            copy_self.volumeImageView.hidden = YES;
        }
    }];
    
    
    //擴(kuò)展功能回調(diào)
    [self.toolView setExtendFunctionBlock:^(int buttonTag) {
        switch (buttonTag) {
            case 1:
                //從相冊(cè)獲取
                [copy_self presentViewController:copy_self.imagePiceker animated:YES completion:^{
                    
                }];
                break;
            case 2:
                //拍照
                break;
                
            default:
                break;
        }
    }];
}

把聊天工具欄中返回的內(nèi)容顯示在tableView中,代碼如下:

//發(fā)送消息
-(void)sendMessage:(MySendContentType) sendType Content:(id)content
{
    
    //把收到的url封裝成字典
    UserType userType = self.userType;
    
    NSMutableDictionary *tempDic = [[NSMutableDictionary alloc] initWithCapacity:2];
    [tempDic setValue:@(userType) forKey:@"userType"];
    
    NSDictionary *bodyDic = @{@"type":@(sendType),
                              @"content":content};
    [tempDic setValue:bodyDic forKey:@"body"];
    [self.dataSource addObject:tempDic];
    
    //重載tableView
    [self.myTableView  reloadData];
    
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self.dataSource.count-1 inSection:0];
    
    [self.myTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
    
 
}

根據(jù)ToolView中回調(diào)接口,獲取工具欄中textView的ContentSize,通過(guò)ContentSize來(lái)調(diào)整ToolView的高度約束,代碼如下:

//更新toolView的高度約束
-(void)updateHeight:(CGSize)contentSize
{
    float height = contentSize.height + 18;
    if (height <= 80) {
        [self.view removeConstraint:self.tooViewConstraintHeight];
        
        NSString *string = [NSString stringWithFormat:@"V:[_toolView(%f)]", height];
        
        NSArray * tooViewConstraintV = [NSLayoutConstraint constraintsWithVisualFormat:string options:0 metrics:0 views:NSDictionaryOfVariableBindings(_toolView)];
        self.tooViewConstraintHeight = tooViewConstraintV[0];
        [self.view addConstraint:self.tooViewConstraintHeight];
    }
}

從本地獲取圖片,并顯示在相應(yīng)的Cell上,代碼如下:

//獲取圖片后要做的方法
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    UIImage *pickerImage = info[UIImagePickerControllerEditedImage];
    
    //發(fā)送圖片
    [self sendMessage:SendImage Content:pickerImage];
    
    [self dismissViewControllerAnimated:YES completion:^{}];
    
}

-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    //在ImagePickerView中點(diǎn)擊取消時(shí)回到原來(lái)的界面
    [self dismissViewControllerAnimated:YES completion:^{}];
}

把NSString 轉(zhuǎn)換成NSMutableAttributeString,用于顯示表情,代碼如下:

//顯示表情,用屬性字符串顯示表情
-(NSMutableAttributedString *)showFace:(NSString *)str
{
    //加載plist文件中的數(shù)據(jù)
    NSBundle *bundle = [NSBundle mainBundle];
    //尋找資源的路徑
    NSString *path = [bundle pathForResource:@"emoticons" ofType:@"plist"];
    //獲取plist中的數(shù)據(jù)
    NSArray *face = [[NSArray alloc] initWithContentsOfFile:path];
    
    //創(chuàng)建一個(gè)可變的屬性字符串
    
    NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:str];
    
    UIFont *baseFont = [UIFont systemFontOfSize:17];
    [attributeString addAttribute:NSFontAttributeName value:baseFont
                       range:NSMakeRange(0, str.length)];
    
    //正則匹配要替換的文字的范圍
    //正則表達(dá)式
    NSString * pattern = @"\\[[a-zA-Z0-9\\u4e00-\\u9fa5]+\\]";
    NSError *error = nil;
    NSRegularExpression * re = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:&error];
    
    if (!re) {
        NSLog(@"%@", [error localizedDescription]);
    }
    
    //通過(guò)正則表達(dá)式來(lái)匹配字符串
    NSArray *resultArray = [re matchesInString:str options:0 range:NSMakeRange(0, str.length)];
    
    
    //用來(lái)存放字典,字典中存儲(chǔ)的是圖片和圖片對(duì)應(yīng)的位置
    NSMutableArray *imageArray = [NSMutableArray arrayWithCapacity:resultArray.count];
    
    //根據(jù)匹配范圍來(lái)用圖片進(jìn)行相應(yīng)的替換
    for(NSTextCheckingResult *match in resultArray) {
        //獲取數(shù)組元素中得到range
        NSRange range = [match range];
        
        //獲取原字符串中對(duì)應(yīng)的值
        NSString *subStr = [str substringWithRange:range];
        
        for (int i = 0; i < face.count; i ++)
        {
            if ([face[i][@"chs"] isEqualToString:subStr])
            {
                
                //face[i][@"gif"]就是我們要加載的圖片
                //新建文字附件來(lái)存放我們的圖片
                NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init];
                
                //給附件添加圖片
                textAttachment.image = [UIImage imageNamed:face[i][@"png"]];
                
                //把附件轉(zhuǎn)換成可變字符串,用于替換掉源字符串中的表情文字
                NSAttributedString *imageStr = [NSAttributedString attributedStringWithAttachment:textAttachment];
                
                //把圖片和圖片對(duì)應(yīng)的位置存入字典中
                NSMutableDictionary *imageDic = [NSMutableDictionary dictionaryWithCapacity:2];
                [imageDic setObject:imageStr forKey:@"image"];
                [imageDic setObject:[NSValue valueWithRange:range] forKey:@"range"];
                
                //把字典存入數(shù)組中
                [imageArray addObject:imageDic];
                
            }
        }
    }
    
    //從后往前替換
    for (int i = imageArray.count -1; i >= 0; i--)
    {
        NSRange range;
        [imageArray[i][@"range"] getValue:&range];
        //進(jìn)行替換
        [attributeString replaceCharactersInRange:range withAttributedString:imageArray[i][@"image"]];
        
    }
    
    return  attributeString;
}

根據(jù)Cell顯示內(nèi)容來(lái)調(diào)整Cell的高度,代碼如下:

//調(diào)整cell的高度
-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    
    //根據(jù)文字計(jì)算cell的高度
    if ([self.dataSource[indexPath.row][@"body"][@"type"] isEqualToNumber:@(SendText)]) {
        NSMutableAttributedString *contentText = [self showFace:self.dataSource[indexPath.row][@"body"][@"content"]];
        
        CGRect textBound = [contentText boundingRectWithSize:CGSizeMake(150, 1000) options:NSStringDrawingUsesLineFragmentOrigin context:nil];
        
        float height = textBound.size.height + 40;
        return height;
    }
    if ([self.dataSource[indexPath.row][@"body"][@"type"] isEqualToNumber:@(SendVoice)])
    {
        return 73;
    }
    
    if ([self.dataSource[indexPath.row][@"body"][@"type"] isEqualToNumber:@(SendImage)])
    {
        return 125;
    }
    
    return 100;
 }

根據(jù)cell內(nèi)容和用戶類型,來(lái)選擇Cell,代碼如下:

//設(shè)置cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //根據(jù)類型選cell
    MySendContentType contentType = [self.dataSource[indexPath.row][@"body"][@"type"] integerValue];
    
    
    if ([self.dataSource[indexPath.row][@"userType"]  isEqual: @(MyFriend)]) {
        switch (contentType) {
            case SendText:
            {
                TextCell *cell = [tableView dequeueReusableCellWithIdentifier:@"textCell" forIndexPath:indexPath];
                NSMutableAttributedString *contentText = [self showFace:self.dataSource[indexPath.row][@"body"][@"content"]];
                [cell setCellValue:contentText];
                return cell;
            }
                break;
                
            case SendImage:
            {
                heImageCell *cell = [tableView dequeueReusableCellWithIdentifier:@"heImageCell" forIndexPath:indexPath];
                [cell setCellValue:self.dataSource[indexPath.row][@"body"][@"content"]];
                
                
                __weak __block ChatViewController *copy_self = self;
                
                //傳出cell中的圖片
                [cell setButtonImageBlock:^(UIImage *image) {
                    [copy_self displaySendImage:image];
                }];
                return cell;
            }
                break;
                
            case SendVoice:
            {
                VoiceCellTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"heVoiceCell" forIndexPath:indexPath];
                [cell setCellValue:self.dataSource[indexPath.row]];
                return cell;
            }

                break;
                
            default:
                break;
        }

    }
        

    if ([self.dataSource[indexPath.row][@"userType"]  isEqual: @(MySelf)]) {
    
        switch (contentType) {
            case SendText:
            {
                TextCell *cell = [tableView dequeueReusableCellWithIdentifier:@"myselfTextCell" forIndexPath:indexPath];
                NSMutableAttributedString *contentText = [self showFace:self.dataSource[indexPath.row][@"body"][@"content"]];
                [cell setCellValue:contentText];
                return cell;
            }
            break;
            
            case SendImage:
            {
                MyImageCell *cell = [tableView dequeueReusableCellWithIdentifier:@"myImageCell" forIndexPath:indexPath];
                [cell setCellValue:self.dataSource[indexPath.row][@"body"][@"content"]];
                
                __weak __block ChatViewController *copy_self = self;
                
                //傳出cell中的圖片
                [cell setButtonImageBlock:^(UIImage *image) {
                    [copy_self displaySendImage:image];
                }];

                
                return cell;
            }
                break;
            
            case SendVoice:
            {
                VoiceCellTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"myVoiceCell" forIndexPath:indexPath];
                [cell setCellValue:self.dataSource[indexPath.row]];
                return cell;
            }

                break;
                
            default:
                break;
        }
    }
    UITableViewCell *cell;
    return cell;
}

點(diǎn)擊發(fā)送的圖片來(lái)放大圖片代碼如下:

//發(fā)送圖片的放大
-(void) displaySendImage : (UIImage *)image
{
    //把照片傳到放大的controller中
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
    
    ImageViewController *imageController = [storyboard instantiateViewControllerWithIdentifier:@"imageController"];
    [imageController setValue:image forKeyPath:@"image"];
    
   [self.navigationController pushViewController:imageController animated:YES];
    

}

根據(jù)鍵盤(pán)的高度來(lái)調(diào)整ToolView的位置,代碼如下:

//鍵盤(pán)出來(lái)的時(shí)候調(diào)整tooView的位置
-(void) keyChange:(NSNotification *) notify
{
    NSDictionary *dic = notify.userInfo;
    
    
    CGRect endKey = [dic[@"UIKeyboardFrameEndUserInfoKey"] CGRectValue];
    //坐標(biāo)系的轉(zhuǎn)換
    CGRect endKeySwap = [self.view convertRect:endKey fromView:self.view.window];
    //運(yùn)動(dòng)時(shí)間
    [UIView animateWithDuration:[dic[UIKeyboardAnimationDurationUserInfoKey] floatValue] animations:^{
        
        [UIView setAnimationCurve:[dic[UIKeyboardAnimationCurveUserInfoKey] doubleValue]];
        CGRect frame = self.view.frame;
        
        frame.size.height = endKeySwap.origin.y;
        
        self.view.frame = frame;
        [self.view layoutIfNeeded];
    }];
}

代碼有點(diǎn)多,不過(guò)在關(guān)鍵的部分都加有注釋,在圖片顯示View中通過(guò)捏合手勢(shì)來(lái)調(diào)整圖片的大小,代碼如下:

- (IBAction)tapPichGesture:(id)sender {
    UIPinchGestureRecognizer *gesture = sender;
    
    //手勢(shì)改變時(shí)
    if (gesture.state == UIGestureRecognizerStateChanged)
    {
        
        //捏合手勢(shì)中scale屬性記錄的縮放比例
        self.myImageView.transform = CGAffineTransformMakeScale(gesture.scale, gesture.scale);
    }
    
}

以上是“iOS開(kāi)發(fā)之微信聊天頁(yè)面怎么實(shí)現(xiàn) ”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!


當(dāng)前文章:iOS開(kāi)發(fā)之微信聊天頁(yè)面怎么實(shí)現(xiàn)-創(chuàng)新互聯(lián)
標(biāo)題網(wǎng)址:http://weahome.cn/article/ccgsce.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部