当即调用layoutSubviews进行布局(若无标识,上面做

2019-09-13 11:20栏目:大奖888官网登录
TAG:

二.主要方法1.setNeedsDisplay or setNeedsDisplayInRect: 触发drawRect方法2.convertPoint:fromView: convertPoint:toView3.setNeedsLayout or layoutIfNeeded

  • sizeToFit会自动调用sizeThatFits方法;
  • sizeToFit不应该在子类中被重写,应该重写sizeThatFits
  • sizeThatFits传入的参数是receiver当前的size,返回一个适合的size
  • sizeToFit可以被手动直接调用
  • sizeToFit和sizeThatFits方法都没有递归,对subviews也不负责,只负责自己。

3、UIView的contentMode属性

这个属性的值决定了,当视图的几何形状变化时如何复用它的内容。当视图第一次展示前,它会将自己的内容渲染成一张底层的bitmap. 然后视图的几何变化都不会使bitmap重新生成。而视图contentMode属性的值决定了bitmap是否缩放、位置在哪儿(固定在左边、右边、上面、下面、居中)。默认情况下,contentMode的值是UIViewContentModeScaleToFill。

UIViewContentModeScaleToFill       //改变内容的高宽比例,缩放内容,UIView中完整显示内容,填满UIView

UIViewContentModeScaleAspectFit     //保持内容的高宽比,缩放内容,完整显示内容,最大化填充UIview,没填充上的区域透明

UIViewContentModeScaleAspectFill      //保持内容高宽比,缩放内容,超出视图的部分内容会被裁减,填充UIView

UIViewContentModeRedraw     //当View的bounds改变,系统会调用setNeedsDisplay,重新绘制视图

UIViewContentModeCenter                //不缩放,内容在视图中间

UIViewContentModeTop                  //内容在视图顶部

www.88pt88.com,UIViewContentModeBottom           //内容在视图底部

UIViewContentModeLeft                //内容在视图左边

UIViewContentModeRight           //内容在视图右边 

UIViewContentModeTopLeft           // the top-left corner of the view.

UIViewContentModeTopRight            // the top-right corner of the view.

UIViewContentModeBottomLeft       //the bottom-left corner of the view.

UIViewContentModeBottomRight           // the bottom-right corner of the view.

一.主要参数1.contentMode:定义UIView的填充模式,如:UIViewContentModeLeft、UIViewContentModeScaleAspectFill、特别介绍下UIViewContentRedraw,这个是只要触发变化(bounds或者transform变化)则就会强制调用drawRect要求重绘,这个参数要少用。2.contentStretch:在contentMode设置为可拉伸情况下,则该参数决定拉伸的范围,用单位值表示。3.clipToBounds:是否显示超出当前view范围的子view.4.transform:变形。CGAffineTransform.注意的是transform变形只针对屏幕已经渲染的view以及其subviews,对于没渲染的是不起作用的,因为每个view只针对自己的bounds进行布局和提供内容。此外如果transform是已经变形过的,则不能用该view的frame来获得位置以及大小,要使用bounds和center。因为变形后,view的frame就为nil.5.contentScaleFactor:用于自己high-resolution屏幕的比例,数值大,表示内容在屏幕上的一点所占的像素越大。6.tag:从view's tree-list里获得view,一个方法是用subviews来搜索,还有一个就是用viewWithTag来寻找某个指定的view

layoutIfNeeded
如果,有需要刷新的标记,立即调用layoutSubviews进行布局(如果没有标记,不会调用layoutSubviews)
setNeedsLayout
标记为需要重新布局,异步调用layoutIfNeeded刷新布局,不立即刷新,但layoutSubviews一定会被调用

在iOS开发中UIView有一些不常用的属性及方法。下面做一些简单介绍:

参考文档:View Programming Guide for iOS

  1. 如果在UIView初始化时没有设置rect大小,将直接导致drawRect不被自动调用。drawRect调用是在Controller->loadView, Controller->viewDidLoad 两方法之后调用的。所以不用担心在控制器中,这些View的drawRect就开始画了。这样可以在控制器中设置一些值给View(如果这些View draw的时候需要用到某些变量值)。
  2. 该方法在调用sizeToFit后被调用。所以可以先调用sizeToFit计算出size,然后系统自动调用drawRect:方法。
  3. 通过设置contentMode属性值为UIViewContentModeRedraw。那么将在每次设置或更改frame的时候自动调用drawRect:。
  4. 直接调用setNeedsDisplay,或者setNeedsDisplayInRect:触发drawRect:,但是有个前提条件是rect不能为0。以上1,2推荐;而3,4不提倡

8、sizeToFit方法

sizeToFit会自动调用sizeThatFits方法;

sizeToFit不应该在子类中被重写,应该重写sizeThatFits

sizeThatFits传入的参数是receiver当前的size,返回一个适合的size

sizeToFit可以被手动直接调用sizeToFit和sizeThatFits方法都没有递归,对subviews也不负责,只负责自己

五.动画(animation&transition)和CALayer区别,在transform上,一个是CATransform3D,另外一个是CAAffineTransform1.+animateWithDuration2.+beginAnimations:context3.+transitionWithView4.在animation transaction里,调用+setAnimationTransition:forView:cache 方法虽然在block里可以混合使用CAAnimation和UIView animation,但是Apple建议当2者都存在时,尽量只选择使用CAAnimation来制作动画。

Tips:

2、UIView 的transform属性

UIView的transform属性,通过设置该属性,我们可以实现调整该view在其superView中的大小和位置,具体来说,Transform(变化矩阵)是一种3×3的矩阵,通过这个矩阵我们可以对一个坐标系统进行缩放,平移,旋转以及这两者的任意组着操作。而且矩阵的操作不具备交换律,即矩阵的操作的顺序不同会导致不同的结果。

获得CGAffineTransform有多种方法,例如使用CGAffineTransformMake,但是对于矩阵操作相对比较麻烦,但是事实上iOS已经为我们提供好了三个对应的方法,分别用于在原来的角度、缩放、移动位置的基础上做出修改:CGAffineTransformRotate、CGAffineTransformScale、CGAffineTransformTranslate

view.transform=CGAffineTransformScale(view.transform, 0.5, 0.5);//  实现的是放大和缩小

view.transform=CGAffineTransformRotate(view.transform, M_PI); //实现的是旋转

view.transform=CGAffineTransformTranslate(view.transform,20, 20);//实现的是平移

创建一个CGAffineTransform transform对象

CGAffineTransform transform;

transform = CGAffineTransformRotate(manImageView.transform,M_PI/6.0);//设置旋转度数

[UIView beginAnimations:@"rotate" context:nil ];//动画开始

[UIView setAnimationDuration:2];//动画时常

[UIView setAnimationDelegate:self];//添加代理

[manImageView setTransform:transform];//获取transform的值

[UIView commitAnimations];//关闭动画

四.自定义UIView大致有以下几个步骤1.initWithFrame、initWithCoder2.dealloc3.drawRect4.autoresizingMask5.构建subviews,并且设置合适的autoresizingMask,如果必要,覆盖layoutSubviews6.构建touch事件和手势识别7.如果需要打印,则drawRect:forViewPrintFormatter:此外还要根据实际情况设置contentMode,contentStretch,还有CALayer的一些设置(layerClass方法取指定默认的CALayer类型)

layoutSubviews
这个方法,默认没有做任何事情,需要子类进行重写。系统在很多时候会去调用这个方法:

4、layoutSubviews方法

这个方法,默认没有做任何事情,需要子类进行重写 。 系统在很多时候会去调用这个方法:

1、初始化不会触发layoutSubviews,但是如果设置了不为CGRectZero的frame的时候就会触发。

2、addSubview会触发layoutSubviews

3、设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化

4、滚动一个UIScrollView会触发layoutSubviews

5、旋转Screen会触发父UIView上的layoutSubviews事件

6、改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件

在苹果的官方文档中强调: You should override this method only if the autoresizing behaviors of the subviews do not offer the behavior you want.layoutSubviews, 当我们在某个类的内部调整子视图位置时,需要调用。反过来的意思就是说:如果你想要在外部设置subviews的位置,就不要重写。

=

三.屏幕布局1.触发重新布局的几个事件a)view的bounds发生变化b)设备方向发生变化c)显示调用view的setNeedsLayout或者layoutIfNeeded,或者某个view的layer的setNeedsLayout方法d)某个view的layer的sublayers发生变化并需要布局2.自动布局a)autoresizesSubviews设置为YESb)autoresizingMask设置UIViewAutoresizing合适的数值来决定布局c)即使自动布局完成,也会给你机会手动调整,调用view的layoutSubviews方法3.手动布局实现方法layoutSubviews方法,你所做的可能是以下类似的工作调整subviews的尺寸位置、添加删除subviews或者对应的layers每个subviews调用setNeedsDisplay或者setNeedsDisplayInRect来重新绘制view的内容苹果文档中给出了一个布局的例子:假设一个scrollview有很多view(tile views),当滚动发生时,调用root view的setNeedsLayout方法,在layoutSubviews里则将下一张图片显示在合适的位置,当scroll发生到当前图片要超过显示区域的时候,则再调用layoutSubviews把超过屏幕的view给移掉,或者将其放在下一张图片的位置上。

  1. 若使用UIView绘图,只能在drawRect:方法中获取相应的contextRef并绘图。如果在其他方法中获取将获取到一个invalidate的ref并且不能用于画图。drawRect:方法不能手动显示调用,必须通过调用setNeedsDisplay 或者 setNeedsDisplayInRect,让系统自动调该方法。
  2. 若使用CALayer绘图,只能在drawInContext: 中(类似于drawRect)绘制,或者在delegate中的相应方法绘制。同样也是调用setNeedDisplay等间接调用以上方法3。若要实时画图,不能使用gestureRecognizer,只能使用touchBegan等方法来调用setNeedsDisplay实时刷新屏幕

