博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于iOS自定义控件:在view上实现事件和代理
阅读量:4349 次
发布时间:2019-06-07

本文共 2794 字,大约阅读时间需要 9 分钟。

  • 自定义控件.h

#import <UIKit/UIKit.h>

#import "PPViewtouchesBeginDelegate.h"

 

@interface PPView : UIView

 

// 这样写避免了内存泄露的问题

@property (nonatomic, strong)UIView *Pview;

 

// 保存鼠标点击在父视图上的位置和子视图的偏移量

@property (nonatomic, assign)CGPoint plusPoint;

 

// 接收传递过来的方法和对象:在touchesBegin时使用该对象调用该包装的方法

@property (nonatomic, strong)id sender;

@property (nonatomic, assign)SEL action;

// 代码加载完毕,通过方法实现保存了该对象和需要调用的SEL

- (void)addTarget:(id)target andAction:(SEL)action;

 

// 点击view显示字符串

@property (nonatomic, strong)NSString *PPText;

// 限定合适的代理(弱引用):触发是view被点击时

@property (nonatomic, weak)id<PPViewtouchesBeginDelegate> delegate;

@end


  • 自定义控件代理

#import <Foundation/Foundation.h>

 

// 谁成为我的代理,谁就属于了我的类型:反向传值(代理应用_2)

@class PPView;

@protocol PPViewtouchesBeginDelegate <NSObject>

 

// - 确保传递出去的形参可以访问属性:谁触发就把谁传递出去

- (void)touchesPPVoewBegin:(PPView *)sender;

@end


 

  •  自定义控件.m

#import "PPView.h"

 

@implementation PPView

 

// 1.在原view基础上添加了一个view:每次创建自定义view就会自带一个添加了的view

- (instancetype)initWithFrame:(CGRect)frame

{

    // - 让该视图在被创建的父视图的中央

    if (self = [super initWithFrame:frame])

    {

        // > 父类初始化成功后才给子类的frame赋值

        CGFloat width = self.frame.size.width;

        CGFloat height = self.frame.size.height;

        

        // > 需要创建对象

        _Pview = [[UIView alloc] initWithFrame:CGRectMake(width/4, height/4, width/2, height/2)];

        _Pview.backgroundColor = [UIColor purpleColor];

        

        // > 在传递过来的父视图上添加主视图,而不是在主视图上:self.view

        [self addSubview:_Pview];

    }

    return self;

}

 

// 2.让添加的view能在父视图上移动

 

// - 基于原来的位置移动,而不是把view的center带到了鼠标点击的位置

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

{

    // > 先记录下点击当前视图的位置

    

    // * 获取点击的位置的坐标:通过方法传递过来的形参获取

     CGPoint clickPoint = [[touches anyObject] locationInView:self];

    

    // * 获取的坐标是相同的

    //[[touches anyObject] previousLocationInView:self];

    

    // > 保存主视图的中心点和鼠标点击位置的差值

    _plusPoint.x = _Pview.center.x - clickPoint.x;

    _plusPoint.y = _Pview.center.y - clickPoint.y;

    

   

    // 3.通过保存的对象和SEL:在touchesBegin时使用该对象调用该包装的方法

    // 注意:是调用被打包的方法,即点击view后传递过来的方法;而不是该类中自定义的事件

    [self.sender performSelector:self.action];

    

    

    // 4.代理:在点击view时让view显示属性(字符串):系统的TouchesBegin事件触发时

    // - 判断代理是否为空

    if (self.delegate!=nil)

    {

        // 判断代理是否实现了协议内方法

        if ([self.delegate respondsToSelector:@selector(touchesPPVoewBegin:)])

        {

            // >复合是思想:代理被使用代理的类所复合,通过代理调用了代理遵循的方法

            // > 确保传递出去的形参可以访问属性:谁触发就把谁传递出去

            [self.delegate touchesPPVoewBegin:self];

        }

    }else

    {

        NSLog(@"delegate = nil");

    }

    

}

 

// - 让鼠标的移动和子视图的距离变得固定

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

{

    CGPoint clickPoint = [[touches anyObject] locationInView:self];

    // > 保存鼠标点击父视图上的位置:这个值是不断变化的

    _Pview.center = (CGPoint){clickPoint.x+_plusPoint.x, clickPoint.y+_plusPoint.y};

}

 

// 3.在view上实现了button的效果

// - 触发事件时就保存了传递过来的对象和被打包的方法

- (void)addTarget:(id)target andAction:(SEL)action

{

    // - 代码加载完毕,通过方法实现保存了该对象和需要调用的SEL

    self.sender = target;

    self.action = action;

    

}


 

转载于:https://www.cnblogs.com/pruple/p/5267530.html

你可能感兴趣的文章
内部类单例模式,
查看>>
opensuse13.1 安装 SqliteMan
查看>>
念初三生活
查看>>
zbb20180827 java获取html内容
查看>>
node处理get和post请求
查看>>
【JAVA集合详解】LinkedList
查看>>
面向 例题
查看>>
RSA加密
查看>>
HTML5游戏开发进阶指南
查看>>
ASP.NET GBK读取QueryString
查看>>
[LintCode] 159 Find Minimum in Rotated Sorted Array
查看>>
在reshard过程中,将会询问reshard多少slots:
查看>>
地精排序-最简单的排序算法
查看>>
跑路啦 跑路啦 这个博客废掉啦
查看>>
JQuery 实现返回顶部效果
查看>>
辛苦挣钱买房,结果房产证一直办不下来
查看>>
Which kind of aspects of OIL PRESS MACHINERY would you like best
查看>>
[转载] 晓说——第17期:揭秘战争秘闻 朝鲜战争62年祭(下)
查看>>
java集合系列之ArrayList源码分析
查看>>
nyoj 518取球游戏(博弈)
查看>>