当前位置: 首页 > news >正文

扬州建设教育信息网站微信app下载最新版本

扬州建设教育信息网站,微信app下载最新版本,ui自学网站,阿里云服务器上传网站阴影 主要是shadowOpacity 、shadowColor、shadowOffset和shadowRadius四个属性 shadowPath属性 我们已经知道图层阴影并不总是方的#xff0c;而是从图层内容的形状继承而来。这看上去不错#xff0c;但是实时计算阴影也是一个非常消耗资源的#xff0c;尤其是图层有多个子…阴影 主要是shadowOpacity 、shadowColor、shadowOffset和shadowRadius四个属性 shadowPath属性 我们已经知道图层阴影并不总是方的而是从图层内容的形状继承而来。这看上去不错但是实时计算阴影也是一个非常消耗资源的尤其是图层有多个子图层每个图层还有一个有透明效果的寄宿图的时候。 如果你事先知道你的阴影形状会是什么样子的你可以通过指定一个shadowPath来提高性能。shadowPath是一个CGPathRef类型一个指向CGPath的指针。CGPath是一个Core Graphics对象用来指定任意的一个矢量图形。我们可以通过这个属性单独于图层形状之外指定阴影的形状。 interface ViewController () property (nonatomic, weak) IBOutlet UIView *layerView1; property (nonatomic, weak) IBOutlet UIView *layerView2; end implementation ViewController - (void)viewDidLoad {[super viewDidLoad];//enable layer shadowsself.layerView1.layer.shadowOpacity 0.5f;self.layerView2.layer.shadowOpacity 0.5f;//create a square shadowCGMutablePathRef squarePath CGPathCreateMutable();CGPathAddRect(squarePath, NULL, self.layerView1.bounds);self.layerView1.layer.shadowPath squarePath; CGPathRelease(squarePath);?//create a circular shadowCGMutablePathRef circlePath CGPathCreateMutable();CGPathAddEllipseInRect(circlePath, NULL, self.layerView2.bounds);self.layerView2.layer.shadowPath circlePath; CGPathRelease(circlePath); } end 如果是一个举行或是圆用CGPath会相当简单明了。但是如果是更加复杂一点的图形UIBezierPath类会更合适它是一个由UIKit提供的在CGPath基础上的Objective-C包装类。   图层蒙板 CALayer有一个属性叫做mask可以解决这个问题。这个属性本身就是个CALayer类型有和其他图层一样的绘制和布局属性。它类似于一个子图层相对于父图层即拥有该属性的图层布局但是它却不是一个普通的子图层。不同于那些绘制在父图层中的子图层mask图层定义了父图层的部分可见区域。 mask图层的Color属性是无关紧要的真正重要的是图层的轮廓。mask属性就像是一个饼干切割机mask图层实心的部分会被保留下来其他的则会被抛弃。如图4.12 interface ViewController () property (nonatomic, weak) IBOutlet UIImageView *imageView; end implementation ViewController - (void)viewDidLoad {[super viewDidLoad];//create mask layerCALayer *maskLayer [CALayer layer];maskLayer.frame self.layerView.bounds;UIImage *maskImage [UIImage imageNamed:Cone.png];maskLayer.contents (__bridge id)maskImage.CGImage;//apply mask to image layer?self.imageView.layer.mask maskLayer; } end   CALayer蒙板图层真正厉害的地方在于蒙板图不局限于静态图。任何有图层构成的都可以作为mask属性这意味着你的蒙板可以通过代码甚至是动画实时生成。   组透明 iOS常见的做法是把一个空间的alpha值设置为0.550%以使其看上去呈现为不可用状态。对于独立的视图来说还不错但是当一个控件有子视图的时候就有点奇怪了图4.20展示了一个内嵌了UILabel的自定义UIButton左边是一个不透明的按钮右边是50%透明度的相同按钮。我们可以注意到里面的标签的轮廓跟按钮的背景很不搭调。   理想状况下当你设置了一个图层的透明度你希望它包含的整个图层树像一个整体一样的透明效果。你可以通过设置Info.plist文件中的UIViewGroupOpacity为YES来达到这个效果但是这个设置会影响到这个应用整个app可能会受到不良影响。如果UIViewGroupOpacity并未设置iOS 6和以前的版本会默认为NO也许以后的版本会有一些改变。 另一个方法就是你可以设置CALayer的一个叫做shouldRasterize属性见清单4.7来实现组透明的效果如果它被设置为YES在应用透明度之前图层及其子图层都会被整合成一个整体的图片这样就没有透明度混合的问题了如图4.21。 为了启用shouldRasterize属性我们设置了图层的rasterizationScale属性。默认情况下所有图层拉伸都是1.0 所以如果你使用了shouldRasterize属性你就要确保你设置了rasterizationScale属性去匹配屏幕以防止出现Retina屏幕像素化的问题。 当shouldRasterize和UIViewGroupOpacity一起的时候性能问题就出现了我们在第12章『速度』和第15章『图层性能』将做出介绍但是性能碰撞都本地化了译者注这句话需要再翻译。 interface ViewController () property (nonatomic, weak) IBOutlet UIView *containerView; end implementation ViewController - (UIButton *)customButton {//create buttonCGRect frame CGRectMake(0, 0, 150, 50);UIButton *button [[UIButton alloc] initWithFrame:frame];button.backgroundColor [UIColor whiteColor];button.layer.cornerRadius 10;//add labelframe CGRectMake(20, 10, 110, 30);UILabel *label [[UILabel alloc] initWithFrame:frame];label.text Hello World;label.textAlignment NSTextAlignmentCenter;[button addSubview:label];return button; } - (void)viewDidLoad {[super viewDidLoad];//create opaque buttonUIButton *button1 [self customButton];button1.center CGPointMake(50, 150);[self.containerView addSubview:button1];//create translucent buttonUIButton *button2 [self customButton];?button2.center CGPointMake(250, 150);button2.alpha 0.5;[self.containerView addSubview:button2];//enable rasterization for the translucent buttonbutton2.layer.shouldRasterize YES;button2.layer.rasterizationScale [UIScreen mainScreen].scale; } end 仿射变换 当对图层应用变换矩阵图层矩形内的每一个点都被相应地做变换从而形成一个新的四边形的形状。CGAffineTransform中的“仿射”的意思是无论变换矩阵用什么值图层中平行的两条线在变换之后任然保持平行CGAffineTransform可以做出任意符合上述标注的变换图5.2显示了一些仿射的和非仿射的变换 UIView可以通过设置transform属性做变换但实际上它只是封装了内部图层的变换。 CALayer同样也有一个transform属性但它的类型是CATransform3D而不是CGAffineTransform本章后续将会详细解释。CALayer对应于UIView的transform属性叫做affineTransform清单5.1的例子就是使用affineTransform对图层做了45度顺时针旋转。 interface ViewController () property (nonatomic, weak) IBOutlet UIView *layerView; end implementation ViewController - (void)viewDidLoad {[super viewDidLoad];//rotate the layer 45 degreesCGAffineTransform transform CGAffineTransformMakeRotation(M_PI_4);self.layerView.layer.affineTransform transform; } end 注意我们使用的旋转常量是M_PI_4而不是你想象的45因为iOS的变换函数使用弧度而不是角度作为单位。弧度用数学常量pi的倍数表示一个pi代表180度所以四分之一的pi就是45度。 C的数学函数库iOS会自动引入提供了pi的一些简便的换算M_PI_4于是就是pi的四分之一如果对换算不太清楚的话可以用如下的宏做换算 #define RADIANS_TO_DEGREES(x) ((x)/M_PI*180.0)  #define DEGREES_TO_RADIANS(x) ((x)/180.0*M_PI) 混合变换 当操纵一个变换的时候初始生成一个什么都不做的变换很重要--也就是创建一个CGAffineTransform类型的空值矩阵论中称作单位矩阵Core Graphics同样也提供了一个方便的常量CGAffineTransformIdentity 最后如果需要混合两个已经存在的变换矩阵就可以使用如下方法在两个变换的基础上创建一个新的变换CGAffineTransformConcat(CGAffineTransform t1, CGAffineTransform t2); 我们来用这些函数组合一个更加复杂的变换先缩小50%再旋转30度最后向右移动200个像素清单5.2。图5.4显示了图层变换最后的结果。 - (void)viewDidLoad {[super viewDidLoad]; //create a new transformCGAffineTransform transform CGAffineTransformIdentity; //scale by 50%transform CGAffineTransformScale(transform, 0.5, 0.5); //rotate by 30 degreestransform CGAffineTransformRotate(transform, M_PI / 180.0 * 30.0); //translate by 200 pointstransform CGAffineTransformTranslate(transform, 200, 0);//apply transform to layerself.layerView.layer.affineTransform transform; } 图5.4中有些需要注意的地方图片向右边发生了平移但并没有指定距离那么远200像素另外它还有点向下发生了平移。原因在于当你按顺序做了变换上一个变换的结果将会影响之后的变换所以200像素的向右平移同样也被旋转了30度缩小了50%所以它实际上是斜向移动了100像素。 这意味着变换的顺序会影响最终的结果也就是说旋转之后的平移和平移之后的旋转结果可能不同。 3D变换 绕Y轴旋转图层 implementation ViewController - (void)viewDidLoad {[super viewDidLoad];//rotate the layer 45 degrees along the Y axisCATransform3D transform CATransform3DMakeRotation(M_PI_4, 0, 1, 0);self.layerView.layer.transform transform; } end 透视投影 CATransform3D的透视效果通过一个矩阵中一个很简单的元素来控制m34。m34图5.9用于按比例缩放X和Y的值来计算到底要离视角多远。 m34的默认值是0我们可以通过设置m34为-1.0 / d来应用透视效果d代表了想象中视角相机和屏幕之间的距离以像素为单位那应该如何计算这个距离呢实际上并不需要大概估算一个就好了。 因为视角相机实际上并不存在所以可以根据屏幕上的显示效果自由决定它的防止的位置。通常500-1000就已经很好了但对于特定的图层有时候更小后者更大的值会看起来更舒服减少距离的值会增强透视效果所以一个非常微小的值会让它看起来更加失真然而一个非常大的值会让它基本失去透视效果对视图应用透视的代码见清单5.5结果见图5.10。 implementation ViewController - (void)viewDidLoad {[super viewDidLoad];//create a new transformCATransform3D transform CATransform3DIdentity;//apply perspectivetransform.m34 - 1.0 / 500.0;//rotate by 45 degrees along the Y axistransform CATransform3DRotate(transform, M_PI_4, 0, 1, 0);//apply to layerself.layerView.layer.transform transform; } end消亡点 Core Animation定义了这个点位于变换图层的anchorPoint通常位于图层中心但也有例外见第三章。这就是说当图层发生变换时这个点永远位于图层变换之前anchorPoint的位置。 当改变一个图层的position你也改变了它的消亡点做3D变换的时候要时刻记住这一点当你视图通过调整m34来让它更加有3D效果应该首先把它放置于屏幕中央然后通过平移来把它移动到指定位置而不是直接改变它的position这样所有的3D图层都共享一个消亡点。 sublayerTransform属性 如果有多个视图或者图层每个都做3D变换那就需要分别设置相同的m34值并且确保在变换之前都在屏幕中央共享同一个position如果用一个函数封装这些操作的确会更加方便但仍然有限制例如你不能在Interface Builder中摆放视图这里有一个更好的方法。 CALayer有一个属性叫做sublayerTransform。它也是CATransform3D类型但和对一个图层的变换不同它影响到所有的子图层。这意味着你可以一次性对包含这些图层的容器做变换于是所有的子图层都自动继承了这个变换方法。 相较而言通过在一个地方设置透视变换会很方便同时它会带来另一个显著的优势消亡点被设置在容器图层的中点从而不需要再对子图层分别设置了。这意味着你可以随意使用position和frame来放置子图层而不需要把它们放置在屏幕中点然后为了保证统一的消亡点用变换来做平移。 我们来用一个demo举例说明。这里用Interface Builder并排放置两个视图图5.12然后通过设置它们容器视图的透视变换我们可以保证它们有相同的透视和消亡点代码见清单5.6结果见图5.13。 interface ViewController () property (nonatomic, weak) IBOutlet UIView *containerView; property (nonatomic, weak) IBOutlet UIView *layerView1; property (nonatomic, weak) IBOutlet UIView *layerView2; end implementation ViewController - (void)viewDidLoad {[super viewDidLoad];//apply perspective transform to containerCATransform3D perspective CATransform3DIdentity;perspective.m34 - 1.0 / 500.0;self.containerView.layer.sublayerTransform perspective;//rotate layerView1 by 45 degrees along the Y axisCATransform3D transform1 CATransform3DMakeRotation(M_PI_4, 0, 1, 0);self.layerView1.layer.transform transform1;//rotate layerView2 by 45 degrees along the Y axisCATransform3D transform2 CATransform3DMakeRotation(-M_PI_4, 0, 1, 0);self.layerView2.layer.transform transform2; } 背面相当于水平翻转但其实是。。。 但这并不是一个很好的特性因为如果图层包含文本或者其他控件那用户看到这些内容的镜像图片当然会感到困惑。另外也有可能造成资源的浪费想象用这些图层形成一个不透明的固态立方体既然永远都看不见这些图层的背面那为什么浪费GPU来绘制它们呢 CALayer有一个叫做doubleSided的属性来控制图层的背面是否要被绘制。这是一个BOOL类型默认为YES如果设置为NO那么当图层正面从相机视角消失的时候它将不会被绘制。 固体对象 我们把一个有颜色的UILabel放置在视图内部是为了清楚的辨别它们之间的关系并且UIButton被放置在第三个面视图里面后面会做简单的解释。 interface ViewController () property (nonatomic, weak) IBOutlet UIView *containerView; property (nonatomic, strong) IBOutletCollection(UIView) NSArray *faces; end implementation ViewController - (void)addFace:(NSInteger)index withTransform:(CATransform3D)transform {//get the face view and add it to the containerUIView *face self.faces[index];[self.containerView addSubview:face];//center the face view within the containerCGSize containerSize self.containerView.bounds.size;face.center CGPointMake(containerSize.width / 2.0, containerSize.height / 2.0);// apply the transformface.layer.transform transform; } - (void)viewDidLoad {[super viewDidLoad];//set up the container sublayer transformCATransform3D perspective CATransform3DIdentity;perspective.m34 -1.0 / 500.0;self.containerView.layer.sublayerTransform perspective;//add cube face 1CATransform3D transform CATransform3DMakeTranslation(0, 0, 100);[self addFace:0 withTransform:transform];//add cube face 2transform CATransform3DMakeTranslation(100, 0, 0);transform CATransform3DRotate(transform, M_PI_2, 0, 1, 0);[self addFace:1 withTransform:transform];//add cube face 3transform CATransform3DMakeTranslation(0, -100, 0);transform CATransform3DRotate(transform, M_PI_2, 1, 0, 0);[self addFace:2 withTransform:transform];//add cube face 4transform CATransform3DMakeTranslation(0, 100, 0);transform CATransform3DRotate(transform, -M_PI_2, 1, 0, 0);[self addFace:3 withTransform:transform];//add cube face 5transform CATransform3DMakeTranslation(-100, 0, 0);transform CATransform3DRotate(transform, -M_PI_2, 0, 1, 0);[self addFace:4 withTransform:transform];//add cube face 6transform CATransform3DMakeTranslation(0, 0, -100);transform CATransform3DRotate(transform, M_PI, 0, 1, 0);[self addFace:5 withTransform:transform]; } end 从这个角度看立方体并不是很明显看起来只是一个方块为了更好地欣赏它我们将更换一个不同的视角。 旋转这个立方体将会显得很笨重因为我们要单独对每个面做旋转。另一个简单的方案是通过调整容器视图的sublayerTransform去旋转照相机。 添加如下几行去旋转containerView图层的perspective变换矩阵 perspective  CATransform3DRotate(perspective, -M_PI_4, 1, 0, 0);  perspective  CATransform3DRotate(perspective, -M_PI_4, 0, 1, 0); 这就对相机或者相对相机的整个场景你也可以这么认为绕Y轴旋转45度并且绕X轴旋转45度。现在从另一个角度去观察立方体就能看出它的真实面貌图5.21。 光亮和阴影 如果需要动态地创建光线效果你可以根据每个视图的方向应用不同的alpha值做出半透明的阴影图层但为了计算阴影图层的不透明度你需要得到每个面的正太向量垂直于表面的向量然后根据一个想象的光源计算出两个向量叉乘结果。叉乘代表了光源和图层之间的角度从而决定了它有多大程度上的光亮。 清单5.10实现了这样一个结果我们用GLKit框架来做向量的计算你需要引入GLKit库来运行代码每个面的CATransform3D都被转换成GLKMatrix4然后通过GLKMatrix4GetMatrix3函数得出一个3×3的旋转矩阵。这个旋转矩阵指定了图层的方向然后可以用它来得到正太向量的值。 结果如图5.22所示试着调整LIGHT_DIRECTION和AMBIENT_LIGHT的值来切换光线效果 #import ViewController.h #import #import #define LIGHT_DIRECTION 0, 1, -0.5 #define AMBIENT_LIGHT 0.5 interface ViewController () property (nonatomic, weak) IBOutlet UIView *containerView; property (nonatomic, strong) IBOutletCollection(UIView) NSArray *faces; end implementation ViewController - (void)applyLightingToFace:(CALayer *)face {//add lighting layerCALayer *layer [CALayer layer];layer.frame face.bounds;[face addSublayer:layer];//convert the face transform to matrix//(GLKMatrix4 has the same structure as CATransform3D)CATransform3D transform face.transform;GLKMatrix4 matrix4 *(GLKMatrix4 *)transform;GLKMatrix3 matrix3 GLKMatrix4GetMatrix3(matrix4);//get face normalGLKVector3 normal GLKVector3Make(0, 0, 1);normal GLKMatrix3MultiplyVector3(matrix3, normal);normal GLKVector3Normalize(normal);//get dot product with light directionGLKVector3 light GLKVector3Normalize(GLKVector3Make(LIGHT_DIRECTION));float dotProduct GLKVector3DotProduct(light, normal);//set lighting layer opacityCGFloat shadow 1 dotProduct - AMBIENT_LIGHT;UIColor *color [UIColor colorWithWhite:0 alpha:shadow];layer.backgroundColor color.CGColor; } - (void)addFace:(NSInteger)index withTransform:(CATransform3D)transform {//get the face view and add it to the containerUIView *face self.faces[index];[self.containerView addSubview:face];//center the face view within the containerCGSize containerSize self.containerView.bounds.size;face.center CGPointMake(containerSize.width / 2.0, containerSize.height / 2.0);// apply the transformface.layer.transform transform;//apply lighting[self applyLightingToFace:face.layer]; } - (void)viewDidLoad {[super viewDidLoad];//set up the container sublayer transformCATransform3D perspective CATransform3DIdentity;perspective.m34 -1.0 / 500.0;perspective CATransform3DRotate(perspective, -M_PI_4, 1, 0, 0);perspective CATransform3DRotate(perspective, -M_PI_4, 0, 1, 0);self.containerView.layer.sublayerTransform perspective;//add cube face 1CATransform3D transform CATransform3DMakeTranslation(0, 0, 100);[self addFace:0 withTransform:transform];//add cube face 2transform CATransform3DMakeTranslation(100, 0, 0);transform CATransform3DRotate(transform, M_PI_2, 0, 1, 0);[self addFace:1 withTransform:transform];//add cube face 3transform CATransform3DMakeTranslation(0, -100, 0);transform CATransform3DRotate(transform, M_PI_2, 1, 0, 0);[self addFace:2 withTransform:transform];//add cube face 4transform CATransform3DMakeTranslation(0, 100, 0);transform CATransform3DRotate(transform, -M_PI_2, 1, 0, 0);[self addFace:3 withTransform:transform];//add cube face 5transform CATransform3DMakeTranslation(-100, 0, 0);transform CATransform3DRotate(transform, -M_PI_2, 0, 1, 0);[self addFace:4 withTransform:transform];//add cube face 6transform CATransform3DMakeTranslation(0, 0, -100);transform CATransform3DRotate(transform, M_PI, 0, 1, 0);[self addFace:5 withTransform:transform]; } end 点击事件 你应该能注意到现在可以在第三个表面的顶部看见按钮了点击它什么都没发生为什么呢 这并不是因为iOS在3D场景下正确地处理响应事件实际上是可以做到的。问题在于视图顺序。在第三章中我们简要提到过点击事件的处理由视图在父视图中的顺序决定的并不是3D空间中的Z轴顺序。当给立方体添加视图的时候我们实际上是按照一个顺序添加所以按照视图/图层顺序来说456在3的前面。 即使我们看不见456的表面因为被123遮住了iOS在事件响应上仍然保持之前的顺序。当试图点击表面3上的按钮表面456截断了点击事件取决于点击的位置这就和普通的2D布局在按钮上覆盖物体一样。 你也许认为把doubleSided设置成NO可以解决这个问题因为它不再渲染视图后面的内容但实际上并不起作用。因为背对相机而隐藏的视图仍然会响应点击事件这和通过设置hidden属性或者设置alpha为0而隐藏的视图不同那两种方式将不会响应事件。所以即使禁止了双面渲染仍然不能解决这个问题虽然由于性能问题还是需要把它设置成NO。 这里有几种正确的方案把除了表面3的其他视图userInteractionEnabled属性都设置成NO来禁止事件传递。或者简单通过代码把视图3覆盖在视图6上。无论怎样都可以点击按钮了图5.23。 转载于:https://www.cnblogs.com/lihaiyin/p/4450663.html
http://www.sadfv.cn/news/47740/