1、autoresizingMask

setAutoresizingMask控件的自适应

typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {

UIViewAutoresizingNone                = 0,

UIViewAutoresizingFlexibleLeftMargin  = 1 << 0,

UIViewAutoresizingFlexibleWidth        = 1 << 1,

UIViewAutoresizingFlexibleRightMargin  = 1 << 2,

UIViewAutoresizingFlexibleTopMargin    = 1 << 3,

UIViewAutoresizingFlexibleHeight      = 1 << 4,

UIViewAutoresizingFlexibleBottomMargin = 1 << 5

};

1、UIViewAutoresizingNone  这个属性是指,控件相对于父视图坐标没有任何改变(不管父视图的长宽改变为多少,子控件的坐标是定值)

2、UiViewAutoresizingFlexibleleftMargin         控件相对于父视图,随着父视图的宽度比例变化,横坐标跟着变化,比如说上面的lable frame = CGRectmake(50,100,200,40);   如果之前父视图的长宽是320*480  现在变成了480*320  那么在父视图改变之后,如果只限制这一个属性,那么变化后的lable横坐标就变为: 50*(480/320) lable的坐标就是:(50*(480/320),100,200,40);

3、UIViewAutoresizingFlexibleRightmargin 、 UIViewAutoresizingFlexibleTopmargin 、 UIViewAutoresizingFlexibleBottommargin  三个属性和2)类似;

