CS193P第五堂课摘要及心得笔记

2020-06-06 作者: 围观:483 40 评论

开课至今已经过了一个多月了,在第五堂课之前的内容大多都是一些基础的观念,是用来帮助我们建立 iPhone 应用程式的基本概念。而在这堂课开始,我们将深入了关于 iPhone 应用程式的深入细节。而在第五堂课中,主要的内容就是关于 View 的部份,也就是介面的呈现。

Views

在前面几堂课中我们曾经提过 MVC 的概念,也大概解说了 View 主要负责功能:显示内容、处理事件。而在实做上,每个 View 都是 UIResponder 的子类别,在画面上以方形呈现。此外,每个 View 下面都可以包含其他的 View,形成一个阶层的形式,要注意的是,每个 View 中涵盖的子 View 是用阵列存放,根据 Index 不同会决定显示的优先顺序。

而在 iPhone 程式中,每个程式里面会有唯一一个 UIWindow 这个 View,而剩下的所有的 View 都会包含在 UIWindow 中。我们要如何新增一个 View 到程式里面呢?有两种作法,一种是透过 Interface Builder 新增,另外也可以透过 UIView 的一些相关方法:

- addSubview:view;- removeFromSuperview;

透过 - addSubview 方法新增的 view 会自动被 retain,需要注意的是,当要移除某个 View 的时候直接对那个 View 呼叫 - removeFromSuperview 即可。当然,UIView 也提供了一些方法让我们可以手动调整 View 的优先顺序:

- insertSubview:view atIndex:index;- insertSubview:view belowSubview:view;- insertSubview:view aboveSubview:view;- exchangeSubviewAtIndex:index withSubviewAtIndex:otherIndex;

如果当我们只是想要暂时隐藏某个 View 的显示,我们可以直接透过 theView.hidden = YES; 就可以把 View 藏起来,不需要将 View 移除掉。

UIView 的定位系统
CS193P第五堂课摘要及心得笔记

UIView 掌管了画面上元素的显示,自然会需要精準的计算,与座标系统有关的物件结构有以下几个:

相对应的建立函式有以下几种,其中的参数均为浮点数:

在 iPhone 的画面上,最左上角的为原点,x 轴将往右延伸而 y 轴则是往下,如下图所视:

CS193P第五堂课摘要及心得笔记

View 的座标和大小又可以有两种表达方式 :Frame 和 Bounds。Frame 就是以上层 View 的角度来看的座标系统,而 Bounds 则是自己本身的座标系统
,而对最上层的 View 来说,其 Frame 等同于 Bounds。需要注意的是,Frame 并没有被储存在物件中,是透过物件的中心点座标以及长宽的资讯被计算出来的。对于 Bounds 和 Frame 有疑惑的朋友,可以参考下图:

CS193P第五堂课摘要及心得笔记

你或许会感到好奇,这样看起来 Frame 跟 Bonuds 的功能大同小异,但是当物件若进行旋转,则 Frame 会变成上层 View 中能涵盖此 View 的最小的四边形,如下图所示:

CS193P第五堂课摘要及心得笔记

那我们要在什幺时候使用 Frame,而又在什幺时候使用 Bounds 呢?可以用以下方法区隔:

建立 View

要如何建立 View 的物件呢?其实相当的简单。我们只要在 Interface Builder 中将想要的 UI 物件拉到 Nib 档中就可以了,就像作业 2B 一样的操作。

CS193P第五堂课摘要及心得笔记

不过我们也可以用程式码来建立新的 View,透过 UIView 物件的 ;-initWithFrame:frame 就可以依照 Frame 建立新的 View。但千万要记得,刚建立出来的 View 要透过 addSubview 将它加入到正确的 View 当中。

那我们要如何建立自己的 View 类别呢?其实我们只要创立一个 UIView 的子类别这样就可以了!

UI 动画

UIView 中提供了许多可以作成动画效果的相关 property,像是 frame、bounds 或是 alpha 和 transform 都是常见的例子。而除了这些可以作成动画的元素之外,也有一些相关的选项。下面是一个简单的範例:

- showAdvancedOptions {   // 假设 polygonView 和 optionView 的存在   [UIView beginAnimations:@”advancedAnimations” context:nil]; // 开始动画   [UIView setAnimationDuration:0.3]; // 动画时间设定为 0.3    optionsView.alpha = 1.0; // 将 optionView 的 alpha 值设到 1    CGRect polygonFrame = polygonView.frame;  // 取得 polygonView 的 frame   polygonFrame.origin.y += 200;  // 移动 frame   polygonView.frame = polygonFrame; // 将移动过后的 frame 指派给 polygonView,也就是让 polygonView 往下移动   [UIView commitAnimations]; // 执行动画 }

在以上这个範例中,我们将可以看到当此方法被呼叫之后,polygonView 将会往下移动,而 optionView 则从原本的透明状态恢复成正常显示,就如同下图中的显示:

CS193P第五堂课摘要及心得笔记

然而,iPhone 上的动画是非同步的,诚如上面程式所见,我们其实不知道什幺时候动画执行完毕。为了解决这个问题,我们可以使用 [UIView setAnimationDelegate:myController]; 来设定 delegate 类别,当动画要开始或结束时都会分别呼叫 delgate 类别的对应方法。详细的方法介绍在投影片的第 73 页可以参考。

以技术上的角度来讲,虽然 iPhone 是透过硬体加速来完成这些绚丽的动画,但实际是每一张 View 的绘图结果是会被快取起来的,只有当内容有做改变的时候 -drawRect 才会被再度呼叫。

最后,除了以上的物件移动及透明度的修改之外,UIView 也有提供变形的 property,也就是 transform。透过这个 property 和 Core Graphic 的函式,我们可以设定像是缩放、旋转等複杂的变形效果。有兴趣的朋友还请参考下面的参考资源。

结论

在这次的内容中我们学到了关于 View 的概念以及如何使用 View 来建立一些动画的效果,而在下一次的笔记中,我们将前进到第六堂课,还请各位读者敬请期待!

参考资源
相关浏览推荐