iOS开发——UI篇OC&transform详解
transframe属性详解
1. transform属性
在OC中,通过transform属性可以修改对象的平移、缩放比例和旋转角度
常用的创建transform结构体方法分两大类
(1) 创建“基于控件初始位置”的形变
CGAffineTransformMakeTranslation(平移)
CGAffineTransformMakeScale(缩放)
CGAffineTransformMakeRotation(旋转)
(2) 创建“基于transform参数”的形变
CGAffineTransformTranslate
CGAffineTransformScale
CGAffineTransformRotate
补充:
在OC中,所有跟角度相关的数值,都是弧度值,180° = M_PI
正数表示顺时针旋转
负数表示逆时针旋转
/**
* 2D缩放
*/
//起始位置:仅一次
self.imageView2D.transform = CGAffineTransformMakeScale(, );
//当前位置:多次
self.imageView2D.transform = CGAffineTransformScale(self.imageView3D.transform, , );
/**
* 2D旋转
*/
//起始位置:仅一次
self.imageView2D.transform = CGAffineTransformMakeRotation(M_PI_4);
//当前位置:多次;
self.imageView2D.transform = CGAffineTransformRotate(self.imageView3D.transform, M_PI_4);
/**
* 2D平移
*/
//起始位置:仅一次
self.imageView2D.transform = CGAffineTransformMakeTranslation(, );
//当前位置:多次
self.imageView2D.transform = CGAffineTransformTranslate(self.imageView3D.transform, , );
/**
* 2D还原
*/
self.imageView2D.transform = CGAffineTransformIdentity;
其他:
/**
/* Invert `t' and return the result. If `t' has zero determinant, then `t'
is returned unchanged. */
CG_EXTERN CGAffineTransform CGAffineTransformInvert(CGAffineTransform t)
CG_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
/* Concatenate `t2' to `t1' and return the result:
t' = t1 * t2 */
CG_EXTERN CGAffineTransform CGAffineTransformConcat(CGAffineTransform t1,
CGAffineTransform t2) CG_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
*/
提示:由于transform属性可以基于控件的上一次的状态进行叠加形变,例如,先旋转再平移。因此在实际动画开发中,当涉及位置、尺寸形变效果时,大多修改控件的transform属性,而不是frame、bounds、center 。
2.代码示例
//
// YYViewController.m
// 01-练习使用按钮的frame和center属性
//
// Created by apple on 14-5-21.
// Copyright (c) 2014年 itcase. All rights reserved.
//
#import "YYViewController.h"
//私有扩展
@interface YYViewController ()
@property(nonatomic,weak)IBOutlet UIButton *headImageView;
@end
@implementation YYViewController
//枚举类型,从1开始
//枚举类型有一个很大的作用,就是用来代替程序中的魔法数字
typedef enum
{
ktopbtntag=,
kdownbtntag,
krightbtntag,
kleftbtntag
}btntag;
//viewDidLoad是视图加载完成后调用的方法,通常在此方法中执行视图控制器的初始化工作
- (void)viewDidLoad
{
//在viewDidLoad方法中,不要忘记调用父类的方法实现
[super viewDidLoad];
//手写控件代码
//一、写一个按钮控件,上面有一张图片
//1.使用类创建一个按钮对象
// UIButton *headbtn=[[UIButton alloc] initWithFrame:CGRectMake(100 ,100, 100, 100)];
//设置按钮对象为自定义型
UIButton *headbtn=[UIButton buttonWithType:UIButtonTypeCustom];
//2.设置对象的各项属性
//(1)位置等通用属性设置
headbtn.frame=CGRectMake(, , , );
//(2)设置普通状态下按钮的属性
[headbtn setBackgroundImage:[UIImage imageNamed:@"i"] forState:UIControlStateNormal];
[headbtn setTitle:@"点我!" forState:UIControlStateNormal];
[headbtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
//(3)设置高亮状态下按钮的属性
[headbtn setBackgroundImage:[UIImage imageNamed:@"a"] forState:UIControlStateHighlighted];
[headbtn setTitle:@"还行吧~" forState:UIControlStateHighlighted];
[headbtn setTitleColor:[UIColor blueColor] forState:UIControlStateHighlighted];
//3.把对象添加到视图中展现出来
[self.view addSubview:headbtn];
//注意点!
self.headImageView=headbtn;
//二、写四个控制图片左右上下移动方向的按钮控件
/**================向上的按钮=====================*/
//1.创建按钮对象
UIButton *topbtn=[UIButton buttonWithType:UIButtonTypeCustom];
//2.设置对象的属性
topbtn.frame=CGRectMake(, , , );
[topbtn setBackgroundImage:[UIImage imageNamed:@"top_normal"] forState:UIControlStateNormal];
[topbtn setBackgroundImage:[UIImage imageNamed:@"top_highlighted"] forState:UIControlStateHighlighted];
[topbtn setTag:];
//3.把控件添加到视图中
[self.view addSubview:topbtn];
//4.按钮的单击控制事件
[topbtn addTarget:self action:@selector(Click:) forControlEvents:UIControlEventTouchUpInside];
/**================向下的按钮=====================*/
//1.创建按钮对象
UIButton *downbtn=[UIButton buttonWithType:UIButtonTypeCustom];
//2.设置对象的属性
downbtn.frame=CGRectMake(, , , );
[downbtn setBackgroundImage:[UIImage imageNamed:@"bottom_normal"] forState:UIControlStateNormal];
[downbtn setBackgroundImage:[UIImage imageNamed:@"bottom_highlighted"] forState:UIControlStateHighlighted];
[downbtn setTag:];
//3.把控件添加到视图中
[self.view addSubview:downbtn];
//4.按钮的单击控制事件
[downbtn addTarget:self action:@selector(Click:) forControlEvents:UIControlEventTouchUpInside];
/**================向左的按钮=====================*/
//1.创建按钮对象
UIButton *leftbtn=[UIButton buttonWithType:UIButtonTypeCustom];
//2.设置对象的属性
leftbtn.frame=CGRectMake(, , , );
[leftbtn setBackgroundImage:[UIImage imageNamed:@"left_normal"] forState:UIControlStateNormal];
[leftbtn setBackgroundImage:[UIImage imageNamed:@"left_highlighted"] forState:UIControlStateHighlighted];
[leftbtn setTag:];
//3.把控件添加到视图中
[self.view addSubview:leftbtn];
//4.按钮的单击控制事件
[leftbtn addTarget:self action:@selector(Click:) forControlEvents:UIControlEventTouchUpInside];
/**================向右的按钮=====================*/
//1.创建按钮对象
UIButton *rightbtn=[UIButton buttonWithType:UIButtonTypeCustom];
//2.设置对象的属性
rightbtn.frame=CGRectMake(, , , );
[rightbtn setBackgroundImage:[UIImage imageNamed:@"right_normal"] forState:UIControlStateNormal];
[rightbtn setBackgroundImage:[UIImage imageNamed:@"right_highlighted"] forState:UIControlStateHighlighted];
[rightbtn setTag:];
//3.把控件添加到视图中
[self.view addSubview:rightbtn];
//4.按钮的单击控制事件
[rightbtn addTarget:self action:@selector(Click:) forControlEvents:UIControlEventTouchUpInside];
//三、写两个缩放按钮
/**================放大的按钮=====================*/
//1.创建对象
UIButton *plusbtn=[UIButton buttonWithType:UIButtonTypeCustom];
//2.设置属性
plusbtn.frame=CGRectMake(, , , );
[plusbtn setBackgroundImage:[UIImage imageNamed:@"plus_normal"] forState:UIControlStateNormal];
[plusbtn setBackgroundImage:[UIImage imageNamed:@"plus_highlighted"] forState:UIControlStateHighlighted];
[plusbtn setTag:];
//3.添加到视图
[self.view addSubview:plusbtn];
//4.单击事件
[plusbtn addTarget:self action:@selector(Zoom:) forControlEvents:UIControlEventTouchUpInside];
/**================缩小的按钮=====================*/
UIButton *minusbtn=[UIButton buttonWithType:UIButtonTypeCustom];
minusbtn.frame=CGRectMake(, , , );
[minusbtn setBackgroundImage:[UIImage imageNamed:@"minus_normal"] forState:UIControlStateNormal];
[minusbtn setBackgroundImage:[UIImage imageNamed:@"minus_highlighted"] forState:UIControlStateHighlighted];
[minusbtn setTag:];
[self.view addSubview:minusbtn];
[minusbtn addTarget:self action:@selector(Zoom:) forControlEvents:UIControlEventTouchUpInside];
/**================向左旋转按钮=====================*/
UIButton *leftrotatebtn=[UIButton buttonWithType:UIButtonTypeCustom];
[leftrotatebtn setFrame:CGRectMake(, , , )];
[leftrotatebtn setBackgroundImage:[UIImage imageNamed:@"left_rotate_normal"] forState:UIControlStateNormal];
[leftrotatebtn setBackgroundImage:[UIImage imageNamed:@"left_rotate_highlighted"] forState:UIControlStateHighlighted];
[leftrotatebtn setTag:];
[self.view addSubview:leftrotatebtn];
[leftrotatebtn addTarget:self action:@selector(Rotate:) forControlEvents:UIControlEventTouchUpInside];
/**================向右旋转按钮=====================*/
UIButton *rightrotatebtn=[UIButton buttonWithType:UIButtonTypeCustom];
[rightrotatebtn setFrame:CGRectMake(, , , )];
[rightrotatebtn setBackgroundImage:[UIImage imageNamed:@"right_rotate_normal"] forState:UIControlStateNormal];
[rightrotatebtn setBackgroundImage:[UIImage imageNamed:@"right_rotate_highlighted"] forState:UIControlStateHighlighted];
[rightbtn setTag:];
[self.view addSubview:rightrotatebtn];
[rightrotatebtn addTarget:self action:@selector(Rotate:) forControlEvents:UIControlEventTouchUpInside];
}
//控制方向的多个按钮调用同一个方法
-(void)Click:(UIButton *)button
{
//练习使用frame属性
//CGRect frame=self.headImageView.frame;
/**注意,这里如果控制位置的两个属性frame和center同时使用的话,会出现很好玩的效果,注意分析*/
//练习使用center属性
CGPoint center=self.headImageView.center;
switch (button.tag) {
case ktopbtntag:
center.y-=;
break;
case kdownbtntag:
center.y+=;
break;
case kleftbtntag:
//发现一个bug,之前的问题是因为少写了break,造成了它们的顺序执行,sorry
//center.x=center.x-30;
center.x-=;
break;
case krightbtntag:
center.x+=;
break;
}
// self.headImageView.frame=frame;
//首尾式设置动画效果
[UIView beginAnimations:nil context:nil];
self.headImageView.center=center;
//设置时间
[UIView setAnimationDuration:2.0];
[UIView commitAnimations];
NSLog(@"移动!");
}
-(void)Zoom:(UIButton *)btn
{
//使用bounds,以中心点位原点进行缩放
CGRect bounds = self.headImageView.bounds;
if (btn.tag) {
bounds.size.height+=;
bounds.size.width+=;
}
else
{
bounds.size.height-=;
bounds.size.width-=;
}
//设置首尾动画
[UIView beginAnimations:nil context:nil];
self.headImageView.bounds=bounds;
[UIView setAnimationDuration:2.0];
[UIView commitAnimations];
}
-(void)Rotate:(UIButton *)rotate
{
//位移(不累加)
//self.headImageView.transform=CGAffineTransformMakeTranslation(50, 200);
//缩放
//self.headImageView.transform=CGAffineTransformMakeScale(1.2, 10);
//在原有的基础上位移(是累加的)
//self.headImageView.transform=CGAffineTransformTranslate(self.headImageView.transform, 50, 50);
//在原有的基础上进行缩放
//self.headImageView.transform=CGAffineTransformScale(self.headImageView.transform, 1.5, 1.6);
//在原有的基础上进行旋转
if (rotate.tag) {
//旋转角度为1/pi,逆时针
self.headImageView.transform=CGAffineTransformRotate(self.headImageView.transform, -M_1_PI);
}
else
{
//旋转的角度为pi/2,顺时针
self.headImageView.transform=CGAffineTransformRotate(self.headImageView.transform, M_PI_2);
}
}
@end
3.viewDidLoad
viewDidLoad是视图加载完成后调用的方法,通常在此方法中执行视图控制器的初始化工作
在viewDidLoad方法中,一定不要忘记调用父类的方法实现
[super viewDidLoad];
CATransform3D
/**
* 3D缩放
*/
//起始位置:仅一次
self.imageView3D.layer.transform = CATransform3DMakeScale(1.0, 0.8, 0.9);
//当前位置:多次
self.imageView3D.layer.transform = CATransform3DScale(self.imageView3D.layer.transform, 1.0, 0.8, 0.9);
/**
* 3D旋转
*/
//起始位置:仅一次
self.imageView3D.layer.transform = CATransform3DMakeRotation(M_PI/, 0.5, 0.8, 0.3);
//当前位置:多次
self.imageView3D.layer.transform = CATransform3DRotate(self.imageView3D.layer.transform, M_PI_2, , );
/**
* 3D平移
*/
//起始位置:仅一次
self.imageView3D.layer.transform = CATransform3DMakeTranslation(, , );
//当前位置:多次
self.imageView3D.layer.transform = CATransform3DTranslate(self.imageView3D.layer.transform, , , );
/**
* 3D
*/
//起始位置:仅一次
// self.imageView3D.layer.transform = CATransform3DMakeAffineTransform(<#CGAffineTransform m#>);
// //当前位置:多次
// self.imageView3D.layer.transform = CATransform3DIsAffine(<#CATransform3D t#>)
CATransform3D结构成员的意义。
struct CATransform3D
{
CGFloat m11(x缩放), m12(y切变), m13(旋转), m14();
CGFloat m21(x切变), m22(y缩放), m23(), m24();
CGFloat m31(旋转), m32(), m33(), m34(透视效果,要操作的这个对象要有旋转的角度,否则没有效果。正直/负值都有意义);
CGFloat m41(x平移), m42(y平移), m43(z平移), m44();
};
ps:整体比例变换时,也就是m11==m22时,若m33>,图形整体缩小,若0<m33<,图形整体放大,若s<,发生关于原点的对称等比变换。
()空的地方以后补充。
. CATransform3DMakeTranslation
CATransform3DMakeTranslation(, , ) 创建了一个4*4的单位矩阵。
. CATransform3DMakeRotation And CATransform3DRotate
CATransform3DMakeRotation()
_transformedLayer = [CALayer layer];
_transformedLayer.frame = self.bounds;
_transformedLayer.anchorPoint = CGPointMake(0.5f, 0.5f);
CATransform3D sublayerTransform = CATransform3DIdentity;
// Set perspective
sublayerTransform.m34 = kPerspective;
[_transformedLayer setSublayerTransform:sublayerTransform];
[self.layer addSublayer:_transformedLayer];
//init Sublayers
CATransform3D t = CATransform3DMakeTranslation(, , );
// take snapshot of the current view
[_transformedLayer addSublayer:[self snapshot:t
withView:_contentView
isMasked:YES]];
// 暂时先支持一个方向翻转
RotateDirection direction = RotateFromBottom;
if (YES || direction == RotateFromBottom)
{
CGFloat height = self.bounds.size.height;
//CGFloat cubeSize = 100.0f;
t = CATransform3DRotate(t, D2R(, , );【】
t = CATransform3DTranslate(t, , height, );
CALayer *subLayer = [self snapshot:t withView:view isMasked:YES];
[_transformedLayer addSublayer:subLayer];
}
else
{
}
_newContentView = view;
[self animationCubeRotate:direction withDuration:duration];
. 翻转的动画
- (void)animationCubeRotate:(RotateDirection)direction
withDuration:(float)duration
{
[CATransaction flush];
CGFloat height = self.bounds.size.height;
CABasicAnimation *rotation;
// CABasicAnimation *translationX; // 如果沿X轴翻转,则用不到这个变量.
CABasicAnimation *translationY; // 如果沿Y轴翻转,则用不到这个变量.
CABasicAnimation *translationZ;
CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
animationGroup.delegate = self;
animationGroup.duration = duration;
if ( direction == RotateFromBottom )
{
// 创建(某方向)关键帧动画.
translationY = [CABasicAnimation animationWithKeyPath:
@"sublayerTransform.translation.y"];
translationY.toValue = [NSNumber numberWithFloat:-(height / )];【】
rotation = [CABasicAnimation animationWithKeyPath:
@"sublayerTransform.rotation.x"];
rotation.toValue = [NSNumber numberWithFloat:D2R(-90.0f)];
}
else if ( direction == RotateFromTop )
{
}
// 处理Z轴
translationZ = [CABasicAnimation animationWithKeyPath:
@"sublayerTransform.translation.z"];
translationZ.toValue = [NSNumber numberWithFloat:height / ];【】
animationGroup.animations =
[NSArray arrayWithObjects: rotation, translationY, translationZ, nil];
animationGroup.fillMode = kCAFillModeForwards;
animationGroup.removedOnCompletion = NO;
[_transformedLayer addAnimation:animationGroup forKey:kAnimationKey];
}
高级使用:
透射投影:(矩阵相乘)
首先封装我们想要的功能
CATransform3D CATransform3DMakePerspective(CGPoint center, float disZ)
{
CATransform3D transToCenter = CATransform3DMakeTranslation(-center.x, -center.y, );
CATransform3D transBack = CATransform3DMakeTranslation(center.x, center.y, );
CATransform3D scale = CATransform3DIdentity;
scale.m34 = -1.0f/disZ;
return CATransform3DConcat(CATransform3DConcat(transToCenter, scale), transBack);
}
CATransform3D CATransform3DPerspect(CATransform3D t, CGPoint center, float disZ)
{
return CATransform3DConcat(t, CATransform3DMakePerspective(center, disZ));
}
那么使用起来就非常简单了:
CATransform3D rotate = CATransform3DMakeRotation(M_PI/, , , );
self.imageView3D.layer.transform = CATransform3DPerspect(rotate, CGPointMake(, ), );
// CATransform3D rotate = CATransform3DMakeRotation(M_PI/6, 0, 0, 1);
// self.imageView3D.layer.transform = CATransform3DPerspect(rotate, CGPointMake(0, 0), 200);
四张同样大小的图片围成一个框,让这个框动画旋转。
CATransform3D move = CATransform3DMakeTranslation(, , ); CATransform3D back = CATransform3DMakeTranslation(, , -); CATransform3D rotate0 = CATransform3DMakeRotation(-angle, , , ); CATransform3D rotate1 = CATransform3DMakeRotation(M_PI_2-angle, , , ); CATransform3D rotate2 = CATransform3DMakeRotation(M_PI_2*-angle, , , ); CATransform3D rotate3 = CATransform3DMakeRotation(M_PI_2*-angle, , , ); CATransform3D mat0 = CATransform3DConcat(CATransform3DConcat(move, rotate0), back); CATransform3D mat1 = CATransform3DConcat(CATransform3DConcat(move, rotate1), back); CATransform3D mat2 = CATransform3DConcat(CATransform3DConcat(move, rotate2), back); CATransform3D mat3 = CATransform3DConcat(CATransform3DConcat(move, rotate3), back); image0.layer.transform = CATransform3DPerspect(mat0, CGPointZero, ); image1.layer.transform = CATransform3DPerspect(mat1, CGPointZero, ); image2.layer.transform = CATransform3DPerspect(mat2, CGPointZero, ); image3.layer.transform = CATransform3DPerspect(mat3, CGPointZero, );
普通界面的立体翻转效果
* 1.732f;
CATransform3D move = CATransform3DMakeTranslation(, , dis);
CATransform3D back = CATransform3DMakeTranslation(, , -dis);
CATransform3D rotate0 = CATransform3DMakeRotation(-angle, , , );
CATransform3D rotate1 = CATransform3DMakeRotation(-angle + M_PI/, , );
CATransform3D mat0 = CATransform3DConcat(CATransform3DConcat(move, rotate0), back);
CATransform3D mat1 = CATransform3DConcat(CATransform3DConcat(move, rotate1), back);
view0.layer.transform = CATransform3DPerspect(mat0, CGPointZero, );
view1.layer.transform = CATransform3DPerspect(mat1, CGPointZero, );
本文需要一定的数学基础,特别是想要实现非常炫酷的效果,当然如果你只是想要实现简单的动画效果那么久没那么多要求了!
iOS开发——UI篇OC&transform详解的更多相关文章
- iOS开发——UI篇OC篇&UIDynamic详解
iOS开发拓展篇—UIDynamic(简单介绍) 一.简单介绍 1.什么是UIDynamic UIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架 可以认为是一种物理引擎,能模拟 ...
- iOS开发——UI篇OC篇&SpriteKit详解
SpriteKit详解 SpriteKit,iOS/Mac游戏制作的新纪元 这是我的WWDC2013系列笔记中的一篇,完整的笔记列表请参看这篇总览.本文仅作为个人记录使用,也欢迎在许可协议范围内转载或 ...
- iOS开发——UI篇OC篇&UIStackView详解
UIStackView详解 一.继承关系.遵守协议.隶属框架及可用平台 UIStackView 类提供了一个高效的接口用于平铺一行或一列的视图组合.Stack视图使你依靠自动布局的能力,创建用户接口使 ...
- iOS开发——UI篇OC篇&UICollectionView详解+实例
UICollectionView详解+实例 实现步骤: 一.新建两个类 1.继承自UIScrollView的子类,比如HMWaterflowView * 瀑布流显示控件,用来显示所有的瀑布流数据 2. ...
- iOS开发——UI篇OC篇&UITableView简单封装
UITableView简单封装 UITableView时iOS开发中使用最多也是最重的一个UI空间,其实在App Store里面的%80以上的应用都用到了这个控件,所以就给大家介绍一下,前面的文章中也 ...
- iOS开发——UI篇OC篇&TextField作为搜索框的使用
TextField作为搜索框的使用 在iOS开发中我们经常会使用到搜索框,但是有的时候系统自带的搜索框不足以满足我吗想要的功能,这个时候我们就可以使用自定义的搜索框实现想要的功能. 今天就简单的介绍一 ...
- 【转】IOS开发网络篇之──ASIHTTPRequest详解
ASIHTTPRequest 详解, http 请求终结者 版权归旺财勇士所有〜转载需声名〜 原贴地地址:http://wiki.magiche.net/pages/viewpage.action?p ...
- iOS开发——UI篇OC篇&UIView/UIWindow/UIScreen/CALayer
UIView/UIWindow/UIScreen/CALayer 1.UIScreen可以获取设备屏幕的大小. 1 2 3 4 5 6 7 // 整个屏幕的大小 {{0, 0}, {320, 480} ...
- iOS开发——UI篇OC篇&不规则排列的图片布局
不规则排列的图片布局 一直在500px上看照片,发照片.以前看它的首页图片展示就只是觉得好看,洋气,也没想过自己在iOS上实现一下.昨天不知怎么的就开始想其中的算法了,现在我把思考的过程在这里贴出来分 ...
随机推荐
- [POJ 3788] Interior Points of Lattice Polygons
同swustoj 169 Interior Points of Lattice Polygons Time Limit: 1000MS Memory Limit: 65536K Total Sub ...
- shell 全局和局部变量
/******************************************************************** * shell 全局和局部变量 * 声明: * 到目前为止, ...
- 我个人有关 Azure 网络 SLA、带宽、延迟、性能、SLB、DNS、DMZ、VNET、IPv6 等的 Azure 常见问题解答
Igor Pagliai(微软) 2014 年 9月 28日上午 5:57 年 11 月 3 年欧洲 TechEd 大会新宣布的内容). 重要提示:这篇文章中我提供的信息具有时间敏感性,因为这些 ...
- Go语言项目的错误和异常管理 via 达达
Go语言项目的错误和异常管理 最近连续遇到朋友问我项目里错误和异常管理的事情,之前也多次跟团队强调过错误和异常管理的一些概念,所以趁今天有动力就赶紧写一篇Go语言项目错误和异常管理的经验分享. 首先我 ...
- MySQL中间层 Atlas
Atlas是由 Qihoo 360, Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目.它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基础上,修改了大量bu ...
- Webdriver API (一)
(转载) 1.1 下载selenium2.0的包 官方download包地址:http://code.google.com/p/selenium/downloads/list 官方User Guid ...
- 开源了一个iOS输入控件【原】
1.Github 地址:https://github.com/linyc/InputBarFollowKeyboard 2.说明文档:https://github.com/linyc/InputBar ...
- Leetcode OJ : Implement strStr() [ Boyer–Moore string search algorithm ] python solution
class Solution { public: int strStr(char *haystack, char *needle) { , skip[]; char *str = haystack, ...
- PHP编码规范整理,很全很实用(图文版)
有一个组织叫做“php互操作性框架制定小组”,这个小组的主要目的是制定各种PHP编码规范的,下面就是我根据小组提供的建议整理的一些常用的编码规范. PSR-1: 1.PHP代码文件必须以<?ph ...
- Eclipse安装ADT插件
安卓开发环境搭建,如果选择的是ADT Bundle,则包含了eclipse和adt tools.但是有些时候是在已经独立安装了Eclipse的基础上,在线安装ADT插件,就稍微麻烦了. 一.在线安装A ...