【UI控件总结】【UIScrollView】深入理解篇UIScrollerView

【UI控件总结】【UIScrollView】基本方法+基本描述

接下来,我整理一下自己的思路,深入理解 UIScrollView

基本点 :

1 . UIScrollView 是一个UIView。

每个UIView都有一个bounds和frame。当布局一个界面时,我们需要处理视图的frame。这允许我们放置并设置视图的大小。 视图的frame和bounds的大小总是一样的,但是他们的origin有可能不同(bounds的原点是(0,0)点(就是view本身的坐标系统,默认永远都是0,0点,除非调用了setbounds函数),而frame的原点却是任意的(相对于父视图中的坐标位置)。)    弄懂这两个工作原理是理解UIScrollView的关键。

2 . UIView的 bounds和frame 工作原理

这里有个概念  光栅化 和 组合 ,   本人的简单理解:

光栅化 :  简单的说就是产生一组绘图指令并且生成一张图片(注意,这些图片并没有被绘制到屏幕上去;它们被自己的视图保持着留到下一个步骤用)

组合 :  光栅化之后,屏幕其实是空的,你什么都看不见,但是其实视图已经出现的了,这个时候这些图片便被一个接一个的绘制,并产生一个屏幕大小的图片,这便是组合, 这个时候,屏幕上就能看到你描绘的东西。再扯一点,视图层级(view hierarchy)对于组合如何进行扮演了很重要的角色:一个视图的图片被组合在它父视图图片的上面。然后,组合好的图片被组合到父视图的父视图图片上 面,就这样。。。最终视图层级最顶端是窗口(window),它组合好的图片便是我们看到的东西了。

小结 : 知道上面两种绘制图像的形式和过程之后 bounds的为什么一般是(0,0) , Frame却是以父控件为坐标原点,相信都有点理解了。

在光栅化步骤中,视图并不关心即将发生的组合步骤,这时视图只关心一件事就是绘制它自己的content。这个绘制发生在每个视图的drawRect:方法中 在drawRect:方法被调用前,会为视图创建一个空白的图片来绘制content。这个图片的坐标系统是视图的bounds。几乎每个视图 bounds的origin都是{0,0}(除非你重写setbounds方法,改动)。因此,当在删格化图片左上角绘制一些东西的时候,你都会在bounds的origin({x:0,y:0}) 处绘制。在一个图片右下角的地方绘制东西的时候,你都会绘制在{x:width, y:height}处。如果你的绘制超出了视图的bounds,那么超出的部分就不属于删格化图片的部分了,并且会被丢弃。

在组合的步骤中,每个视图将自己光栅化图片组合到自己父视图的光栅化图片上面。视图的frame决定了自己在父视图中绘制的位置,frame的 origin表明了视图光栅化图片左上角相对父视图光栅化图片左上角的偏移量。所以,一个origin为{x:20,y:15}的frame所绘制的图片 左边距其父视图20点,上边距父视图15点。因为视图的frame和bounds矩形的大小总是一样的,所以光栅化图片组合的时候是像素对齐的。这确保了 光栅化图片不会被拉伸或缩小。

小结 : bound 和 frame 大小一样,位置不同的深沉原因。

组合的时候,视图图片的左上角会根据它frame的origin进行偏移,并绘制到父视图的图片上:

// 组合点的X值 = 当前视图的frameX值 - 父视图的光栅化X值CompositedPosition.x = View.frame.origin.x - Superview.bounds.origin.x(一般来说总是0);
// 组合点的Y值 = 当前视图的frameY值 - 父视图的光栅化Y值
CompositedPosition.y = View.frame.origin.y - Superview.bounds.origin.y(一般来说总是0);

3 . UIScrollView的 Content Offset 工作原理

正因为IOS这种组合原理, UIScrollView的工作原理就这样带出来了。

组合点的位置 (CompositedPosition.x , CompositedPosition.y) 就是子视图组合在父视图的位置

(题外话 :其实所有UIView都是这样,光栅化,组合的原理都是一样。 )

根据上面的公式,

改变 View.frame.origin.x 的值 和  Superview.bounds.origin.y的值,  都可以改变组合点值.

说个例子方便理解吧,

UIView *view = [[UIView alloc] init];
view.frame = CGRectMake(10,10,100,100);
view.background = [UIColor redcolor];
[self.view addSubviews:view];

UIButton *btn = [[UIButton alloc] init]
btn.frame = (10, 10,10,10);
[view addSubviews:btn];

UIButton *btn2 = [[UIButton alloc] init]
btn.frame = (20, 20,10,10);
[view addSubviews:btn2];

UIButton *btn3 = [[UIButton alloc] init]
btn.frame = (30, 30,10,10);
[view addSubviews:btn3];

/*  简单的步骤
 步骤一 光栅化 :首先,view会创建一块 100 * 100 的空白区域,的图像指令, btn,btn2,btn3会创建一块 10 * 10 的空白区域
( 此时 ,屏幕啥都没看见,)

步骤二 组合, view会找到父view,以父view的原点(记得那条公式吗?也就是Superview.bounds.origin ,用自己的 (10 ,10) 减去 父VIew的 (0 , 0)),然后描绘在父view身上。同理 button 也是这样。

试想一下。btn现在是嵌套在哪里? 嵌套在view的 (10,10)(20,20)(30,30)这里,
因为他是用 btn.frame.origin.x, - view.bound.origin.x
假设,现在改变view.bound.origin , 将view的bound点,转移到 (-10,-10),刷新draw:rect方法重新组合的时候,是不是相当于,3个btn的组合点都在view的 {0,0}上了,是不是就相当于整一块向左上角平移了? UIScrollView的原理就是这样!!!

*/

