广

IOS开发

  • IOS开发
  • android开发
  • PHP编程
  • JavaScript
  • ASP.NET
  • ASP编程
  • JSP编程
  • Java编程
  • 易语言
  • Ruby编程
  • Perl编程
  • AJAX
  • 正则表达式
  • C语言
  • 编程开发

    iOS开发中Subview的事件响应以及获取subview的方法

    2018-04-04 08:34:43 次阅读 稿源:互联网
    广告

    Subview的事件响应
    在view的层级里面,默认情况下subview是可以显示到其父view的frame区域以外的,通过设置clipToBounds属性为YES,可以限制subview的显示区域。但是touch在各个UIView中传递的时候,区域时限制在view的frame内,此处包含两个信息:1、在当前view的frame以外所做的操作是不会传递到该view中的,这一点很容易理解。2、如果touch事件是发生在当前view的frame以外,该view所有的subview将也不会再收到该消息。这一点通常容易被我们忽略,很多奇怪的问题就是这个引起的。
     
      下面请看一个小例子,定制view的代码如下:
     
    代码如下:

    SvTestClipSubviewEvent.h

    //

    //  SvTestClipSubviewEvent.h

    //  SvUIViewSample

    //

    //  Created by maple on 3/19/12.

    //  Copyright (c) 2012 smileEvday. All rights reserved.

    //

    //  默认的情况下,subView可以超出父view的frame,即可以显示到父View的外边

    //  但是消息的接受返回却是由于父View的大小限制,即出了父View的subView将不能收到消息

    //  在程序中一定要注意当前程序view的最底层是充满整个window的可用区域的,

    //  否则将会导致某些区域明明有按钮但是却点不中的问题

    #import <UIKit/UIKit.h>

    @interface SvTestClipSubviewEvent : UIView

    @end

    代码如下:

    //
    //  SvTestClipSubviewEvent.m
    //  SvUIViewSample
    //
    //  Created by maple on 3/19/12.
    //  Copyright (c) 2012 smileEvday. All rights reserved.
    //

    #import "SvTestClipSubviewEvent.h"

    @interface SvTestClipSubviewEvent()

    - (void)btnAction:(UIButton*)btn;

    @end

    @implementation SvTestClipSubviewEvent

    - (id)initWithFrame:(CGRect)frame
    {   
        self = [super initWithFrame:frame];   
        if (self) {       
            // Initialization code       
            self.backgroundColor = [UIColor redColor];               
            UIButton *testOutBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];                    testOutBtn.frame = CGRectMake(-80, -50, 70, 30);      
            [testOutBtn addTarget:self action:@selecto (btnAction: forControlEvents:UIControlEventTouchUpInside];       
            [testOutBtn setTitle:@"I'm out" forState:UIControlStateNormal];       
            [self addSubview:testOutBtn];                
            UIButton *testInBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];                    testInBtn.frame = CGRectMake(20, 30, 70, 30);       
            [testInBtn setTitle:@"I'm in" forState:UIControlStateNormal];       
            [testInBtn addTarget:self action:@selector(btnAction: forControlEvents:UIControlEventTouchUpInside];       
            [self addSubview:testInBtn];   
        }   
        return self;
    }

    /*
    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    - (void)drawRect:(CGRect)rect
    {   
        // Drawing code
    }
    */

    - (void)btnAction:(UIButton*)sender
    {   
        NSLog(@"HI, you tap button %@", [sender titleForState:UIControlStateNormal]);
    }
    @end

      在程序的ViewController中添加如下测试代码:
     代码如下:

    SvTestClipSubviewEvent *testClipSubView = [[SvTestClipSubviewEvent alloc]initWithFrame:CGRectMake(100, 100, 150, 150)];
    [self.view addSubview:testClipSubView];
    [testClipSubView release];
      运行可以看到如下界面:

    获取subview
    通常我们在view层级里面对subView的操作可以通过两种方式:1、保留一个subview的引用,然后在类中通过该引用对该subview进行操作,但是要注意在适当的位置添加内存维护的代码,退出前手动释放。2、设置subview的Tag,让后在要使用的时候,通过viewWithTag获取到相应的subview,这种方法比较简洁,也不用自己去维护内存。
     
      ViewWithTag: 通常采用深度遍历优先的算法,返回第一个tag和给定Tag相等的subview。这就导致了一个当一个view的多个subview的tag相同的时候,我们通过该方法得到的view可能并不是自己想要的。
     
      下面通过一个小例子验证一下,代码如下:
     
    代码如下:

    //
    //  SvTestViewTag.h
    //  SvUIViewSample
    //
    //  Created by maple on 3/18/12.
    //  Copyright (c) 2012 smileEvday. All rights reserved.
    //
    //  view根据Tag获取subView的时候执行的是深度优先遍历的算法
    //  返回第一个Tag和请求tag相等的子View
    //  从subViews中查找,最下层的优先找到

    #import <UIKit/UIKit.h>

    @interface SvTestViewWithTag : UIView

    @end


    例子中每个subview都是一个UILabel,而且设置了相应的内容。按钮的响应函数的实现思路:首先隐藏所有类型为UILabel的subview(排除UIButton,因为button需要一直显示),然后根据指定的Tag获取到相应的subview,该subview及其superView的hidden属性为NO。这样就可以保证点击按钮的时候只显示的是第一个tag和指定tag相等的subview。
     
      为了验证viewWithTag获取subview的原理:
     
      首先我在subview1中添加了两个tag都为11的subview11和subview12。 运行程序可以,当我们点击"Show Tag 11"按钮的时候屏幕上将显示“SubView11”,而非“SubView12”。同时不管你点击几次该按钮,始终只显示“SubView11”。这样可以看出来同一层级中获取subview时候查找顺序为index从小到大的原则,即位于相对下层的将首先被找到。
     
      其次我还在subview1中添加了tag均为13的subview13,同时向view中添加了tag也为13的subview2,运行程序点击“Show Tag 13”按钮,屏幕上将会显示“SubView13”,而非“SubView2”。这可以验证viewWithTag在搜索的时候遵循深度优先遍历的原则,即会首先查找最下层的view并递归查询其subview。
     
      综上两点我们可以看出来viewWithTag获取subview的基本原则,即遵循深度优先,下层优先两个原则。

    一起学吧部分文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与一起学吧进行文章共享合作。

    广告
    广告
    广告