iOS学学习日记(十七)重绘与UIScrollView

这篇博客介绍了在iOS开发中如何实现自定义视图BNRHypnosister的重绘,当用户触摸时改变颜色。首先声明一个属性来保存圆形颜色,并在drawRect:方法中使用。接着覆盖touchesBegan:withEvent:方法处理触摸事件,但由于自定义视图被rootViewController的content view遮挡,需调整视图层级。通过setNeedsDisplay消息标记视图需要重绘,实现颜色变化。然后讲解如何使用UIScrollView展示大尺寸视图,通过设置contentSize实现滚动,并启用paging实现分页效果。
摘要由CSDN通过智能技术生成

本节,继续开发Hypnosister应用,当用户触摸视图时,圆形的颜色会改变。为了改变颜色,BNRHyponsister需要重新绘制自己。
(1)声明一个属性,用来表示圆形的颜色

在BNRHypnosister.m的类扩展部分声明属性,并在initWithFrame:方法中初始化

@interface BNRHypnosister()
@property(strong,nonatomic)UIColor *circleColor;
@end

@implementation BNRHypnosister
- (instancetype)initWithFrame:(CGRect)frame
{
    self=[super initWithFrame:frame];
    if(self)
    {
        self.backgroundColor=[UIColor clearColor];
        self.circleColor=[UIColor lightGrayColor];
    }
    return self;
}

在drawRect:方法中修改设置线条颜色的代码,使用circleColor作为线条颜色。

//[[UIColor lightGrayColor] setStroke];
    [self.circleColor setStroke];

(2)编写视图触摸改变颜色的代码

当用户触摸视图时,视图会受到touchesBegan:withEvent: 消息,用来处理触摸事件
在BNRHypnosister.m中对这个方法进行覆盖

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    NSLog(@"%@ was touched",self);
    float red=arc4random()%100/100.0;
    float green=arc4random()%100/100.0;
    float blue=arc4random()%100/100.0;
    UIColor *randomColor=[UIColor colorWithRed:red
                                         green:green
                                          blue:blue
                                         alpha:1.0];
    self.circleColor=randomColor;
}

**这里强调一点:
触摸视图并没有触发触摸事件,是因为需要把我自定义的UIView添加到这里1,而不是2
rootViewController会给window设定一个content View,也是UIView类,所以将我自定义的UIView给遮挡了,导致无法触发touchesBegan事件

[self.window.rootViewController.view addSubview:firstView];  //1
[self.window addSubview:firstView];  //2


此时构建项目,点击任意位置 控制台输出触摸事件,但是颜色并未改变。
应用将控制权交回给运行循环时,首先检查有没有等待重绘的视图,向它们发送drawRect:消息。
这是因为我们还需要进行重绘,发送一次drawRect:消息。

(3)进行重绘标记
为了标记视图需要重绘,必须向其发送setNeedsDisplay消息。
做法是:为circleColor属性实现自定义的存方法,当circleColor改变时(就是调用了存方法的时候)向视图发送setNeedsDisplay消息。

- (void)setCircleColor:(UIColor *)circleColor
{
    _circleColor=circleColor;
    [self setNeedsDisplay];
}

在这里插入图片描述
在这里插入图片描述
点击视图可以换色了。

(4)使用UIScrollView
添加一个UIScrollView对象,使其成为应用窗口的子视图,然后再将BNRHypnosister作为子视图加入UIScrollView对象。

UIScrollView对象的尺寸就是这个镜头的尺寸,能拍摄的范围是由属性 contentSize决定的。创建一个超大尺寸的BNRHyponsister对象并将其加入一个UIScrollView对象,然后把这个UIScrollView对象加入窗口。

 //创建两个结构作为 uiscrollview和bnrhtpnosister对象的frame
    CGRect screenRect=self.window.bounds;
    CGRect bigRect =screenRect;
    bigRect.size.height*=2.0;
    bigRect.size.width*=2.0;
    //分别设置两个对象
    UIScrollView *scrollView=[[UIScrollView alloc] initWithFrame:screenRect];
    [self.window.rootViewController.view addSubview:scrollView];
    BNRHypnosister *hypnosisView=[[BNRHypnosister alloc] initWithFrame:bigRect];
    [scrollView addSubview:hypnosisView];
    //设置取景范围
    scrollView.contentSize=bigRect.size;
    
    [self.window makeKeyAndVisible];

**这里注意self.window.rootViewController.view 道理同之前所说,否则触摸事件不会被触发。
在这里插入图片描述
可以拖动来查看大尺寸的背景其余部分。

(5)拖动与分页
UIScrollView对象还可以滑动显示所有加入UIScrollView对象的子视图

把BNRHypnosister对象的尺寸改回与屏幕的尺寸相同,然后再创建一个BNRHypnosister对象,并加入UIScrollView对象。此外将UIScrollView的contentSize宽度设置为屏幕宽度的两倍。
代码如下:

//创建两个结构作为 uiscrollview和bnrhtpnosister对象的frame
    CGRect screenRect=self.window.bounds;
    CGRect bigRect =screenRect;
    bigRect.size.width*=2.0;
    
    //分别设置三个对象
    UIScrollView *scrollView=[[UIScrollView alloc] initWithFrame:screenRect];
    [self.window.rootViewController.view addSubview:scrollView];
    
    BNRHypnosister *hypnosisView=[[BNRHypnosister alloc] initWithFrame:screenRect];
    [scrollView addSubview:hypnosisView];
    screenRect.origin.x+=screenRect.size.width;
    
    BNRHypnosister *anotherView=[[BNRHypnosister alloc] initWithFrame:screenRect];
    [scrollView addSubview:anotherView];

    //设置取景范围
    scrollView.contentSize=bigRect.size;
    
    [self.window makeKeyAndVisible];

此时左右拖动屏幕看到两个对象,有可能出现连接部分。
在这里插入图片描述
有些时候我们需要让镜头的边和某个视图对齐,加入一行代码如下
[scrollView setPagingEnabled:YES];
构建并运行,拖动屏幕直到能看到两个对象的连接部分,松开之后会自动把镜头切换到一个对象上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值