相同的ui布局怎么封装起来ios

ios中UI和常用动画汇总
.cn/?tag=ios-animation-ui
 1.保证程序UI和设计图完全吻合(UI显示) 北京达内科技
  2.尽量能避免闪出闪去等*作,结合实际情况,能过渡的交互尽量结合动画制作,以符合ios风格,(Animation)
  (一).UI显示:
  原则:保证要与设计图模式一摸一样,发现不适合的东西,需要及时沟通后让设计师修改,尽量要保证和设计图的像素一一对应
  1.自定义UIAlertView:
  换背景:达内科技
UIAlertView *theAlert = [[UIAlertView alloc] initWithTitle:title
message:message delegate:delegate cancelButtonTitle:cancleTitle
otherButtonTitles:otherTitle,nil];
[theAlert show];
theAlert.backgroundColor = [UIColor clearColor];
UILabel *theTitle = [theAlert valueForKey:@"_titleLabel"];
[theTitle setTextColor:[UIColor whiteColor]];
UILabel *theBody = [theAlert valueForKey:@"_bodyTextLabel"];
[theBody setTextColor:[UIColor whiteColor]];
UIImage *theImage = [UIImage imageNamed:@"alertBack.png"];
theImage = [theImage stretchableImageWithLeftCapWidth:0.
topCapHeight:0.];
CGSize theSize = [theAlert frame].
UIGraphicsBeginImageContext(theSize);
[theImage drawInRect:CGRectMake(0, 0, theSize.width,
theSize.height)];
theImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
theAlert.layer.contents = (id)[theImage CGImage];
for (UIView *tempView in theAlert.subviews)
if ([tempView isMemberOfClass:[UIImageView class]])
[tempView removeFromSuperview];
[theAlert release];
&span class="Apple-style-span"
style="font-family: Georgia, 'Times New Roman', 'Bitstream
Charter', Times, font-size: 13 line-height: 19
white-space:
"&2.自定义UIPageControl&/span&
  改变点儿的颜色,可以改变小点儿的颜色:(附件中)
  MyPageControl.h
  MyPageControl.m
  3.自定义UISegmentConrol
  改变自定义风格:(需要用切图配合)
UISegmentedControl *segmentControl = [[UISegmentedControl alloc]
initWithItems:[NSArray arrayWithObjects:
[UIImage imageNamed:@"seg1_tapped.png"],
[UIImage imageNamed:@"seg2.png"],
[UIImage imageNamed:@"seg3.png"],nil]];
segmentControl.segmentedControlStyle =
UISegmentedControlStyleB
segmentControl.frame = CGRectMake((DeviceWidth-76*3)/2-9,
14+[cellContentArray count]*35, 76*3, 33.5);
segmentControl.selectedSegmentIndex = 0;
[segmentControl addTarget:self action:@selector(changeBookType:)
forControlEvents:UIControlEventValueChanged];
[cell.contentView addSubview:segmentControl];
[segmentControl release];
  4.自定义UIProgressView
  改变pressView的进度颜色显示:基于QuartzCore绘制图像
  CustemProgressBar.h
  CustemProgressBar.m
  5.自定义UITableView/UITableViewCell
  很常用,往后要倾向IB来做:layOutSubView布局frame
  6.自定义UINavigationBar(用view组合)
  TopBarView.h
  TopBarView.m
  我的做法:将自身的navibar英藏后在显示为自定义的navibarView:这样方便程序来控制:
  7.自定义UIPopViewController(用view组合)
  iPhone里不支持PopViewController,但是有时会需要在程序里显示PopViewController这样的东西
  8.自定义UITabBarView
  用一组button组合成tabbar的显示,方便灵活,但要确保需要管理好内容:
  由于sdk中的tabbar是很不灵活的,隐藏之类的*作都很难控制:
  9.自定义UISearchBar
  用多个view组合起来平城searchview的显示:可以改变背景,圆角等
  改变背景等需求;
  10.自定义UITextField/UITextView
  可以换背景等:leftview rightView background等
  11.翻页效果:UIPageViewController(iOS5)
  1.官方demo,
  2.leaves框架翻页效果
  (二).常用到的动画汇总:
  一.控件本身附有的动画方法:
  UIKit包含的动画效果,用起来也比较省事,举例如下:
  1. [self.navigationController setNavigationBarHidden:YES
animated:YES];
  2.一般使用UITableView的的动画效果汇总:
  先设置数据源,然后在执行动画:
An error has occurred. Please try again later.
(void)insertSections:(NSIndexSet *)sections
withRowAnimation:(UITableViewRowAnimation)
- (void)deleteSections:(NSIndexSet *)sections
withRowAnimation:(UITableViewRowAnimation)
- (void)reloadSections:(NSIndexSet *)sections
withRowAnimation:(UITableViewRowAnimation)animation
__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths
withRowAnimation:(UITableViewRowAnimation)
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths
withRowAnimation:(UITableViewRowAnimation)
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths
withRowAnimation:(UITableViewRowAnimation)animation
__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);
  3.[scrollVie setContentOffset:CGPoint animated:BOOL]
  4.UIImageView的动画效果:
UIImageView *campFireView = [[UIImageView alloc]
initWithFrame:XXX];
campFireView.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:@"campFire01.gif"],
[UIImage imageNamed:@"campFire02.gif"]......., nil];
campFireView.animationDuration = 1.75;
campFireView.animationRepeatCount = 0;
[campFireView startAnimating];
[campFireView release];
  二.UIViewAnimation实例:Animation块动画,Animation块支持多种动画叠加,会产生各种不同的效果
  //在这里之前初始化参数
[UIView beginAnimations:nil context:nil];
&[UIView setAnimationDelegate:delegate];
setAnimationWillStartSelector:startSelector];//开始的代理
setAnimationDidStopSelector:stopSelector];//结束的代理
&[UIView setAnimationDuration:seconds];
//改变后的参数,动画将会从初始化的参数向改变后的参数过渡
&tempView.center =
//大小transform
tempView.transform = CGAffineTransformMakeScale(number,
tempView.alpha = 0;
CGAffineTransform newTransform =
CGAffineTransformMakeRotation(M_PI);
[viewToAddAnimation setTransform:newTransform];
//翻转两个View的动画:
把一个removeFromSupview同时把另一个addSubView,设置一下动画的翻转效果:上下左右选一个;
[view1 removeFromSupview];
[view addSubView:view2];
//横向滑动效果等
[UIView commitAnimations];
  三.CAAnimation实例:
  弹出时抖动显示,模仿AlertView的弹出效果,可以将抖动结合用到其他的地方:
+(void) showCustemAlertViewInRect:(CGRect) frame inView:(UIView
*) superview
UIView *tempView = [UIGloble newWhiteViewWithFrame:frame
backgroundColor:[UIColor blueColor]];
[superview addSubview:tempView];//CGRectMake(40, 60,
DeviceWidth-80, DeviceHeight-200)
CAKeyframeAnimation *animation=
animation = [CAKeyframeAnimation
animationWithKeyPath:@"transform"];
animation.duration = 0.8;
animation.delegate =
animation.removedOnCompletion = YES;
animation.fillMode = kCAFillModeF
NSMutableArray *values = [NSMutableArray array];
[values addObject:[NSValue
valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1,
[values addObject:[NSValue
valueWithCATransform3D:CATransform3DMakeScale(1.2, 1.2,
[values addObject:[NSValue
valueWithCATransform3D:CATransform3DMakeScale(0.9, 0.9,
[values addObject:[NSValue
valueWithCATransform3D:CATransform3DMakeScale(1.0, 1.0,
animation.values =
animation.timingFunction = [CAMediaTimingFunction
functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[tempView.layer addAnimation:animation forKey:nil];
[tempView release];
  四.晃动动效果:CABasicAnimation动画举例:可以模仿iphone删除程序模式下的抖动效果:
CALayer*viewLayer=[self layer];
CABasicAnimation*animation=[CABasicAnimation
animationWithKeyPath:@"transform"];
animation.duration=0.2;
animation.repeatCount = 100000;
animation.autoreverses=YES;
animation.fromValue=[NSValue
valueWithCATransform3D:CATransform3DRotate(viewLayer.transform,
-0.03, 0.0, 0.0, 0.03)];
animation.toValue=[NSValue
valueWithCATransform3D:CATransform3DRotate(viewLayer.transform,
0.03, 0.0, 0.0, 0.03)];
[viewLayer addAnimation:animation forKey:@"wiggle"];
  五.按照路径绘制动画的效果(CAKeyframeAnimation : CAPropertyAnimation)
  指定几个点,会按照动画指定的轨迹出效果:可以自选几个比较明显重要的点来绘制出动画
CAKeyframeAnimation *animation = [CAKeyframeAnimation
animationWithKeyPath:@"position"];
[animation setDuration:0.8];
CGPoint p1 = tempButton.
CGPoint p2 = CGPointMake(152, 97);
CGPoint p3 = CGPointMake(189, 110);
CGPoint p4 = CGPointMake(220, 124);
CGPoint p5 = CGPointMake(245, 163);
CGPoint p6 = CGPointMake(220, 250);
CGPoint p7 = CGPointMake(177, 379);
[animation setValues:[NSArray arrayWithObjects:
[NSValue valueWithCGPoint:p1],
[NSValue valueWithCGPoint:p2],
[NSValue valueWithCGPoint:p3],
[NSValue valueWithCGPoint:p4],
[NSValue valueWithCGPoint:p5],
[NSValue valueWithCGPoint:p6],
[NSValue valueWithCGPoint:p7],
[animation setKeyTimes:[NSArray arrayWithObjects:
[NSNumber numberWithFloat:0.0],
[NSNumber numberWithFloat:0.3],
[NSNumber numberWithFloat:0.4],
[NSNumber numberWithFloat:0.5],
[NSNumber numberWithFloat:0.6],
[NSNumber numberWithFloat:0.7],
[NSNumber numberWithFloat:0.8],
//[animation setAutoreverses:YES];//返回到原始状态
[tempButton.layer addAnimation:animation
forKey:@"BookView-Fly"];
[UIGloble addAnimationFade:tempButton duraion:0.8];
[UIGloble addAnimationScal:tempButton toPoint:tempButton.center
lightState:YES delegate:tempButton startSelector:nil
stopSelector:@selector(removeFromSuperview) scaleNumber:0.1
duraion:0.8];
[tempButton release];
[self performSelector:@selector(changeBadgeValue) withObject:nil
afterDelay:0.8];
六.CATransition,cube动画翻转,privateAPI
CATransition *animation = [CATransition animation];
animation.delegate =
animation.duration = 0.5f;
animation.timingFunction = UIViewAnimationCurveEaseInO
animation.fillMode = kCAFillModeR
animation.removedOnCompletion = NO;
animation.type = @"cube";
[[UIApplication sharedApplication].keyWindow.layer
addAnimation:animation forKey:@"animationID"];
  总结出来的:
  实现iphone漂亮的动画效果主要有两种方法,一种是UIView层面的,一种是使用CATransition进行更低层次的控制,
  第一种是UIView,UIView方式可能在低层也是使用CATransition进行了封装,它只能用于一些简单的、常用的效果展现,这里写一个常用的示例代*,供大家参考。
[UIView beginAnimations:@"Curl"context:nil];//动画开始
[UIView setAnimationDuration:0.75];
[UIView setAnimationDelegate:self];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp
forView:myview cache:YES];
[myview removeFromSuperview];
[UIView commitAnimations];
  第二种方式相对复杂一些,但如果更好的进行控制,还是使用这种方法吧,基本使用方法可以看一下如下例子:
CATransition *animation = [CATransition animation];
[animation setDuration:1.25f];
[animation setTimingFunction:[CAMediaTimingFunction
functionWithName:kCAMediaTimingFunctionEaseIn]];
[animation setType:kCATransitionReveal];
[animation setSubtype: kCATransitionFromBottom];
[self.view.layer addAnimation:animation forKey:@"Reveal"];
  还有一种设置动画类型的方法,不用setSubtype,只用setType
  [animation setType:@"suckEffect"];
  这里的suckEffect就是效果名称,可以用的效果主要有:
  pageCurl 向上翻一页
  pageUnCurl 向下翻一页
  rippleEffect 滴水效果
  suckEffect 收缩效果,如一块布被抽走
  cube 立方体效果
  oglFlip 上下翻转效果
  最后再给出一种常用代*供大家参考。
// Curl the image up or down
CATransition *animation = [CATransition animation];
[animation setDuration:0.35];
[animation setTimingFunction:UIViewAnimationCurveEaseInOut];
if (!curled){
//animation.type = @"mapCurl";
animation.type = @"pageCurl";
animation.fillMode = kCAFillModeF
animation.endProgress = 0.99;
//animation.type = @"mapUnCurl";
animation.type = @"pageUnCurl";
animation.fillMode = kCAFillModeB
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。iOS开发之微信聊天工具栏的封装
招聘信息:
微信大家肯定都非常熟悉,它的产品经理张小龙已经是圈内神一样的人物,所以它的设计必定有可学习借鉴之处,今天我们就来实践“山寨”一下,实现微信具体的功能,先从微信的聊天界面开始。提到封装是少不了写代码的,在封装组件的时候,为了组件的可移植性,我们就不能用
storyboard来拖拽了。为了屏幕的适配,适应不同屏幕的手机,所以在封装组件的时候是少不了为我们的组件来添加约束。今天文章中的所有代码都是脱离storyboard的,这些代码在别的工程中也是可以使用的。好,废话少说,切入正题。今天要做的就是微信的聊天工具条。聊天工具条还是比较复杂的,其中包括发送表情,发送文字,发送图片,发送声音,拍照等等功能,下面给出发送录音,文字,表情的代码,其他的和这几样类似。还是那句话百字不如一图,先来几张效果图吧。在封装聊天工具条的的时候表情键盘是之前封装好的(请参考:“”),所以拿过来就可以用的啦。因为不管是工具条还是表情键盘都是用约束来控件大小的,所以横屏也是没问题的,在大屏手机上也是没问题的。下面将会一步步讲解如何封装下面的聊天工具条。主要是对工具条的封装,表情键盘在这就不做讲解了。一:ToolView预留的接口在封装ToolView中主要用到Block回调,读者可以根据自己的个人习惯来选择是Block回调,还是委托回调或者是目标动作回调(笔者更喜欢Block回调),下面的代码是ToolView给调用者提供的接口//
//&&ToolView.h
//&&MecroMessage
//&&Created&by&(青玉伏案:博客地址(/ludashi/))&on&14-9-22.
//&&Copyright&(c)&2014年&Mrli.&All&rights&reserved.
#import&//定义block类型把ToolView中TextView中的文字传入到Controller中
typedef&void&(^MyTextBlock)&(NSString&*myText);
//录音时的音量
typedef&void&(^AudioVolumeBlock)&(CGFloat&volume);
//录音存储地址
typedef&void&(^AudioURLBlock)&(NSURL&*audioURL);
//改变根据文字改变TextView的高度
typedef&void&(^ContentSizeBlock)(CGSize&contentSize);
//录音取消的回调
typedef&void&(^CancelRecordBlock)(int&flag);
@interface&ToolView&:&UIView//设置MyTextBlock
-(void)&setMyTextBlock:(MyTextBlock)
//设置声音回调
-(void)&setAudioVolumeBlock:(AudioVolumeBlock)&
//设置录音地址回调
-(void)&setAudioURLBlock:(AudioURLBlock)&
-(void)setContentSizeBlock:(ContentSizeBlock)&
-(void)setCancelRecordBlock:(CancelRecordBlock)
-(void)&changeFunctionHeight:&(float)&
@end二:初始化ToolView中所需的控件1.为了更好的封装我们的组件,在.h中预留接口,在ToolView.m的延展中添加我们要使用的组件(私有属性),延展代码如下:@interface&ToolView()
//最左边发送语音的按钮
@property&(nonatomic,&strong)&UIButton&*voiceChangeB
//发送语音的按钮
@property&(nonatomic,&strong)&UIButton&*sendVoiceB
//文本视图
@property&(nonatomic,&strong)&UITextView&*sendTextV
//切换键盘
@property&(nonatomic,&strong)&UIButton&*changeKeyBoardB
@property&(nonatomic,&strong)&UIButton&*moreB
//键盘坐标系的转换
@property&(nonatomic,&assign)&CGRect&endKeyBoardF
//表情键盘
@property&(nonatomic,&strong)&FunctionView&*functionV
@property&(nonatomic,&strong)&MoreView&*moreV
//数据model
@property&(strong,&nonatomic)&ImageModelClass&&*imageM
@property&(strong,&nonatomic)HistoryImage&*tempI
//传输文字的block回调
@property&(strong,&nonatomic)&MyTextBlock&textB
//contentsinz
@property&(strong,&nonatomic)&ContentSizeBlock&sizeB
//传输volome的block回调
@property&(strong,&nonatomic)&AudioVolumeBlock&volumeB
//传输录音地址
@property&(strong,&nonatomic)&AudioURLBlock&urlB
//录音取消
@property&(strong,&nonatomic)&CancelRecordBlock&cancelB
//添加录音功能的属性
@property&(strong,&nonatomic)&AVAudioRecorder&*audioR
@property&(strong,&nonatomic)&NSTimer&*
@property&(strong,&nonatomic)&NSURL&*audioPlayURL;
@end2. 接受相应的Block回调,把block传入ToolView中,代码如下:-(void)setMyTextBlock:(MyTextBlock)block
&&&&self.textBlock&=&
-(void)setAudioVolumeBlock:(AudioVolumeBlock)block
&&&&self.volumeBlock&=&
-(void)setAudioURLBlock:(AudioURLBlock)block
&&&&self.urlBlock&=&
-(void)setContentSizeBlock:(ContentSizeBlock)block
&&&&self.sizeBlock&=&
-(void)setCancelRecordBlock:(CancelRecordBlock)block
&&&&self.cancelBlock&=&
}3. 控件的初始化,纯代码添加ToolView中要用到的组件(分配内存,配置相应的属性),因为是自定义组件的封装,所以我们的storyboard就用不上啦,添加控件的代码如下://控件的初始化
-(void)&addSubview
&&&&self.voiceChangeButton&=&[[UIButton&alloc]&initWithFrame:CGRectZero];
&&&&[self.voiceChangeButton&setImage:[UIImage&imageNamed:@"chat_bottom_voice_press.png"]&forState:UIControlStateNormal];
&&&&[self.voiceChangeButton&addTarget:self&action:@selector(tapVoiceChangeButton:)&forControlEvents:UIControlEventTouchUpInside];
&&&&[self&addSubview:self.voiceChangeButton];
&&&&self.sendVoiceButton&=&[[UIButton&alloc]&initWithFrame:CGRectZero];
&&&&[self.sendVoiceButton&setBackgroundImage:[UIImage&imageNamed:@"chat_bottom_textfield.png"]&forState:UIControlStateNormal];
&&&&[self.sendVoiceButton&setTitleColor:[UIColor&blackColor]&forState:UIControlStateNormal];
&&&&[self.sendVoiceButton&setTitle:@"按住说话"&forState:UIControlStateNormal];
&&&&[self.sendVoiceButton&addTarget:self&action:@selector(tapSendVoiceButton:)&forControlEvents:UIControlEventTouchUpInside];
&&&&self.sendVoiceButton.hidden&=&YES;
&&&&[self&addSubview:self.sendVoiceButton];
&&&&self.sendTextView&=&[[UITextView&alloc]&initWithFrame:CGRectZero];
&&&&self.sendTextView.delegate&=&
&&&&[self&addSubview:self.sendTextView];
&&&&self.changeKeyBoardButton&=&[[UIButton&alloc]&initWithFrame:CGRectZero];
&&&&[self.changeKeyBoardButton&setImage:[UIImage&imageNamed:@"chat_bottom_smile_nor.png"]&forState:UIControlStateNormal];
&&&&[self.changeKeyBoardButton&addTarget:self&action:@selector(tapChangeKeyBoardButton:)&forControlEvents:UIControlEventTouchUpInside];
&&&&[self&addSubview:self.changeKeyBoardButton];
&&&&self.moreButton&=&[[UIButton&alloc]&initWithFrame:CGRectZero];
&&&&[self.moreButton&setImage:[UIImage&imageNamed:@"chat_bottom_up_nor.png"]&forState:UIControlStateNormal];
&&&&[self.moreButton&addTarget:self&action:@selector(tapMoreButton:)&forControlEvents:UIControlEventTouchUpInside];
&&&&[self&addSubview:self.moreButton];
&&&&[self&addDone];
&&&&//实例化FunctionView
&&&&self.functionView&=&[[FunctionView&alloc]&initWithFrame:CGRectMake(0,&0,&320,&216)];
&&&&self.functionView.backgroundColor&=&[UIColor&blackColor];
&&&&//设置资源加载的文件名
&&&&self.functionView.plistFileName&=&@"emoticons";
&&&&__weak&__block&ToolView&*copy_self&=&
&&&&//获取图片并显示
&&&&[self.functionView&setFunctionBlock:^(UIImage&*image,&NSString&*imageText)
&&&&&&&&&NSString&*str&=&[NSString&stringWithFormat:@"%@%@",copy_self.sendTextView.text,&imageText];
&&&&&&&&&copy_self.sendTextView.text&=&
&&&&&&&&&//把使用过的图片存入sqlite
&&&&&&&&&NSData&*imageData&=&UIImagePNGRepresentation(image);
&&&&&&&&&[copy_self.imageMode&save:imageData&ImageText:imageText];
&&&&//给sendTextView添加轻击手势
&&&&UITapGestureRecognizer&*tapGesture&=&[[UITapGestureRecognizer&alloc]&initWithTarget:self&action:@selector(tapGesture:)];
&&&&[self.sendTextView&addGestureRecognizer:tapGesture];
&&&&//给sendVoiceButton添加长按手势
&&&&UILongPressGestureRecognizer&*longPress&=&[[UILongPressGestureRecognizer&alloc]&initWithTarget:self&action:@selector(sendVoiceButtonLongPress:)];
&&&&//设置长按时间
&&&&longPress.minimumPressDuration&=&0.2;
&&&&[self.sendVoiceButton&addGestureRecognizer:longPress];
&&&&//实例化MoreView
&&&&self.moreView&=&[[MoreView&alloc]&initWithFrame:CGRectMake(0,&0,&0,&0)];
&&&&self.moreView.backgroundColor&=&[UIColor&blackColor];
&&&&[self.moreView&setMoreBlock:^(NSInteger&index)&{
&&&&&&&&NSLog(@"MoreIndex&=&%d",(int)index);
}4. 给我们的控件添加相应的约束,为了适合不同的屏幕,所以自动布局是少不了的。当然啦给控件添加约束也必须是手写代码啦,添加约束的代码如下://给控件加约束
-(void)addConstraint
&&&&//给voicebutton添加约束
&&&&self.voiceChangeButton.translatesAutoresizingMaskIntoConstraints&=&NO;
&&&&NSArray&*voiceConstraintH&=&[NSLayoutConstraint&constraintsWithVisualFormat:@"H:|-5-[_voiceChangeButton(30)]"&options:0&metrics:0&views:NSDictionaryOfVariableBindings(_voiceChangeButton)];
&&&&[self&addConstraints:voiceConstraintH];
&&&&NSArray&*voiceConstraintV&=&[NSLayoutConstraint&constraintsWithVisualFormat:@"V:|-8-[_voiceChangeButton(30)]"&options:0&metrics:0&views:NSDictionaryOfVariableBindings(_voiceChangeButton)];
&&&&[self&addConstraints:voiceConstraintV];
&&&&//给MoreButton添加约束
&&&&self.moreButton.translatesAutoresizingMaskIntoConstraints&=&NO;
&&&&NSArray&*moreButtonH&=&[NSLayoutConstraint&constraintsWithVisualFormat:@"H:[_moreButton(30)]-5-|"&options:0&metrics:0&views:NSDictionaryOfVariableBindings(_moreButton)];
&&&&[self&addConstraints:moreButtonH];
&&&&NSArray&*moreButtonV&=&[NSLayoutConstraint&constraintsWithVisualFormat:@"V:|-8-[_moreButton(30)]"&options:0&metrics:0&views:NSDictionaryOfVariableBindings(_moreButton)];
&&&&[self&addConstraints:moreButtonV];
&&&&//给changeKeyBoardButton添加约束
&&&&self.changeKeyBoardButton.translatesAutoresizingMaskIntoConstraints&=&NO;
&&&&NSArray&*changeKeyBoardButtonH&=&[NSLayoutConstraint&constraintsWithVisualFormat:@"H:[_changeKeyBoardButton(33)]-43-|"&options:0&metrics:0&views:NSDictionaryOfVariableBindings(_changeKeyBoardButton)];
&&&&[self&addConstraints:changeKeyBoardButtonH];
&&&&NSArray&*changeKeyBoardButtonV&=&[NSLayoutConstraint&constraintsWithVisualFormat:@"V:|-5-[_changeKeyBoardButton(33)]"&options:0&metrics:0&views:NSDictionaryOfVariableBindings(_changeKeyBoardButton)];
&&&&[self&addConstraints:changeKeyBoardButtonV];
&&&&//给文本框添加约束
&&&&self.sendTextView.translatesAutoresizingMaskIntoConstraints&=&NO;
&&&&NSArray&*sendTextViewConstraintH&=&[NSLayoutConstraint&constraintsWithVisualFormat:@"H:|-45-[_sendTextView]-80-|"&options:0&metrics:0&views:NSDictionaryOfVariableBindings(_sendTextView)];
&&&&[self&addConstraints:sendTextViewConstraintH];
&&&&NSArray&*sendTextViewConstraintV&=&[NSLayoutConstraint&constraintsWithVisualFormat:@"V:|-10-[_sendTextView]-10-|"&options:0&metrics:0&views:NSDictionaryOfVariableBindings(_sendTextView)];
&&&&[self&addConstraints:sendTextViewConstraintV];
&&&&//语音发送按钮
&&&&self.sendVoiceButton.translatesAutoresizingMaskIntoConstraints&=&NO;
&&&&NSArray&*sendVoiceButtonConstraintH&=&[NSLayoutConstraint&constraintsWithVisualFormat:@"H:|-50-[_sendVoiceButton]-90-|"&options:0&metrics:0&views:NSDictionaryOfVariableBindings(_sendVoiceButton)];
&&&&[self&addConstraints:sendVoiceButtonConstraintH];
&&&&NSArray&*sendVoiceButtonConstraintV&=&[NSLayoutConstraint&constraintsWithVisualFormat:@"V:|-6-[_sendVoiceButton]-6-|"&options:0&metrics:0&views:NSDictionaryOfVariableBindings(_sendVoiceButton)];
&&&&[self&addConstraints:sendVoiceButtonConstraintV];
}5. 因为我们要发送录音,所以对音频部分的初始化是少不了的,以下代码是对音频的初始化//录音部分初始化
-(void)audioInit
&&&&NSError&*&err&=&
&&&&AVAudioSession&*audioSession&=&[AVAudioSession&sharedInstance];
&&&&[audioSession&setCategory&:AVAudioSessionCategoryPlayAndRecord&error:&err];
&&&&if(err){
&&&&&&&&NSLog(@"audioSession:&%@&%d&%@",&[err&domain],&[err&code],&[[err&userInfo]&description]);
&&&&[audioSession&setActive:YES&error:&err];
&&&&err&=&
&&&&if(err){
&&&&&&&&NSLog(@"audioSession:&%@&%d&%@",&[err&domain],&[err&code],&[[err&userInfo]&description]);
&&&&//通过可变字典进行配置项的加载
&&&&NSMutableDictionary&*setAudioDic&=&[[NSMutableDictionary&alloc]&init];
&&&&//设置录音格式(aac格式)
&&&&[setAudioDic&setValue:@(kAudioFormatMPEG4AAC)&forKey:AVFormatIDKey];
&&&&//设置录音采样率(Hz)&如:AVSampleRateKey==/96000(影响音频的质量)
&&&&[setAudioDic&setValue:@(44100)&forKey:AVSampleRateKey];
&&&&//设置录音通道数1&Or&2
&&&&[setAudioDic&setValue:@(1)&forKey:AVNumberOfChannelsKey];
&&&&//线性采样位数&&8、16、24、32
&&&&[setAudioDic&setValue:@16&forKey:AVLinearPCMBitDepthKey];
&&&&//录音的质量
&&&&[setAudioDic&setValue:@(AVAudioQualityHigh)&forKey:AVEncoderAudioQualityKey];
&&&&NSString&*strUrl&=&[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,&NSUserDomainMask,&YES)&lastObject];
&&&&NSString&*fileName&=&[NSString&stringWithFormat:@"%ld",&(long)[[NSDate&date]&timeIntervalSince1970]];
&&&&NSURL&*url&=&[NSURL&fileURLWithPath:[NSString&stringWithFormat:@"%@/%@.aac",&strUrl,&fileName]];
&&&&_audioPlayURL&=&
&&&&NSError&*
&&&&//初始化
&&&&self.audioRecorder&=&[[AVAudioRecorder&alloc]initWithURL:url&settings:setAudioDic&error:&error];
&&&&//开启音量检测
&&&&self.audioRecorder.meteringEnabled&=&YES;
&&&&self.audioRecorder.delegate&=&
}6. 添加键盘回收键Done//给键盘添加done键
-(void)&addDone
&&&&//TextView的键盘定制回收按钮
&&&&&UIToolbar&*&toolBar&=&[[UIToolbar&alloc]initWithFrame:CGRectMake(0,&0,&320,&30)];
&&&UIBarButtonItem&*&item1&=&[[UIBarButtonItem&alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemDone&target:self&action:@selector(tapDone:)];
&&&&UIBarButtonItem&*&item2&=&[[UIBarButtonItem&alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace&target:nil&action:nil];
&&&&&&UIBarButtonItem&*&item3&=&[[UIBarButtonItem&alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace&target:nil&action:nil];
&&&&toolBar.items&=&@[item2,item1,item3];
&&&&&self.sendTextView.inputAccessoryView&=toolB
}三.编写控件的回调方法控件添加好以后下面要添加触发控件要干的事情:1. 从最复杂的开始,长按发送录音的按钮时,会录音。松开收时会发送(在发送时要判断音频的时间,太小不允许发送)。录音时上滑取消录音
(删除录音文件)。主要是给录音按钮加了一个LongPress手势,根据手势的状态来做不同的事情。关于手势的内容请参考之前的博客:(),下面是录音业务逻辑的实现(个人在Coding的时候,感觉这一块是工具条中最复杂的部分),代码如下:  //长按手势触发的方法
-(void)sendVoiceButtonLongPress:(id)sender
&&&&static&int&i&=&1;
&&&&if&([sender&isKindOfClass:[UILongPressGestureRecognizer&class]])&{
&&&&&&&&UILongPressGestureRecognizer&*&longPress&=&
&&&&&&&&//录音开始
&&&&&&&&if&(longPress.state&==&UIGestureRecognizerStateBegan)
&&&&&&&&&&&&
&&&&&&&&&&&&i&=&1;
&&&&&&&&&&&&
&&&&&&&&&&&&[self.sendVoiceButton&setTitleColor:[UIColor&redColor]&forState:UIControlStateNormal];
&&&&&&&&&&&&//录音初始化
&&&&&&&&&&&&[self&audioInit];
&&&&&&&&&&&&
&&&&&&&&&&&&//创建录音文件,准备录音
&&&&&&&&&&&&if&([self.audioRecorder&prepareToRecord])
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&//开始
&&&&&&&&&&&&&&&&[self.audioRecorder&record];
&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&//设置定时检测音量变化
&&&&&&&&&&&&&&&&_timer&=&[NSTimer&scheduledTimerWithTimeInterval:0.05&target:self&selector:@selector(detectionVoice)&userInfo:nil&repeats:YES];
&&&&&&&&&&&&}
&&&&&&&&//取消录音
&&&&&&&&if&(longPress.state&==&UIGestureRecognizerStateChanged)
&&&&&&&&&&&&
&&&&&&&&&&&&CGPoint&piont&=&[longPress&locationInView:self];
&&&&&&&&&&&&NSLog(@"%f",piont.y);
&&&&&&&&&&&&if&(piont.y&&1)
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&//如果录制时间<2&不发送
&&&&&&&&&&&&&&&&&&&&NSLog(@"发出去");
&&&&&&&&&&&&&&&&&&&&self.urlBlock(self.audioPlayURL);
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&else
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&//删除记录的文件
&&&&&&&&&&&&&&&&&&&&[self.audioRecorder&deleteRecording];
&&&&&&&&&&&&&&&&&&&&UIAlertView&*alter&=&[[UIAlertView&alloc]&initWithTitle:@"提示"&message:@"录音时间太短!"&delegate:nil&cancelButtonTitle:@"取消"&otherButtonTitles:&nil];
&&&&&&&&&&&&&&&&&&&&[alter&show];
&&&&&&&&&&&&&&&&&&&&self.cancelBlock(1);
&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&[self.audioRecorder&stop];
&&&&&&&&&&&&&&&&[_timer&invalidate];
&&&&&&&&&&&&}
}2. 下面的代码是检测音量的变化,用于根据音量变化图片,代码如下://录音的音量探测
-&(void)detectionVoice
&&&&[self.audioRecorder&updateMeters];//刷新音量数据
&&&&//获取音量的平均值&&[recorder&averagePowerForChannel:0];
&&&&//音量的最大值&&[recorder&peakPowerForChannel:0];
&&&&CGFloat&lowPassResults&=&pow(10,&(0.05&*&[self.audioRecorder&peakPowerForChannel:0]));
&&&&//把声音的音量传给调用者
&&&&self.volumeBlock(lowPassResults);
}3.轻击输入框时,切换到系统键盘,代码如下://轻击sendText切换键盘
-(void)tapGesture:(UITapGestureRecognizer&*)&sender
&&&&if&([self.sendTextView.inputView&isEqual:self.functionView])
&&&&&&&&self.sendTextView.inputView&=&
&&&&&&&&[self.changeKeyBoardButton&setImage:[UIImage&imageNamed:@"chat_bottom_smile_nor.png"]&forState:UIControlStateNormal];
&&&&&&&&[self.sendTextView&reloadInputViews];
&&&&if&(![self.sendTextView&isFirstResponder])
&&&&&&&&[self.sendTextView&becomeFirstResponder];
}4. 通过输入框的文字多少改变toolView的高度,因为输入框的约束是加在ToolView上的,所以需要把输入框的ContentSize通过
block传到ToolView的调用者上,让ToolView的父视图来改变ToolView的高度,从而sendTextView的高度也会随着改变
的,下面的代码是把ContentSize交给父视图:代码如下://通过文字的多少改变toolView的高度
-(void)textViewDidChange:(UITextView&*)textView
&&&&CGSize&contentSize&=&self.sendTextView.contentS
&&&&self.sizeBlock(contentSize);
}效果如下,文字多时TextView的高度也会增大:5. 点击最左边的按钮触发的事件(切换文本输入框和录音按钮),代码如下://切换声音按键和文字输入框
-(void)tapVoiceChangeButton:(UIButton&*)&sender
&&&&if&(self.sendVoiceButton.hidden&==&YES)
&&&&&&&&self.sendTextView.hidden&=&YES;
&&&&&&&&self.sendVoiceButton.hidden&=&NO;
&&&&&&&&[self.voiceChangeButton&setImage:[UIImage&imageNamed:@"chat_bottom_keyboard_nor.png"]&forState:UIControlStateNormal];
&&&&&&&&if&([self.sendTextView&isFirstResponder])&{
&&&&&&&&&&&&[self.sendTextView&resignFirstResponder];
&&&&&&&&self.sendTextView.hidden&=&NO;
&&&&&&&&self.sendVoiceButton.hidden&=&YES;
&&&&&&&&[self.voiceChangeButton&setImage:[UIImage&imageNamed:@"chat_bottom_voice_press.png"]&forState:UIControlStateNormal];
&&&&&&&&if&(![self.sendTextView&isFirstResponder])&{
&&&&&&&&&&&&[self.sendTextView&becomeFirstResponder];
}6. 点击return发送文字(通过Block回调传入到父视图上),代码如下://发送信息(点击return)
-&(BOOL)textView:(UITextView&*)textView&shouldChangeTextInRange:(NSRange)range&replacementText:(NSString&*)text
&&&&if&([text&isEqualToString:@"\n"])
&&&&&&&&//通过block回调把text的值传递到Controller中共
&&&&&&&&self.textBlock(self.sendTextView.text);
&&&&&&&&self.sendTextView.text&=&@"";
&&&&&&&&return&NO;
&&&&return&YES;
}7. 录音按钮本身要做的事情(在LongPress没有被触发时调用)代码如下://发送声音按钮回调的方法
-(void)tapSendVoiceButton:(UIButton&*)&sender
&&&&NSLog(@"sendVoiceButton");
&&&&//点击发送按钮没有触发长按手势要做的事儿
&&&&UIAlertView&*alter&=&[[UIAlertView&alloc]&initWithTitle:@"提示"&message:@"按住录音"&delegate:nil&cancelButtonTitle:@"取消"&otherButtonTitles:&nil];
&&&&[alter&show];
}8. 调用表情键盘://变成表情键盘
-(void)tapChangeKeyBoardButton:(UIButton&*)&sender
&&&&if&([self.sendTextView.inputView&isEqual:self.functionView])
&&&&&&&&self.sendTextView.inputView&=&
&&&&&&&&[self.changeKeyBoardButton&setImage:[UIImage&imageNamed:@"chat_bottom_smile_nor.png"]&forState:UIControlStateNormal];
&&&&&&&&[self.sendTextView&reloadInputViews];
&&&&&&&&self.sendTextView.inputView&=&self.functionV
&&&&&&&&[self.changeKeyBoardButton&setImage:[UIImage&imageNamed:@"chat_bottom_keyboard_nor.png"]&forState:UIControlStateNormal];
&&&&&&&&[self.sendTextView&reloadInputViews];
&&&&if&(![self.sendTextView&isFirstResponder])
&&&&&&&&[self.sendTextView&becomeFirstResponder];
&&&&if&(self.sendTextView.hidden&==&YES)&{
&&&&&&&&self.sendTextView.hidden&=&NO;
&&&&&&&&self.sendVoiceButton.hidden&=&YES;
&&&&&&&&[self.voiceChangeButton&setImage:[UIImage&imageNamed:@"chat_bottom_voice_press.png"]&forState:UIControlStateNormal];
}以上就是ToolView的所有封装代码,至于在Controller中如何使用他来发送消息,如何定义聊天Cell,如何处理录音文件,聊天时的气泡是如何实现的等功能,在以后的博客中会继续讲解,希望大家继续关注。
微信扫一扫
订阅每日移动开发及APP推广热点资讯公众号:CocoaChina
点击量13789点击量12578点击量8155点击量7014点击量6909点击量6862点击量6356点击量5440点击量5011
&2015 Chukong Technologies,Inc.
京公网安备89

我要回帖

更多关于 ios ui控件 的文章

 

随机推荐