4、UIViewAutoResizingFlexibleWidth  和2类似,只不过是lable的宽度按照比例发生改变

=

如果要立即刷新,要先调用[view setNeedsLayout],把标记设为需要布局,然后马上调用[view layoutIfNeeded],实现布局在视图第一次显示之前,标记总是“需要刷新”的。**可以直接调用[view layoutIfNeeded]*

6、layoutIfNeeded方法

如果,有需要刷新的标记,立即调用layoutSubviews进行布局

iOS layout的相关方法:

5、setNeedsLayout方法

标记为需要重新布局,不立即刷新,但layoutSubviews一定会被调用

配合layoutIfNeeded立即更新

=

  • layoutSubviews
  • layoutIfNeeded
  • setNeedsLayout
  • setNeedsDisplay
  • drawRect
  • sizeThatFits
  • sizeToFit

7、drawRect方法

这个方法是用来重绘的。

drawRect在以下情况下会被调用:

1、如果在UIView初始化时没有设置rect大小,将直接导致drawRect不被自动调用。drawRect调用是在Controller->loadView, Controller->viewDidLoad 两方法之后掉用的.所以不用担心在控制器中,这些View的drawRect就开始画了.这样可以在控制器中设置一些值给View(如果这些View draw的时候需要用到某些变量值).