UIScrollView 的工作原理,就是改变scroll view.bounds的origin。(其实很自然就会想到,为什么不是改变View.frame.origin.x,,,苹果喜欢呗...道理容后解释)

当你设置它的contentOffset属性时:它改变scroll view.bounds的origin。事实上,contentOffset甚至不是实际存在的。代码看起来像这样:

时间: 2024-10-20 21:51:45

【UI控件总结】【UIScrollView】深入理解篇UIScrollerView的相关文章

UI控件(UIScrollView)

@implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //创建一个scrollview UIScrollView *_scrollview = [[UIScrollView alloc]init]; _scrollview.frame = CGRectMake(10,20,200,300); _scrollview.backgroundColor = [UIColor grayColor]; [self

UI控件之UIScrollView

1.contentSize 默认CGSizeZero,用来设置scrollView的滚动范围 // 设置scrollView的滚动范围 self.mainScrollView.contentSize = CGSizeMake(7*KScreenWith, KScreenHeight); 2.contentOffset 默认CGSizeZero,用来设置scrollView的滚动偏移量 // self.rootView.mainScrollView.contentOffset.x 水平方向的偏移量

《深入理解Windows Phone 8.1 UI控件编程》

<深入理解Windows Phone 8.1 UI控件编程>本书基于最新的Windows Phone 8.1 Runtime SDK编写,全面深入地论述了最酷的UI编程技术:实现复杂炫酷的动画.掌握布局原理.列表虚拟化原理.高性能列表实现.图表编程.控件原理等. 目录如下: <深入理解Windows Phone 8 .1 UI控件编程>目录 第1章 深入解析程序界面 1.1 XAML的原理 1.1.1 XAML的概念 1.1.2 XAML页面的编译 1.1.3 动态加载XAML 1

Cocos2d-x3.0游戏实例之《别救我》第六篇——从代码中获取UI控件

这篇的内容很简单,获取UI控件,然后使用它. 还记得我们在UI编辑器中给三个按钮分别命名了吧? 现在要用上了. 笨木头花心贡献,啥?花心?不呢,是用心~ 转载请注明,原文地址: http://www.benmutou.com/blog/archives/918 文章来源:笨木头与游戏开发 根据名字查找控件 首先给TollgateScene再include一些头文件,不然等会编译又报错了: #include "editor-support/cocostudio/CCSGUIReader.h&quo

《深入理解Windows Phone 8.1 UI控件编程》基于最新的Runtime框架

<深入理解Windows Phone 8.1 UI控件编程>本书基于最新的Windows Phone 8.1 Runtime SDK编写,全面深入地论述了最酷的UI编程技术:实现复杂炫酷的动画.掌握布局原理.列表虚拟化原理.高性能列表实现.图表编程.控件原理等.  全书源代码免费下载: http://vdisk.weibo.com/s/zt_pyrfNHoezI 试读章节会在博客园持续更新: [WP8.1UI控件编程]Windows Phone XAML页面的编译 [WP8.1UI控件编程]W

IOS开发UI篇--常用UI控件的基本使用

一. UIButton概述: UIKit框架提供了非常多的UI控件,其中有些控件天天使用,比如UIButton.UILabel.UIImageView.UITableView等. UIButton,俗称“按钮”,通常点击某个控件后,会做出相应反应的都是按钮.按钮的功能较多,既能显示图片又能显示汉字还能随时调整图片的文字和位置,如下面两个图 团购和音乐播放器的app: 下面本文通过一个实例总结一下它们的基本使用. 二. 按钮的基本设置 按钮既可以通过mainstoryboard创建也可以通过代码创

初级篇第四期:纯代码来写UI控件

学习建议:自己动手,丰衣足食 学习周期:1周 学习目的:熟练使用Obejct-C中最常用的简单UI控件 学习答疑:欢迎来技术群里提问并做分享 学习工具:Xcode开发环境 学习内容:我们会在下面告诉大家手动创建常见的UI控件 经过前几期的学习,相信小伙伴们应该对UI控件有所熟悉了哦,没错,那我们接下来就用纯代码来写一些常用的UI控件好了 首先,任何一个UI控件都是有它固定的属性的,第一就是frame,一定要记住,没有frame就没有它的存在,所以一个UI控件的灵魂就在于它的frame,因为它是显

理解SynchronizationContext,如何在Winform里面跨线程访问UI控件

SynchronizationContext 类是一个基类,可提供不带同步的自由线程上下文. 此类实现的同步模型的目的是使公共语言运行库内部的异步/同步操作能够针对不同的异步模型采取正确的行为.此模型还简化了托管应用程序为在不同的同步环境下正常工作而必须遵循的一些要求.同步模型的提供程序可以扩展此类并为这些方法提供自己的实现.(来自MSDN)简而言之就是允许一个线程和另外一个线程进行通讯,SynchronizationContext在通讯中充当传输者的角色.另外这里有个地方需要清楚的,不是每个线

Silverlight项目笔记1:UI控件与布局、MVVM、数据绑定、await/async、Linq查询、WCF RIA Services、序列化、委托与事件

最近从技术支持转到开发岗,做Silverlight部分的开发,用的Prism+MVVM,框架由同事搭好,目前做的主要是功能实现,用到了一些东西,侧重于如何使用,总结如下:   1.UI控件与布局     2.MVVM     3.数据绑定     4.await/async     5.Linq查询     6.WCF RIA Services     7.序列化     8.委托与事件 1.UI控件与布局 常用的主要是Grid.StackPanel.Border,其中最常用的的是Grid,是一