精华内容
下载资源
问答
  • 前段时间只看,没有手动写过代码,今天无聊就写了一个画聊天对话框的例子,其实还是蛮实用的,以后一定会有用到的地方。 主要用到Quartz的几个关键技术 路径,阴影,填充,描边,图像上下文环境的设置。 ...

    原文转自:http://donbe.blog.163.com/blog/static/13804802120106302487518/

    前段时间只看,没有手动写过代码,今天无聊就写了一个画聊天对话框的例子,其实还是蛮实用的,以后一定会有用到的地方。

    主要用到Quartz的几个关键技术
    路径,阴影,填充,描边,图像上下文环境的设置。
    效果图:

    用 Quartz 只做聊天对话框背景实例 - happy dog - 又一个部落格
     
    以下是代码:

    CGContextRef MyCreateBitmapContext (int pixelsWide,
    int pixelsHigh)
    {
        CGContextRef    context = NULL;
        CGColorSpaceRef colorSpace;
        void *          bitmapData;
        int             bitmapByteCount;
        int             bitmapBytesPerRow;
        
        //声明一个变量来代表每行的字节数。每一个位图像素的代表是4个字节,8bit红,8bit绿,8bit蓝,和8bit alpha通道信息(透明信息)。
        bitmapBytesPerRow   = (pixelsWide * 4);
        bitmapByteCount     = (bitmapBytesPerRow * pixelsHigh);
        colorSpace = CGColorSpaceCreateDeviceRGB();// 创建一个通用的RGB色彩空间
        bitmapData = malloc( bitmapByteCount );// 调用的malloc函数来创建的内存用来存储位图数据块
        if (bitmapData == NULL)
        {
            fprintf (stderr, "Memory not allocated!");
            return NULL;
        }
        
        //创建一个位图图形上下文
        context = CGBitmapContextCreate (bitmapData,
     pixelsWide,
     pixelsHigh,
     8,      // bits per component
     bitmapBytesPerRow,
     colorSpace,
    kCGImageAlphaPremultipliedLast);
        if (context== NULL)
        {
            free (bitmapData);
            fprintf (stderr, "Context not created!");
            return NULL;
        }
        //释放colorSpace 注意使用的函数
        CGColorSpaceRelease( colorSpace );
        return context;
    }

    /*
     生成一个聊天的对话框背景图
     参数
     myContext:一个图形上下文
     ox: 矩形左下角x坐标
     oy: 矩形左下角y坐标
     rw: 矩形宽度
     rh: 矩形高度
     r : 矩形圆角半径
     Orientation: 箭头方向,0-7 
     */
    UIImage* createDialogBox (CGContextRef myContext, float ox, float oy, float rw, float rh, float r,  int Orientation)
    {
    CGMutablePathRef path = CGPathCreateMutable();
    //画矩形
    CGPathMoveToPoint(path, NULL,ox, oy+r);
    CGPathAddArcToPoint(path, NULL, ox, oy+rh, ox+r,oy+rh, r);
    CGPathAddArcToPoint(path, NULL, ox+rw, oy+rh, ox+rw, oy+rh-r, r);
    CGPathAddArcToPoint(path, NULL, ox+rw, oy, ox+rw-r, oy, r);
    CGPathAddArcToPoint(path, NULL, ox, oy, ox,oy+r,r);
    //画箭头
    switch (Orientation) {
    case 0:
    CGPathMoveToPoint(path, NULL,ox+r+10.0, oy+rh);
    CGPathAddLineToPoint(path, NULL, ox+r+10.0, oy+rh+20);
    CGPathAddLineToPoint(path, NULL, ox+r+30.0, oy+rh);
    break;
    case 1:
    CGPathMoveToPoint(path, NULL,ox+rw-r-10.0, oy+rh);
    CGPathAddLineToPoint(path, NULL, ox+rw-r-10.0, oy+rh+20);
    CGPathAddLineToPoint(path, NULL, ox+rw-r-30.0, oy+rh);
    break;
    case 2:
    CGPathMoveToPoint(path, NULL,ox+rw, oy+rh-r-10);
    CGPathAddLineToPoint(path, NULL, ox+rw+20, oy+rh-r-10);
    CGPathAddLineToPoint(path, NULL, ox+rw, oy+rh-r-30);
    break;
    case 3:
    CGPathMoveToPoint(path, NULL,ox+rw, oy+r+10);
    CGPathAddLineToPoint(path, NULL, ox+rw+20, oy+r+10);
    CGPathAddLineToPoint(path, NULL, ox+rw, oy+r+30);
    break;
    case 4:
    CGPathMoveToPoint(path, NULL,ox+rw-r-10.0, oy);
    CGPathAddLineToPoint(path, NULL, ox+rw-r-10.0, oy-20);
    CGPathAddLineToPoint(path, NULL, ox+rw-r-30.0, oy);
    break;
    case 5:
    CGPathMoveToPoint(path, NULL,ox+r+10.0, oy);
    CGPathAddLineToPoint(path, NULL, ox+r+10.0, oy-20);
    CGPathAddLineToPoint(path, NULL, ox+r+30.0, oy);
    break;
    case 6:
    CGPathMoveToPoint(path, NULL,ox, oy+r+10);
    CGPathAddLineToPoint(path, NULL, ox-20, oy+r+10);
    CGPathAddLineToPoint(path, NULL, ox, oy+r+30);
    break;
    case 7:
    CGPathMoveToPoint(path, NULL,ox, oy+rh-r-10);
    CGPathAddLineToPoint(path, NULL, ox-20, oy+rh-r-10);
    CGPathAddLineToPoint(path, NULL, ox, oy+rh-r-30);
    break;
    default:
    break;
    }
    //描边 以及添加阴影效果
    CGContextSetLineJoin(myContext, kCGLineJoinRound);
    CGFloat zStrokeColour[4]    = {180.0/255, 180.0/255.0, 180.0/255.0, 1.0};
    CGContextSetLineWidth(myContext, 13.0);
    CGContextAddPath(myContext,path);
    CGContextSetStrokeColorSpace(myContext, CGColorSpaceCreateDeviceRGB());
    CGContextSetStrokeColor(myContext, zStrokeColour);
    CGContextStrokePath(myContext);
    CGSize myShadowOffset = CGSizeMake (0,  0);
        CGContextSaveGState(myContext);

        CGContextSetShadow (myContext, myShadowOffset, 5);
    CGContextSetLineJoin(myContext, kCGLineJoinRound);
    CGFloat zStrokeColour1[4]    = {228.0/255, 168.0/255.0, 81.0/255.0, 1.0};
    CGContextSetLineWidth(myContext, 3.0);
    CGContextAddPath(myContext,path);
    CGContextSetStrokeColorSpace(myContext, CGColorSpaceCreateDeviceRGB());
    CGContextSetStrokeColor(myContext, zStrokeColour1);
    CGContextStrokePath(myContext);
    CGContextRestoreGState(myContext);
    //填充矩形内部颜色
    CGContextAddPath(myContext,path);
    CGContextSetFillColorSpace(myContext, CGColorSpaceCreateDeviceRGB());
    CGFloat zFillColour1[4]    = {229.0/255, 229.0/255.0, 231.0/255.0, 1};
    CGContextSetFillColor(myContext, zFillColour1);
    CGContextEOFillPath(myContext);
    //生成图像
    CGImageRef myImage = CGBitmapContextCreateImage (myContext);
    UIImage * image = [UIImage imageWithCGImage:myImage];
    CGImageRelease(myImage);
    return image;
    }


    - (void)viewDidLoad {
    [super viewDidLoad];
    float wd = 320.0;
    float ht = 480.0;
    CGContextRef myContext = MyCreateBitmapContext (wd, ht);

    UIImageView *iv = [[UIImageView alloc] initWithImage:createDialogBox(myContext, 50, 350, 100, 60, 5, 7)];
    [self.view addSubview:iv];
    CGContextRelease (myContext);
    [iv release];
    }
    展开全文
  • 前段时间只看,没有手动写过代码,今天无聊就写了一个画聊天对话框的例子,其实还是蛮实用的,以后一定会有用到的地方。 主要用到Quartz的几个关键技术 路径,阴影,填充,描边,图像上下文环境的设置。 ...
    
    

    前段时间只看,没有手动写过代码,今天无聊就写了一个画聊天对话框的例子,其实还是蛮实用的,以后一定会有用到的地方。

    主要用到Quartz的几个关键技术
    路径,阴影,填充,描边,图像上下文环境的设置。
    效果图:

    用 Quartz 只做聊天对话框背景实例 - happy dog - 又一个部落格
     
    以下是代码:

    CGContextRef MyCreateBitmapContext (int pixelsWide,
    int pixelsHigh)
    {
        CGContextRef    context = NULL;
        CGColorSpaceRef colorSpace;
        void *          bitmapData;
        int             bitmapByteCount;
        int             bitmapBytesPerRow;
        
        //声明一个变量来代表每行的字节数。每一个位图像素的代表是4个字节,8bit红,8bit绿,8bit蓝,和8bit alpha通道信息(透明信息)。
        bitmapBytesPerRow   = (pixelsWide * 4);
        bitmapByteCount     = (bitmapBytesPerRow * pixelsHigh);
        colorSpace = CGColorSpaceCreateDeviceRGB();// 创建一个通用的RGB色彩空间
        bitmapData = malloc( bitmapByteCount );// 调用的malloc函数来创建的内存用来存储位图数据块
        if (bitmapData == NULL)
        {
            fprintf (stderr, "Memory not allocated!");
            return NULL;
        }
        
        //创建一个位图图形上下文
        context = CGBitmapContextCreate (bitmapData,
     pixelsWide,
     pixelsHigh,
     8,      // bits per component
     bitmapBytesPerRow,
     colorSpace,
     kCGImageAlphaPremultipliedLast);
        if (context== NULL)
        {
            free (bitmapData);
            fprintf (stderr, "Context not created!");
            return NULL;
        }
        //释放colorSpace 注意使用的函数
        CGColorSpaceRelease( colorSpace );
        return context;
    }

    /*
     生成一个聊天的对话框背景图
     参数
     myContext:一个图形上下文
     ox: 矩形左下角x坐标
     oy: 矩形左下角y坐标
     rw: 矩形宽度
     rh: 矩形高度
     r : 矩形圆角半径
     Orientation: 箭头方向,0-7 
     */
    UIImage* createDialogBox (CGContextRef myContext, float ox, float oy, float rw, float rh, float r,  int Orientation)
    {
    CGMutablePathRef path = CGPathCreateMutable();
    //画矩形
    CGPathMoveToPoint(path, NULL,ox, oy+r);
    CGPathAddArcToPoint(path, NULL, ox, oy+rh, ox+r,oy+rh, r);
    CGPathAddArcToPoint(path, NULL, ox+rw, oy+rh, ox+rw, oy+rh-r, r);
    CGPathAddArcToPoint(path, NULL, ox+rw, oy, ox+rw-r, oy, r);
    CGPathAddArcToPoint(path, NULL, ox, oy, ox,oy+r,r);
    //画箭头
    switch (Orientation) {
    case 0:
    CGPathMoveToPoint(path, NULL,ox+r+10.0, oy+rh);
    CGPathAddLineToPoint(path, NULL, ox+r+10.0, oy+rh+20);
    CGPathAddLineToPoint(path, NULL, ox+r+30.0, oy+rh);
    break;
    case 1:
    CGPathMoveToPoint(path, NULL,ox+rw-r-10.0, oy+rh);
    CGPathAddLineToPoint(path, NULL, ox+rw-r-10.0, oy+rh+20);
    CGPathAddLineToPoint(path, NULL, ox+rw-r-30.0, oy+rh);
    break;
    case 2:
    CGPathMoveToPoint(path, NULL,ox+rw, oy+rh-r-10);
    CGPathAddLineToPoint(path, NULL, ox+rw+20, oy+rh-r-10);
    CGPathAddLineToPoint(path, NULL, ox+rw, oy+rh-r-30);
    break;
    case 3:
    CGPathMoveToPoint(path, NULL,ox+rw, oy+r+10);
    CGPathAddLineToPoint(path, NULL, ox+rw+20, oy+r+10);
    CGPathAddLineToPoint(path, NULL, ox+rw, oy+r+30);
    break;
    case 4:
    CGPathMoveToPoint(path, NULL,ox+rw-r-10.0, oy);
    CGPathAddLineToPoint(path, NULL, ox+rw-r-10.0, oy-20);
    CGPathAddLineToPoint(path, NULL, ox+rw-r-30.0, oy);
    break;
    case 5:
    CGPathMoveToPoint(path, NULL,ox+r+10.0, oy);
    CGPathAddLineToPoint(path, NULL, ox+r+10.0, oy-20);
    CGPathAddLineToPoint(path, NULL, ox+r+30.0, oy);
    break;
    case 6:
    CGPathMoveToPoint(path, NULL,ox, oy+r+10);
    CGPathAddLineToPoint(path, NULL, ox-20, oy+r+10);
    CGPathAddLineToPoint(path, NULL, ox, oy+r+30);
    break;
    case 7:
    CGPathMoveToPoint(path, NULL,ox, oy+rh-r-10);
    CGPathAddLineToPoint(path, NULL, ox-20, oy+rh-r-10);
    CGPathAddLineToPoint(path, NULL, ox, oy+rh-r-30);
    break;
    default:
    break;
    }
    //描边 以及添加阴影效果
    CGContextSetLineJoin(myContext, kCGLineJoinRound);
    CGFloat zStrokeColour[4]    = {180.0/255, 180.0/255.0, 180.0/255.0, 1.0};
    CGContextSetLineWidth(myContext, 13.0);
    CGContextAddPath(myContext,path);
    CGContextSetStrokeColorSpace(myContext, CGColorSpaceCreateDeviceRGB());
    CGContextSetStrokeColor(myContext, zStrokeColour);
    CGContextStrokePath(myContext);
    CGSize myShadowOffset = CGSizeMake (0,  0);
        CGContextSaveGState(myContext);

        CGContextSetShadow (myContext, myShadowOffset, 5);
    CGContextSetLineJoin(myContext, kCGLineJoinRound);
    CGFloat zStrokeColour1[4]    = {228.0/255, 168.0/255.0, 81.0/255.0, 1.0};
    CGContextSetLineWidth(myContext, 3.0);
    CGContextAddPath(myContext,path);
    CGContextSetStrokeColorSpace(myContext, CGColorSpaceCreateDeviceRGB());
    CGContextSetStrokeColor(myContext, zStrokeColour1);
    CGContextStrokePath(myContext);
    CGContextRestoreGState(myContext);
    //填充矩形内部颜色
    CGContextAddPath(myContext,path);
    CGContextSetFillColorSpace(myContext, CGColorSpaceCreateDeviceRGB());
    CGFloat zFillColour1[4]    = {229.0/255, 229.0/255.0, 231.0/255.0, 1};
    CGContextSetFillColor(myContext, zFillColour1);
    CGContextEOFillPath(myContext);
    //生成图像
    CGImageRef myImage = CGBitmapContextCreateImage (myContext);
    UIImage * image = [UIImage imageWithCGImage:myImage];
    CGImageRelease(myImage);
    return image;
    }


    - (void)viewDidLoad {
    [super viewDidLoad];
    float wd = 320.0;
    float ht = 480.0;
    CGContextRef myContext = MyCreateBitmapContext (wd, ht);

    UIImageView *iv = [[UIImageView alloc] initWithImage:createDialogBox(myContext, 50, 350, 100, 60, 5, 7)];
    [self.view addSubview:iv];
    CGContextRelease (myContext);
    [iv release];
    }
    展开全文
  • 用TableView实现聊天对话框

    千次阅读 2013-09-17 22:15:53
    用tableView可实现如QQ,飞信,微信等聊天软件的对话框效果。 要实现如功能要解决以下几个问题: 1.对话框的高度能随着文本的多少动态变化,如果字数少于一行能存放的最大字数还要调整对话框的宽度,如果对话框...

    用tableView可实现如QQ,飞信,微信等聊天软件的对话框效果。

    要实现如图功能要解决以下几个问题:

    1.对话框的高度能随着文本的多少动态变化,如果字数少于一行能存放的最大字数还要调整对话框的宽度,如果对话框的文字太少要保证对话框至少要与头像照片一样高

    2.对话框是一个button,要完成对话框的背景的拉伸,使之与文字适合,点击对话框有高亮显示

    3.要在toolbar中加入textfield与button,点击textfield键盘弹出后要动态调整toolbar高度使textfield不会被键盘遮挡

    4.完成输入后键盘取消第一响应,textfield需要清空,tableView重新加载数据并滚动到最后一个cell

    准备工作在storyboard中只需加入navigation controller并把viewController设置为rootViewController就完成工作,其他的部分全部用代码实现。包括tableView的生成cell的数据的载入全部用代码就可以实现。


    为了展示效果先从字典中加载部分数据。

    我定义了一个Message类来存放对话消息,定义字符串message存放内容,isMine来判断是我自己发的信息还是对方发的信息

    Message.h

    #import <Foundation/Foundation.h>
    
    @interface Message : NSObject
    @property(nonatomic,strong)NSString *message;
    @property(nonatomic,assign)BOOL isMine;
    @end

    头文件viewController.h

    #import <UIKit/UIKit.h>
    @interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate,UITextFieldDelegate>
    @property(strong,nonatomic)UITableView *tableView;
    @property(strong,nonatomic)NSMutableArray *dialogMessages;
    @property(nonatomic,strong) UITextField *myTextField;
    @property(nonatomic,strong) UIToolbar *myToolbar;
    @property(nonatomic,strong) UIButton *myButton;
    @end
    

    里面定义了tableView,用来输入数据的myTextField,点击响应发送信息的myButton,和存放myTextField与myButton的myToolbar,最后是用来存储用于tableViewCell中的数据的数组dialogMessage。其中在头文件中一定不能忘记包含下面的委托,否则不能使用系统函数。
    <UITableViewDataSource,UITableViewDelegate,UITextFieldDelegate>

    读取字典中的数据

        const NSString *MsgKey = @"msg";
        const NSString *MineKey = @"ismine";
        
        NSString *path = [[NSBundle mainBundle] pathForResource:@"messages" ofType:@"plist"];
        NSArray *dataArray = [NSArray arrayWithContentsOfFile:path];
        
        [dataArray enumerateObjectsUsingBlock:^(NSDictionary *dict, NSUInteger idx, BOOL *stop) {
            Message *message = [[Message alloc] init];
            message.message = dict[MsgKey];
            message.isMine = [dict[MineKey] boolValue];
            [self.dialogMessages addObject:message];
        }];//读取字典中的数据

    代码生成界面各部分内容

    tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, 320, 371)];
        tableView.delegate =self;
        tableView.dataSource =self;
        self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
        myToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 372, 320, 44)];
        myTextField.delegate =self;
        myTextField = [[UITextField alloc] init];//初始化UITextField
        myTextField.frame = CGRectMake(0, 0, 250, 32);
        myTextField.delegate = self;//设置代理
        myTextField.borderStyle = UITextBorderStyleRoundedRect;//设置textField的样式为圆角
        myTextField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;//垂直居中
        myTextField.placeholder = @"请输入内容";//内容为空时默认文字
        myTextField.returnKeyType = UIReturnKeyDone;//设置放回按钮的样式
        myTextField.keyboardType = UIKeyboardTypeDefault;//设置键盘样式为默认
        
        UIBarButtonItem *textfieldButtonItem =[[UIBarButtonItem alloc]initWithCustomView:myTextField];
        UIBarButtonItem *sendMessageButtonItem =[[UIBarButtonItem alloc]initWithTitle:@"发送" style:UIBarButtonItemStyleDone target:self action:@selector(sendMessage)];
        NSArray *textfieldArray=[[NSArray alloc]initWithObjects:textfieldButtonItem,sendMessageButtonItem,nil];
        [myToolbar setItems:textfieldArray];
        [self.view addSubview:tableView];
        [self.view addSubview:myToolbar];
    
    切记要设置委托对象为self

    tableView.delegate =self;
    tableView.dataSource =self;
    myTextField.delegate =self;
    实现tableView

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
        return 1;
    }
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return [self.dialogMessages count];
    }
    
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        Message *msg = self.dialogMessages[indexPath.row];
        UIFont *font = [UIFont systemFontOfSize:12];
        CGSize size =[msg.message sizeWithFont:font constrainedToSize:CGSizeMake(115, 400) lineBreakMode: NSLineBreakByCharWrapping];
        if (size.height < 55) {//判断对话框的高度,如果比头像矮就设置为头像高度,否则就设置为对话框的文本高度加上间隔
            return 55;
        }
        else{
        return size.height+25+5;//与边线的间隔加上文本的上下缩进
        }
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        float buttonHeight,buttonWidth;
        NSString *CellIdentifier=@"CellIdentifier";
        UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
        if (cell == nil) {
            cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        }
        cell.selectionStyle = UITableViewCellSelectionStyleNone;//消去边线
        Message *msg = self.dialogMessages[indexPath.row];
        UIFont *font = [UIFont systemFontOfSize:12];//设置字体,这里使用了系统默认字体
        CGSize size =[msg.message sizeWithFont:font constrainedToSize:CGSizeMake(115, 400) lineBreakMode: NSLineBreakByCharWrapping];//计算文本高度
        if (size.height <16) {
            CGSize sizeSec=[msg.message sizeWithFont:font constrainedToSize:CGSizeMake(500, 15) lineBreakMode: NSLineBreakByCharWrapping];
            buttonWidth=sizeSec.width +35;//35是前缩进加上后缩进的宽度
        }
        else{
            buttonWidth = 150;
        }
    
        if (size.height <50) {//设置对话框高度
            buttonHeight = 50;//高度小于照片高度的就设置为照片高度
        }
        else{
            buttonHeight = size.height +25;
        }
        UIImage *normalImage,*highlightedImage;
        UIButton *dialogMessageButton =[[UIButton alloc]init];
        UIEdgeInsets insets;
        UIImage *headImage;
        UIImageView *headImageView =[[UIImageView alloc]init];
        if (msg.isMine ==true) {//判断信息来源,自己和别人的不一样的处理
            headImage =[UIImage imageNamed:@"me.jpg"];
            [headImageView setFrame:CGRectMake(5, 5, 50, 50)];
            normalImage = [UIImage imageNamed:@"mychat_normal"];
            highlightedImage = [UIImage imageNamed:@"mychat_focused"];
            insets = UIEdgeInsetsMake(10, 25, 15, 10);//设置文本的内边框,使文字与对话框更协调
            [dialogMessageButton setContentEdgeInsets:insets];//设置缩进
            [dialogMessageButton setFrame:CGRectMake(55, 5, buttonWidth, buttonHeight)];
            [dialogMessageButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
        }
        else{
            headImage =[UIImage imageNamed:@"mate.jpg"];
            [headImageView setFrame:CGRectMake(265, 5, 50, 50)];
            normalImage = [UIImage imageNamed:@"matechat_normal"];
            highlightedImage = [UIImage imageNamed:@"matechat_focused"];
            insets = UIEdgeInsetsMake(10, 10, 15, 25);//设置文本的内边框
            [dialogMessageButton setFrame:CGRectMake(320-buttonWidth-55, 5,buttonWidth, buttonHeight)];
            [dialogMessageButton setTitleColor:[UIColor blueColor] forState:UIControlStateHighlighted];//设置点击时文字颜色变成蓝色
        }
                                     
        [headImageView setImage:headImage];
        NSMutableString *buttonName =[[NSMutableString alloc]initWithFormat:@"%@",msg.message];
        [dialogMessageButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        normalImage = [normalImage stretchableImageWithLeftCapWidth:normalImage.size.width*0.5 topCapHeight:normalImage.size.height*0.6];//设置图片拉伸区域
        highlightedImage = [highlightedImage stretchableImageWithLeftCapWidth:highlightedImage.size.width*0.5 topCapHeight:highlightedImage.size.height*0.6];//设置图片拉伸区域
        [dialogMessageButton setBackgroundImage:normalImage forState:UIControlStateNormal];//设置对话框图片
        [dialogMessageButton setBackgroundImage:highlightedImage forState:UIControlStateHighlighted];//设置点击时对话框图片
        [dialogMessageButton setTitle:buttonName forState:UIControlStateNormal];
        [dialogMessageButton setContentEdgeInsets:insets];//设置缩进
        dialogMessageButton.titleLabel.font = font;
        dialogMessageButton.titleLabel.lineBreakMode = NSLineBreakByCharWrapping;
        dialogMessageButton.titleLabel.numberOfLines = 0;
        [cell.contentView addSubview:headImageView];
        [cell.contentView addSubview:dialogMessageButton];
        return cell;
    }
    
    其中
    CGSize size =[msg.message sizeWithFont:font constrainedToSize:CGSizeMake(115, 400) lineBreakMode: NSLineBreakByCharWrapping];

    的作用是计算在一定字体样式与大小(font)情况下文本(msg.message)在Width=115,Height=400的矩形约束下的文本所占高度,Height应设置的比较高足够容纳可能存放的文字数量才能保证结果不会偏差,NSLineBreakByCharWrapping是文本的换行方式我在上一篇博文中有介绍。150是我设置的button的最大宽度,减去了前后缩进的35就剩下115了。

    button因为是矩形的所以它的实际大小是图片中黄色区域部分,所以要设置文字的缩进让文字不要在对话框外的区域(黄色区域),所以用到insets设置缩进。点击的时候点击到对话框外的区域也会实现高亮显示,所以可以将button的backgroundColor设为[UIColor clearColor]然后再设置对话框为imageVIew调整它们之间的位置实现更好的用户体验

     insets = UIEdgeInsetsMake(10, 10, 15, 25);//设置文本的内边框
    这一句中UIEdgeInsetsMake(up,left,right,down)里面的参数分别为上,左,下,右逆时针的四个方向的缩进设置,然后通过[dialogMessageButton setContentEdgeInsets:insets]把数据传入button中

     if (size.height <16) {
            CGSize sizeSec=[msg.message sizeWithFont:font constrainedToSize:CGSizeMake(500, 15) lineBreakMode: NSLineBreakByCharWrapping];
            buttonWidth=sizeSec.width +35;//35是前缩进加上后缩进的宽度
        }
        else{
            buttonWidth = 150;
        }
    上面一段代码中因为一行大小12的systemfont高度为15.00000...(float),浮点数不能直接用等于号判断是否满足要求,用等于号会出错,所以我用判断是否为小于16代替,当判断到文本高度为16时,我们故技重施,限制住高度为15,再用CGSize来得到文本的宽度,然后就把button宽度设置为文本宽度加上缩进,否则维持150不变

        [dialogMessageButton setBackgroundImage:normalImage forState:UIControlStateNormal];//设置对话框图片
        [dialogMessageButton setBackgroundImage:highlightedImage forState:UIControlStateHighlighted];//设置点击时对话框图片

    背景图片和titleColor都可以分别在UIControlStateNormal和UIControlStateHighLighted两种状态下设置,相当方便,读者也可自行尝试其他属性

    tableView完成后就要着手完成textfield的功能了,在

        [self.view addSubview:tableView];
        [self.view addSubview:myToolbar];

    后面加上

     //注册键盘出现与隐藏时候的通知
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(keyboadWillShow:)
                                                     name:UIKeyboardWillShowNotification
                                                   object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(keyboardWillHide:)
                                                     name:UIKeyboardWillHideNotification
                                                   object:nil];
    
    然后是键盘出现与消失时调整toolbar位置函数

    //键盘出现时候调用的事件
    -(void) keyboadWillShow:(NSNotification *)note{
        NSDictionary *info = [note userInfo];
        CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;//键盘的frame
        CGFloat offY = (416-keyboardSize.height)-myToolbar.frame.size.height;//屏幕总高度-键盘高度-myToolbar高度
        [UIView beginAnimations:nil context:NULL];//此处添加动画,使之变化平滑一点
        [UIView setAnimationDuration:0.3];//设置动画时间 秒为单位
        myToolbar.frame =CGRectMake(0, offY, 320, 44);
        [UIView commitAnimations];//开始动画效果
        
    }
    //键盘消失时候调用的事件
    -(void)keyboardWillHide:(NSNotification *)note{
        [UIView beginAnimations:nil context:NULL];//此处添加动画,使之变化平滑一点
        [UIView setAnimationDuration:0.3];
        myToolbar.frame =CGRectMake(0, 372, 320, 44);
        [UIView commitAnimations];
    }
    //隐藏键盘方法
    -(void)hideKeyboard{
        [myTextField resignFirstResponder];
    }
    

    textfield的委托事件

    //开始编辑:
    - (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
    {
        return YES;
    }
    
    //点击return按钮所做的动作:
    - (BOOL)textFieldShouldReturn:(UITextField *)textField
    {
        [textField resignFirstResponder];//取消第一响应
        return YES;
    }
    
    //编辑完成:
    - (void)textFieldDidEndEditing:(UITextField *)textField
    {
        
    }
    
    -(void)viewDidDisappear:(BOOL)animated{
        [super viewDidDisappear:animated];
        [[NSNotificationCenter defaultCenter] removeObserver:self];//移除观察者
    }

    然后是button的响应函数
    -(void)sendMessage{//完成输入响应函数 
        Message *newMessage =[[Message alloc]init];
        newMessage.message = [[NSString alloc]initWithString:myTextField.text];
        newMessage.isMine =YES;
        [self.dialogMessages addObject:newMessage];//把textField的文本加入到字典数组中
        [tableView reloadData];//tableView重新加载数据
        NSUInteger rowCount = [tableView numberOfRowsInSection:0];
        NSIndexPath* indexPath = [NSIndexPath indexPathForRow:rowCount-1 inSection:0];//indexPath设置成最后一个cell的下标
        [tableView scrollToRowAtIndexPath:indexPath
                            atScrollPosition:UITableViewScrollPositionBottom animated:NO];//设置滚动到底部
        [myTextField resignFirstResponder];//键盘消失,取消第一响应
        myTextField.text =@"";//清空textField
        
    }
    

    最后是设置cell的点击事件,让用户点击空白处键盘会消失

    -(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{
        [myTextField resignFirstResponder];
    }

    tableView实现对话框代码下载


    展开全文
  • 前两天的《C#实现微信聊天对话框》大家给了不少的好的建议,本文基于前进文进行了改进,望大家一起来讨论~~~ 先看一下改进后的界面效果: 之前背景的边框采用背景图片的方式,目前已采用GDI+直接绘制的方式,...

     

    前两天的《C#实现微信聊天对话框》大家给了不少的好的建议,本文基于前进文进行了改进,望大家一起来讨论~~~

    先看一下改进后的界面效果:

    之前背景的边框采用背景图片的方式,目前已采用GDI+直接绘制的方式,并且添加了背景色以增加用户体验~~

    具本的代码如下:

    View Code
      1 using System;
      2 using System.ComponentModel;
      3 using System.Drawing;
      4 using System.Drawing.Drawing2D;
      5 using System.Windows.Forms;
      6 
      7 namespace Sun.WinFormControl
      8 {
      9     /// <summary>
     10     /// 类似微信的聊天对话框。
     11     /// </summary>
     12     /// <remarks>
     13     /// Author:SunYujing
     14     /// DateTime:2012-07-19
     15     /// </remarks>
     16     public class WxChartBox : Control
     17     {
     18         /// <summary>
     19         /// 构造方法。
     20         /// </summary>
     21         public WxChartBox()
     22         {
     23             SetStyle(ControlStyles.DoubleBuffer, true);                   //双缓冲防止重绘时闪烁
     24             SetStyle(ControlStyles.AllPaintingInWmPaint, true);           //忽略 WM_ERASEBKGND 窗口消息减少闪烁
     25             SetStyle(ControlStyles.UserPaint, true);                      //自定义绘制控件内容
     26             SetStyle(ControlStyles.SupportsTransparentBackColor, true);   //模拟透明            
     27             SetStyle(ControlStyles.Selectable, false);                     //接收焦点
     28             Size = new Size(500, 60);                                      //初始大小
     29             Font = new Font("微软雅黑", 10);
     30         }
     31         /// <summary>
     32         /// 用户名。
     33         /// </summary>
     34         private string _username = "用户名";
     35         /// <summary>
     36         /// 消息日期时间。
     37         /// </summary>
     38         private DateTime _messagetime = DateTime.Now;
     39         /// <summary>
     40         /// 消息内容。
     41         /// </summary>
     42         private string _messagecontent = "消息内容";
     43         /// <summary>
     44         /// 每行消息数据的字节数。
     45         /// </summary>
     46         //private int _perlinebit = 68;
     47         /// <summary>
     48         /// 每行字符数。
     49         /// </summary>
     50         private int _perlinechar = 35;
     51         /// <summary>
     52         /// 消息内容的行高。
     53         /// </summary>
     54         private int _lineheight = 22;
     55         /// <summary>
     56         /// 背景图高。
     57         /// </summary>
     58         private int _iheight = 8;
     59         /// <summary>
     60         /// 背景图宽。
     61         /// </summary>
     62         private int _iwidth = 8;
     63         /// <summary>
     64         /// 消息类型。
     65         /// </summary>
     66         private MessageType _messagetype = MessageType.Receive;
     67         /// <summary>
     68         /// 获取或设置用户名。
     69         /// </summary>
     70         [Description("获取或设置用户名。")]
     71         public string UserName
     72         {
     73             get
     74             {
     75                 return _username;
     76             }
     77             set
     78             {
     79                 _username = value;
     80                 Invalidate(false);
     81             }
     82         }
     83 
     84         /// <summary>
     85         /// 获取或设置用户名。
     86         /// </summary>
     87         [Description("获取或设置用户名。")]
     88         public DateTime MessageTime
     89         {
     90             get
     91             {
     92                 return _messagetime;
     93             }
     94             set
     95             {
     96                 _messagetime = value;
     97                 Invalidate(false);
     98             }
     99         }
    100 
    101         /// <summary>
    102         /// 获取或设置消息内容。
    103         /// </summary>
    104         [Description("获取或设置消息内容。")]
    105         public string MessageContent
    106         {
    107             get
    108             {
    109                 return _messagecontent;
    110             }
    111             set
    112             {
    113                 _messagecontent = value;
    114                 Invalidate(false);
    115             }
    116         }
    117 
    118         /// <summary>
    119         /// 获取或设置消息的类型。
    120         /// </summary>
    121         [Description("获取或设置消息的类型。")]
    122         public MessageType MType
    123         {
    124             get
    125             {
    126                 return _messagetype;
    127             }
    128             set
    129             {
    130                 _messagetype = value;
    131                 Invalidate(false);
    132             }
    133         }
    134         /// <summary>
    135         /// 自定义绘制。
    136         /// </summary>
    137         protected override void OnPaint(PaintEventArgs e)
    138         {
    139             base.OnPaint(e);
    140             Graphics g = e.Graphics;
    141             g.SmoothingMode = SmoothingMode.HighQuality;
    142             g.PixelOffsetMode = PixelOffsetMode.HighQuality;
    143             Size = new Size(500, InitHeight());
    144             DrawBackColor(g);
    145             DrawBackGroundLine(g);
    146             DrawText(g);
    147             DrawLine(g);
    148             DrawMessageContent(g);
    149         }
    150         /// <summary>
    151         /// 绘制用户名和消息时间。
    152         /// </summary>
    153         private void DrawText(Graphics g)
    154         {
    155             Font f = new Font("微软雅黑", 10,FontStyle.Bold);
    156             g.DrawString(UserName+"  "+MessageTime.ToString("yyyy-MM-dd HH:mm:ss"), f, new SolidBrush(ForeColor), 8+_iwidth, 2);
    157         }
    158         /// <summary>
    159         /// 绘制一条直线。
    160         /// </summary>
    161         private void DrawLine(Graphics g)
    162         {
    163             Color color = Color.Green;
    164             if(MType==MessageType.Receive)
    165                 color = Color.Red;
    166             Pen p = new Pen(color);
    167             p.Width = 1;
    168             g.DrawLine(p, 4 + _iwidth, 22, Width - 8 - _iwidth , 22);
    169         }
    170         /// <summary>
    171         /// 绘制短信内容。
    172         /// </summary>
    173         private void DrawMessageContent(Graphics g)
    174         {
    175             int initheight = 22;
    176             int rowscount = MessageLineCount();
    177             string contents = MessageContent;
    178             string content = "";
    179             for (int i = 0; i < rowscount; i++)
    180             {
    181                 if (contents.Length > _perlinechar)
    182                 {
    183                     content = contents.Substring(0, _perlinechar);
    184                     contents = contents.Remove(0, _perlinechar);
    185                 }
    186                 else
    187                 {
    188                     content = contents;
    189                 }
    190                 g.DrawString(content, Font, new SolidBrush(ForeColor), 4+_iwidth, initheight + i * _lineheight);
    191             }
    192         }
    193         /// <summary>
    194         /// 绘制边框。
    195         /// </summary>
    196         private void DrawBackGroundLine(Graphics g)
    197         {
    198             Pen p = new Pen(Color.Black);
    199             p.Width = 1;
    200             g.DrawArc(p, _iwidth, 0, _iwidth, _iheight, 180, 90);
    201             g.DrawLine(p, (int)(_iwidth * 1.5), 0, Width - (int)(_iwidth * 1.5), 0);
    202             g.DrawArc(p, Width - _iwidth * 2, 0, _iwidth, _iheight, 270, 90);
    203             if (MType == MessageType.Send)
    204             {
    205                 g.DrawLine(p, Width - _iwidth, (int)(_iheight * 0.5), Width - _iwidth, (int)(_iheight * 1.5));
    206                 g.DrawLine(p, Width - _iwidth, (int)(_iheight * 1.5), Width, _iheight * 2);
    207                 g.DrawLine(p, Width - _iwidth, (int)(_iheight * 2.5), Width, _iheight * 2);
    208                 g.DrawLine(p, Width - _iwidth, (int)(_iheight * 2.5), Width - _iwidth, Height - (int)(_iheight * 0.5));
    209             }
    210             else
    211             {
    212                 g.DrawLine(p, Width - _iwidth, (int)(_iheight * 0.5), Width - _iwidth, Height - (int)(_iheight * 0.5));
    213             }
    214             g.DrawArc(p, Width - _iwidth * 2, Height - _iheight,_iwidth,_iheight, 0, 90);
    215             g.DrawLine(p, (int)(_iwidth * 1.5), Height, Width - (int)(_iwidth * 1.5), Height);
    216             g.DrawArc(p, _iwidth, Height - _iheight, _iwidth, _iheight, 90, 90);
    217             if (MType == MessageType.Receive)
    218             {
    219                 g.DrawLine(p, _iwidth, (int)(_iheight * 0.5), _iwidth, (int)(_iheight * 1.5));
    220                 g.DrawLine(p, 0, _iheight * 2, _iwidth, (int)(_iheight * 1.5));
    221                 g.DrawLine(p, 0, _iheight * 2, _iwidth, (int)(_iheight * 2.5));
    222                 g.DrawLine(p, _iwidth, (int)(_iheight * 2.5), _iwidth, Height - (int)(_iheight * 0.5));
    223             }
    224             else
    225             {
    226                 g.DrawLine(p, _iwidth, (int)(_iheight * 0.5), _iwidth, Height - (int)(_iheight * 0.5));
    227             }
    228         }
    229         /// <summary>
    230         /// 绘制背景色。
    231         /// </summary>
    232         private void DrawBackColor(Graphics g)
    233         {
    234             Brush b = Brushes.YellowGreen;
    235             Point[] ps = new Point[3];
    236             if (MType == MessageType.Receive)
    237             {
    238                 ps[0] = new Point(0, _iheight * 2);
    239                 ps[1] = new Point(_iwidth, (int)(_iheight * 1.5));
    240                 ps[2] = new Point(_iwidth, (int)(_iheight * 2.5));
    241             }
    242             else
    243             {
    244                 b = Brushes.Goldenrod;
    245                 ps[0] = new Point(Width - _iwidth, (int)(_iheight * 1.5));
    246                 ps[1] = new Point(Width - _iwidth, (int)(_iheight * 2.5));
    247                 ps[2] = new Point(Width, _iheight * 2);
    248             }
    249             g.FillEllipse(b, _iwidth, 0, _iwidth, _iheight);
    250             g.FillEllipse(b, Width - _iwidth * 2, 0, _iwidth, _iheight);
    251             g.FillEllipse(b, Width - _iwidth * 2, Height-_iheight, _iwidth, _iheight);
    252             g.FillEllipse(b, _iwidth, Height - _iheight, _iwidth, _iheight);
    253             g.FillRectangle(b, _iwidth, (int)(_iheight*0.5), Width - _iwidth * 2, Height - _iheight);
    254             g.FillRectangle(b, (int)(_iwidth * 1.5), 0, Width - _iwidth * 3, (int)(_iheight * 0.5));
    255             g.FillRectangle(b, (int)(_iwidth * 1.5), Height - (int)(_iheight * 0.5), Width - _iwidth * 3, (int)(_iheight * 0.5));
    256             g.FillPolygon(b, ps);
    257         }
    258         /// <summary>
    259         /// 动态计算控件高度。
    260         /// </summary>
    261         /// <returns>控件高度。</returns>
    262         public int InitHeight()
    263         {
    264             int rowCount = MessageLineCount();
    265             int iRows = rowCount == 0 ? 1 : rowCount;
    266             return iRows * _lineheight + 22;
    267         }
    268         /// <summary>
    269         /// 获取消息行数。
    270         /// </summary>
    271         /// <returns>消息行数。</returns>
    272         private int MessageLineCount()
    273         {
    274             //int MessageBits = Encoding.Default.GetByteCount(MessageContent.Trim());
    275             //return (int)Math.Ceiling(MessageBits * 1.0 / _perlinebit);
    276             int MessageCharCount = MessageContent.Trim().Length;
    277             return (int)Math.Ceiling(MessageCharCount * 1.0 / _perlinechar);
    278         }
    279     }
    280 
    281     /// <summary>
    282     /// 消息类型。
    283     /// </summary>
    284     public enum MessageType
    285     {
    286         /// <summary>
    287         /// 发送消息。
    288         /// </summary>
    289         Send,
    290         /// <summary>
    291         /// 接收消息。
    292         /// </summary>
    293         Receive
    294     }
    295 }

    欢迎有兴趣的园友一起讨论学习~~~

    转载于:https://www.cnblogs.com/sunyujing/archive/2012/07/22/wxChartBox.html

    展开全文
  • 今天和大家分享两个微信小技巧,它们隐藏的有点深,但是非常实用,第一个就是:一键设置所有聊天背景图,通常我们在设置聊天背景图的时候都是打开好友的对话框,点击右上三点来操作的,这样的话只能设置跟她聊天的...
  • 如上所示,这是聊天界面中有人发送的视频,这个泡泡背景左上有个尖角,按照我们普通的设计来说,这个角要么是空白的,要么视频内容完全覆盖了那个尖角。 那么我们如何才能实现截图中的效果呢,这里我们就需要用到...
  • 微信“无边框”聊天背景图难度系数:1颗星适用系统:安卓,iOS(苹果)今天所长想给大家介绍一组会让人好运爆棚的壁纸,不过,运营妹纸给我分享了一款有趣的聊天背景图,换上后,就看不到自己的聊天消息对话框。...
  • 需求如下: 1. TextView的大小,是随着文字的多少,其大小是会变化的,不能固定。即文字多的,View就大一点。 2. 而背景图片,能始终保持和TextView的大小...请问该怎么做才能做出像微信聊天对话框那样的效果,谢谢!
  • 上面GameObject是对话框图片背景,第一个脚本有两个参数,是设置水平扩展还是垂直扩展,我选择的是垂直拉伸自适应,如文章开篇的效果,第二个脚本是设置内边距的,这样让里面的文字看起来很好看。 Text也...
  • 1.先设置背景聊天文件的图片 资源管理器中找到安装文件下的tools->draw9patch.bat的文件,双击可以运行,在里面打开将背景图片加入编辑,并保存替换原来的图片 2.设置依赖库 在app/build.gradle中添加依赖库...
  • 聊天界面以及contextm

    2016-06-15 15:29:50
    聊天界面,首先是布局,先用tools下的制作9patch图片的工具制作两张对话框图片,分别用作接收消息的图片背景和发送消息的图片背景。activity_main.xml的布局文件如下: android:id="@+id/message_listview" ...
  • .9 图片的创建

    2017-07-27 09:43:00
    中间写到聊天界面的时候遇到一个问题,聊天对话框背景需要 .9 的图片,不然发送内容不同,图片就被变形了。 然后就自己去写 .9 的图片,在as中选中图片,点右键弹出菜单,里面就有创建 .9 图片。 这个时候就要...
  • 8、聊天室里对话框下加入了部分链接,网友可自行修改; 9、在原版上增加了万年皇历; 10、在原版基本上加入了收费服务,包括永久保留、邮件列表、在线发信、泡分工具,和正版一模一样; 11、加入警告功能; 12、...
  • 9png图片一般用在需要拉伸的地方,比如聊天程序的对话框,字数不同,对话框的大小也不同。 普通位图拉伸后有多难看参考当年windows 95桌面背景拉伸效果。 所以就有了9png,之所以叫9是因为图片被分割为9个部分。 ...
  • 点九图,是Android开发中用到的一种特殊格式的图片,文件名以”.9.png“结尾。...这是我截屏自手机QQ一组聊天对话框,可以看出,不同两条消息字数不同,长度也不同,但它们采用了相同的背景样式,这
  • 最近很多人在微信群问我点9怎么切的问题,今天u妹把工作中积累的关于点9切图的经验分享给大家,希望大家可以掌握这些切图方法。点九图,是Android开发...点九图常用于对话框聊天气泡背景图片中。U妹结合一些具体...
  • 一、需求背景 在项目开发中,在UI切图不全的情况下,我们可以通过放大缩小...(而我所遇到的问题是, 设置聊天对话框, 会随着聊天文字内容而横向和纵向的变化) 二.首先讲iOS中的切片缩放 iOS的图片Slicing,同等于Andr
  • 实际使用情形1:按钮的背景图拉伸以适应文字大小情形2:聊天对话框按钮.png对话框.png一、iOS 5.0之前iOS中有个叫端盖(end cap)的概念,用来指定图片中的哪一部分不用拉伸。比如下图中,黑色代表需要被拉伸的矩形...
  • 实例134——使用位图作为对话框背景 实例135——创建半透明对话框窗口 实例136——创建圆形对话框窗口 实例137——全屏幕显示对话框窗口 实例138——动态改变对话框窗口大小 实例139——按下Esc键,对话框不...
  • 9.3 将图片作为窗口显示的背景 第10 章 网络编程 10.1 计算机网络的基本概念 10.1.1 计算机网络的分类 10.1.2 网络拓扑结构 10.2 网络体系结构和网络协议 10.2.1 ISO/OSI 参考模型 10.2.2 TCP/IP 参考模型 ...
  • 实例134——使用位图作为对话框背景 实例135——创建半透明对话框窗口 实例136——创建圆形对话框窗口 实例137——全屏幕显示对话框窗口 实例138——动态改变对话框窗口大小 实例139——按下Esc键,...
  • C++范例大全(400)

    2013-06-29 21:23:07
    实例134——使用位图作为对话框背景 实例135——创建半透明对话框窗口 实例136——创建圆形对话框窗口 实例137——全屏幕显示对话框窗口 实例138——动态改变对话框窗口大小 实例139——按下Esc键,对话框不...
  • 实例134——使用位图作为对话框背景 实例135——创建半透明对话框窗口 实例136——创建圆形对话框窗口 实例137——全屏幕显示对话框窗口 实例138——动态改变对话框窗口大小 实例139——按下Esc键,对话框不...

空空如也

空空如也

1 2 3 4 5 6
收藏数 108
精华内容 43
关键字:

对话框聊天背景图