2、该方法在调用sizeToFit后被调用,所以可以先调用sizeToFit计算出size。然后系统自动调用drawRect:方法。

3、通过设置contentMode属性值为UIViewContentModeRedraw。那么将在每次设置或更改frame的时候自动调用drawRect:。

4、直接调用setNeedsDisplay,或者setNeedsDisplayInRect:触发drawRect:,但是有个前提条件是rect不能为0。以上1,2推荐;而3,4不提倡

drawRect方法使用注意点:

1、若使用UIView绘图,只能在drawRect:方法中获取相应的contextRef并绘图。如果在其他方法中获取将获取到一个invalidate的ref并且不能用于画图。drawRect:方法不能手动显示调用,必须通过调用setNeedsDisplay 或者 setNeedsDisplayInRect,让系统自动调该方法。

2、若使用calayer绘图,只能在drawInContext: 中(类似于drawRect)绘制,或者在delegate中的相应方法绘制。同样也是调用setNeedDisplay等间接调用以上方法3、若要实时画图,不能使用gestureRecognizer,只能使用touchbegan等方法来掉用setNeedsDisplay实时刷新屏幕

=

  1. 初始化不会触发layoutSubviews,但是如果设置了不为CGRectZero的frame的时候就会触发

  2. addSubview会触发layoutSubviews

  3. 设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化

  4. 滚动一个UIScrollView会触发layoutSubviews

  5. 旋转Screen会触发父UIView上的layoutSubviews事件

  6. 改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件

     在苹果的官方文档中强调:   
     You should override this method only if the autoresizing behaviors of the subviews do not offer the behavior you want.    
     layoutSubviews, 当我们在某个类的内部调整子视图位置时,需要调用;如果你想要在外部设置subviews的位置,就不要重写。
    
  • layoutSubviews对subviews重新布局
  • layoutSubviews方法调用先于drawRect
  • setNeedsLayout在receiver标上一个需要被重新布局的标记,在系统runloop的下一个周期自动调用layoutSubviews
  • layoutIfNeeded方法如其名,UIKit会判断该receiver是否需要layout,根据Apple官方文档,layoutIfNeeded方法应该是这样的
  • layoutIfNeeded遍历的不是superview链,应该是subviews链
    drawRect是对receiver的重绘,能获得context
  • setNeedDisplay在receiver标上一个需要被重新绘图的标记,在下一个draw周期自动重绘,iPhone device的刷新频率是60HZ,也就是1/60秒后重绘

drawRect
这个方法是用来重绘的。
drawRect在以下情况下会被调用:


sizeToFit

drawRect方法使用注意点:

版权声明:本文由大奖888-www.88pt88.com-大奖888官网登录发布于大奖888官网登录,转载请注明出处:当即调用layoutSubviews进行布局(若无标识,上面做