iOS学习日记(十六)视图与视图层次结构

若如初见. 提交于 2019-11-28 19:50:35

本节,学习视图与视图层次结构的概念,并编写一个Hypnosister应用。应用只有一个界面,绘制了一系列同心圆。
(1)创建项目
创建a single + class 如下
在这里插入图片描述
由于xcode8不支持空项目,所以要创建single 然后进行修改。
参考如下
https://blog.csdn.net/MR_ROG/article/details/41719985

(2)编辑AppDelegate.m文件。
UIView子类模板自动生成两个方法,第一个是initWithFrame: 这个方法是UIView的指定初始化方法,带一个CGRect 结构类型的参数。
视图的frame 属性保存的是 视图的大小和相对于父视图的位置。
CGRect结构包含另外两个结构:origin(是CGPoint结构 包含x 和y 两个float类型成员)和size(CGSize结构,包含两个float成员:width和height)。

打开AppDelegate.m 找到application:didFinishLaunchchingWithOptions:方法
在创建UIWindow之后创建一个CGRect结构,使用他创建一个BNRHypnosister对象,设置背景为红色,最后加入UIWindow对象,使其成为子窗口

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window=[[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.window.backgroundColor=[UIColor whiteColor];
    BNRViewController *vc=[[BNRViewController alloc] init];
    self.window.rootViewController=vc;
    
    CGRect firstFrame=CGRectMake(160, 240, 100, 150);
    BNRHypnosister *firstView=[[BNRHypnosister alloc] initWithFrame:firstFrame];
    firstView.backgroundColor=[UIColor redColor];
    [self.window addSubview:firstView];
    
    [self.window makeKeyAndVisible];

    return YES;
}

结构不是OC对象,不能向CGRect发送消息,可以使用CGRectMake函数创建一个CGRect,传入4个参数。
在这里插入图片描述
(3)在drawRect中自定义绘图
视图根据drawRect: 方法把自己绘制到图层上。UIView的子类可以覆盖drawRect:完成自定义的绘图任务。

先修改这一条
(x)CGRect firstFrame =CGRectMake(160,240,100,150);
(✔)CGRect firstFrame=self.Window.bounds;
这样屏幕会显示充满全屏的红色视图
在这里插入图片描述
接下来在BNRHyponsisView.mz的drawRect:方法中添加代码 划出一个可能大的圆形

#import "BNRHypnosister.h"

@implementation BNRHypnosister

- (void)drawRect:(CGRect)rect {
    CGRect bounds=self.bounds;
    
    CGPoint center;//计算中心点
    center.x=bounds.origin.x+bounds.size.width/2.0;
    center.y=bounds.origin.y+bounds.size.height/2.0;
    
    //计算半径
    float radius=(MIN(bounds.size.width, bounds.size.height)/2.0);
}

@end

现在可以使用UIBezierPath类绘制圆形了,这个类用来绘制直线或者曲线,从而组成各种形状。
在这里插入图片描述

下面需要我们修改线条宽度和颜色。
UIBezierPath类有一个lineWidth属性。
使用set或者setStroke方法可以设置线条颜色。
setStroke方法是一个实例方法,因此需要创建一个UIColor对象。
在这里插入图片描述
可能已经注意到,视图的背景色属性不会受到drawRect:中代码的影响,通常应该把重写了drawRect:方法的视图背景颜色设置为透明 (clearColor),这样可以让视图只显示drawRect:方法中的内容。

注释掉appDelegate.m中 设置背景色的代码
在BNRHypnosisView.m中 重写initWithFrame:方法 设置BNRHypnosisView对象的背景色为透明。
在这里插入图片描述
(4)绘制同心圆

有两个基本的办法,第一个方法是创建多个UIBezierPath对象,每个对象代表一个圆形;
第二个方法是使用一个UIBezierPath对象绘制多个圆形,为每个圆形定义一个绘制路径。
第二个显然更好些,只创建一个UIBezierPath对象可以减少内存占用。

把视图的对角线作为外层圆的直径,这个圆形成为视图的外接圆,然后从这个直径递减,确定其他圆形的直径。
修改drawRect:方法代码如下

- (void)drawRect:(CGRect)rect {
    CGRect bounds=self.bounds;
    
    CGPoint center;//计算中心点
    center.x=bounds.origin.x+bounds.size.width/2.0;
    center.y=bounds.origin.y+bounds.size.height/2.0;
    
    //计算半径
    float maxRadius=hypot(bounds.size.width, bounds.size.height)/2.0;
    
    //定义路径
    UIBezierPath *path=[[UIBezierPath alloc] init];
    
    for(float currentRadius =maxRadius;currentRadius>0;currentRadius-=20)
    {
        [path addArcWithCenter:center
                    radius:currentRadius
                startAngle:0.0
                  endAngle:M_PI *2.0
                  clockwise:YES];
    }
    //设置线条
    path.lineWidth=10;
    [[UIColor lightGrayColor] setStroke];
    
    //绘制路径
    [path stroke];
}

在这里插入图片描述
看到右面多出了一条奇怪的线,这是因为UIBezierPath对象在绘制完一个圆之后去绘制另一个圆时没有抬起笔。正确做法是每次画完一个圆将抬起笔。

加入一行代码,画完一个圆形,画下一个圆时候,首抬起笔,移动到正确的位置。
[path moveToPoint:CGPointMake(center.x+currentRadius, center.y)];
在这里插入图片描述

初级练习:绘制图像
从文件创建一个UIImage对象只需要一行代码
UIImage *logoImage=[UIImage imageNamed:@“logo.png”];

在drawRect:方法中 把图像绘制到视图上 只需要添加一行代码:
[logoImage drawInRect:(CGRect类型的参数)];

在这里插入图片描述

高级练习:阴影和渐变

为阴影设置偏移量,CGSize
模糊指数 CGFloat

声明如下
void CGContextSetShadow(CGContextRef context,CGSize offset,CGFloat blur);

由于没有删除阴影效果的函数 所以先保存,再恢复
CGContextSaveGState(currentContext);
CGContextSetShadow(currentContext,CGSizeMake(4,7),3);

CGContextReStoreGState(currentContext):

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!