自定义view的一些记录

来源:互联网 发布:linux gpu使用率 编辑:程序博客网 时间:2024/06/04 22:24

在做自定义view,给一个AVPlayerviewcontrller用。

首先,这个view上有暂停,快进,快退 全屏button,还有一个进度条的progress,都采用了懒加载的方式加载到view上,为了节省内存开销:

-(UIButton *)fullScreen{

    if (!_fullScreen) {

        _fullScreen=[UIButtonbuttonWithType:UIButtonTypeCustom];

        [_fullScreensetBackgroundImage:[UIImageimageNamed:@"kr-video-player-fullscreen"]forState:UIControlStateNormal];

        [_fullScreenaddTarget:selfaction:@selector(fullScreenBtnAction:)

                 forControlEvents:(UIControlEventTouchUpInside)];

        

    }

    return_fullScreen;

}

-(UIButton *)pause{

    if (!_pause) {

        _pause=[UIButtonbuttonWithType:UIButtonTypeCustom];

        [_pausesetBackgroundImage:[UIImageimageNamed:@""]forState:UIControlStateNormal];

        [_pauseaddTarget:selfaction:@selector(fullScreenBtnAction:)

              forControlEvents:(UIControlEventTouchUpInside)];

    }

    return_pause;

}

-(UIButton *)goForward{

    if (!_goForward) {

        _goForward=[UIButtonbuttonWithType:UIButtonTypeCustom];

        [_goForwardsetBackgroundImage:[UIImageimageNamed:@"next.png"]forState:UIControlStateNormal];

        [_goForwardaddTarget:selfaction:@selector(fullScreenBtnAction:)

         forControlEvents:(UIControlEventTouchUpInside)];

    }

    return_goForward;

}

-(UIButton *)backForward{

    if (!_backForward) {

        _backForward=[UIButtonbuttonWithType:UIButtonTypeCustom];

        [_backForwardsetBackgroundImage:[UIImageimageNamed:@"返回.png"]forState:UIControlStateNormal];

        [_backForwardaddTarget:selfaction:@selector(fullScreenBtnAction:)

         forControlEvents:(UIControlEventTouchUpInside)];

    }

    return_backForward;

}

-(UIView *)bottomView{

    if (!_bottomView) {

        _bottomView=[[UIViewalloc]init];

        _bottomView.backgroundColor=[UIColorgreenColor];

    }

    return_bottomView;

}

-(UIProgressView *)progress{

    if (!_progress) {

        _progress=[[UIProgressViewalloc]init];

        

    }

    return_progress;

}


懒加载创建完毕,首先说明一下,懒加载时候的属性用的是_name,这是因为:

@property (nonatomic,copy) NSString *propertyName;

self.propertyName是对属性的访问;使用_propertyName是对局部变量的访问。

所有被声明为属性的成员,在iOS5 之前需要使用编译器指令@synthesize 来告诉编译器帮助生成属性的getter,setter方法。之后这个指令可以不用人为指定了,默认情况下编译器会帮我们生成。 编译器在生成getter,setter方法时是有优先级的,它首先查找当前的类中用户是否已定义属性的getter,setter方法,如果有,则编译器会跳过,不会再生成,使用用户定义的方法。 也就是说你在使用self.propertyName 时是在调用一个getter方法。

self.propertyName 会让计数器+1;_propertyName却不会。  

_propertyName是类似于self->_propertyName。

用self.propertyName 是更好的选择,因为这样可以兼容懒加载,同时也避免了使用下划线的时候忽视了self这个指针,后者容易在block中造成循环引用。

接下来就是对这个view进行初始化操作。

-(instancetype)initWithFrame:(CGRect)frame{

   self=[superinitWithFrame:frame];

    if (self) {

        [selfaddSubview:self.bottomView];

        [self.bottomViewaddSubview:self.goForward];

        [self.bottomViewaddSubview:self.backForward];

        [self.bottomViewaddSubview:self.fullScreen];

        [self.bottomViewaddSubview:self.pause];

        [self.bottomViewaddSubview:self.progress];

        

        isShowBar=YES;

        UITapGestureRecognizer * tap=[[UITapGestureRecognizeralloc]initWithTarget:selfaction:@selector(tapview:)];

        [selfaddGestureRecognizer:tap];

        

    }

    

    returnself;

}

至此,我的疑问来了,我在外面的viewcontrller中初始化这个view的时候,用懒加载调用的是【view alloc】 init】;但是上面这个初始化方法initWithFrame方法打断点之后也走了,这是为什么呢?查了一下,用纯代码创建的view在init的时候都会调用initWithFrame。即使用init方法初始化也会调用initWithFrame,只是frame参数是CGRectZero。用xib和storyboard创建的view初始化的时候调用inirWithCoder。原理和上面一样。

这样就解释了我再外面调用该view时  也对他进行了初始化操作,也能解释手势调用。

初始化完毕后,对懒加载的空间设置的frame 就用layoutSubviews 这个方法 就可以了 。

-(void)layoutSubviews{

    self.bottomView.frame=CGRectMake(0,self.bounds.size.height-BarHeight,self.bounds.size.width,BarHeight);

    self.bottomView.backgroundColor=[UIColorgreenColor];

    self.progress.frame=CGRectMake(100,self.bounds.size.height-BarHeight,self.bounds.size.width-200,BarHeight);

    self.backForward.frame=CGRectMake(50,self.bounds.size.height-BarHeight,40, BarHeight);

    self.goForward.frame=CGRectMake(self.bounds.size.width-100,self.bounds.size.height-BarHeight,40, BarHeight);

    self.pause.frame=CGRectMake(0,self.bounds.size.height-BarHeight,40, BarHeight);

}

初始化方法走完之后会自动走这个方法,我吧这个方法改了个名字  然后在初始化时候调用  不知道为什么没走。这也是疑问之一。

查了一下,layoutSubview是处理子视图的数据,那么我view在初始化的时候调用init,会调用initwithframe方法。而这个view上的各种button和progress  属于子视图所以调用这个方法可以,而如果把layoutSubview改成别的自定义名字,因为这个是定义各种属性,在对view的init未结束时,子视图是没办法显示出来的。目前的理解是这样的,希望大神指正。

0 0
原创粉丝点击