相关文章:

  • 洛阳做网站那家好网站的首页需要什么内容
  • 中国工商银行官网网站创新logo标志设计
  • 个人网站设计的参考文献高端上海网站设计公司价格
  • 做淘宝网站需要多少钱ICP备案网站服务内容
  • 无锡网站建设 app昆山市建设工程交易中心网站
  • 怎样设计自己网站域名安徽省高等级公路工程建设指挥部网站
  • 乐山网站公众号建设科技特长生包括哪些项目
  • 广州市住房建设局网站wordpress安卓显示
  • 西工网站建设设计怎么做网站的主页面
  • 快速搭建网站信息库国外专门做杂志的共享网站
  • 网站猜你喜欢代码网络营销是什么研究
  • 网页的创新型网站策划个人网站认证
  • 中英 网站模板 带手机版org的域名网站
  • 企业网站策划案模板做网站的案例
  • 马云做黄页网站时候wordpress百度云盘插件
  • 沈阳市建设局网站宣传的网站开发需要多少钱
  • 上海千途建站网站关键词数量减少
  • 南昌网站建设推广注册公司的条件
  • 网站设计策划书 模板深圳公司官网
  • 酒店怎样做网站好评开发者 电影
  • 成都微网站开发凡科网做网站视频
  • 网站开发的售后 维保成都 网站建设培训班
  • 广州专业的网站建设公司哪家好西昌手机网站制作
  • 整形网站源码建程网会员共享
  • 网站建设费 什么科目wordpress实现301跳转详解
  • logo网站设计图片做网站虚拟主机和云服务器吗
  • 只能在线观看的电影网站咋么做wordpress 添加淘宝
  • 广告网站设计公司旅游网站排行榜前20
  • 建筑工程的公司网站优化怎样提高网站用户体验
  • namecheap建站wordpress优化型网站模板