当前位置: 首页 > article >正文

「OC」事件点击demo合集

「OC」事件点击demo合集

文章目录

  • 「OC」事件点击demo合集
    • 前言
    • 可用鼠标移动的UIview
    • 突出的tabBar按钮
    • 扩大按钮的响应范围

前言

在前面通过学习事件响应流程,学习了许多新的内容,当然也学习了许多不同的用法,但在之前的文章之中并没有将运用到事件响应链的demo写在文章当中,所以这篇文章总结了我学习事件点击写的一些小demo

可用鼠标移动的UIview

我们可以重写UIView之中的- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event,实现一个可供鼠标点击移动的UIview

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    //获取触摸对象
    UITouch *touch = [touches anyObject];
    //获取前一个触摸点位置
    CGPoint prePoint = [touch previousLocationInView:self];
    //获取当前触摸点位置
    CGPoint curPoint = [touch locationInView:self];
    //计算偏移量
    CGFloat offsetX = curPoint.x - prePoint.x;
    CGFloat offsetY = curPoint.y - prePoint.y;
    //相对之前的位置偏移视图
    self.transform = CGAffineTransformTranslate(self.transform, offsetX, offsetY);
}

Sep-07-2024 12-14-16

突出的tabBar按钮

我们通过重写tabBar的子类可以做出以下内容,但是我们发现点击超出tabBar范围的按钮部分并不会响应

//写tabBar的子类
#import "JCTabBar.h"
@implementation JCTabBar

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self setupCenterButton];
    }
    return self;
}

- (UIImage *)rotateImage:(UIImage *)image byDegrees:(CGFloat)degrees {
    CGSize size = image.size;
    UIGraphicsBeginImageContextWithOptions(size, NO, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    // 计算旋转角度
    CGContextTranslateCTM(context, size.width / 2, size.height / 2);
    CGContextRotateCTM(context, degrees * M_PI / 180);

    
    [image drawInRect:CGRectMake(-size.width / 2, -size.height / 2, size.width, size.height)];
    UIImage *rotatedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return rotatedImage;
}

- (void)setupCenterButton {
    self.centerButton = [UIButton buttonWithType:UIButtonTypeCustom];
    self.centerButton.backgroundColor = [UIColor whiteColor];

    [self.centerButton setImage:[UIImage imageNamed:@"jiahao.png"] forState:UIControlStateNormal];
    [self.centerButton setImage:[self rotateImage:[UIImage imageNamed:@"jiahao.png"] byDegrees:45] forState:UIControlStateSelected];
    [self addSubview:self.centerButton];
}

- (void)layoutSubviews {
    [super layoutSubviews];
    
    [self bringSubviewToFront:self.centerButton];
    
    CGFloat width = self.frame.size.width;
    
    self.backgroundColor = [UIColor whiteColor];
    CGFloat centerButtonSize = 60; // 中间按钮的大小
    self.centerButton.frame = CGRectMake((width - centerButtonSize) / 2,
                                         -centerButtonSize / 2,
                                         centerButtonSize ,
                                         centerButtonSize);
    self.centerButton.layer.cornerRadius = (centerButtonSize) / 2;
    self.centerButton.clipsToBounds = YES;
    [self.centerButton addTarget:self action:@selector(centerButtonAction:) forControlEvents:UIControlEventTouchUpInside];
    // 调整其他 TabBar 项的位置
    CGFloat tabBarItemWidth = width / 5;
    NSInteger index = 0;
    for (UIView *subview in self.subviews) {
        if ([subview isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
            if (index == 2) {
                // 跳过中间位置
                index++;
            }
            CGRect frame = subview.frame;
            frame.origin.x = index * tabBarItemWidth;
            subview.frame = frame;
            index++;
        }
    }
}

- (void)centerButtonAction:(UIButton *)sender {
    self.centerButton.selected = !self.centerButton.selected;
    

}

@end

Sep-07-2024 12-10-00

在这个demo之中我们主要是运用了在寻找最佳响应者之中的相关内容,我们先画出以下图片。

img

我们通过分析可以得出视图层次

RootView
└── TableView
└── TabBar
    └── CircleButton

如果我们点击按钮区域后,我们自己料想的应该是,生成的触摸事件首先传到UIWindow,然后传到控制器的根视图即RootView。RootView经判断可以响应触摸事件,而后将事件传给了子控件TabBar。但是问题就出在这里,如果我们点击红色方框的部分触摸点不在TabBar的坐标范围内,因此TabBar无法响应该触摸事件,hitTest:withEvent: 直接返回了nil。

既然如此,问题是出现在hitTest:withEvent: 的判断逻辑之上,我们只要重写TabBar的 pointInside:withEvent: 当我们点击到按钮的范围就返回YES,如果没有点击到按钮的范围之中,那么就按照之前的点击方式进行判断即可。

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
    //将触摸点坐标转换到在CircleButton上的坐标
    CGPoint pointTemp = [self convertPoint:point toView:_centerButton];
    //若触摸点在CricleButton上则返回YES
    if ([_centerButton pointInside:pointTemp withEvent:event]) {
        return YES;
    }
    //否则返回默认的操作
    return [super pointInside:point withEvent:event];
}

修改pointInside的方法后我们得到的程序如下

Sep-07-2024 12-24-33

无论我们点击按钮的哪个位置,按钮都可以正常响应啦。但是这个demo存在另外一个问题,如果给按钮添加旋转45度的动画的话,按钮会直接消失,可能是这个button旋转45度之后超出了正常下时的。所以我只能使用Core Graphics对图像进行旋转,关于Core Graphics框架的内容感觉后面会再进行学习,整理为一篇博客。

扩大按钮的响应范围

如果我们需要使用按钮来扩大它的响应范围10个像素,我们可以修改hitText的方法

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    CGRect extendedBounds = CGRectInset(self.bounds, -10, -10); // 扩大点击区域
    return CGRectContainsPoint(extendedBounds, point);
}

通过扩大button的原有范围,进行判断即可轻松的实现


http://www.kler.cn/a/305478.html

相关文章:

  • Go语言锁笔记
  • Unity性能优化 -- 性能分析工具
  • 多态(c++)
  • EasyUI弹出框行编辑,通过下拉框实现内容联动
  • LeetCode热题100之贪心算法
  • Go语言goroutine线程和channel通信
  • python数据分析知识点大全
  • 560 和为k的子数组
  • pptp解说
  • vb.net发送邮件:如何高效地实现邮件发送?
  • 【鸿蒙】HarmonyOS NEXT星河入门到实战4-ArkTS界面布局深入
  • 什么品牌的宠物空气净化器性价比最高?352/希喂/霍尼韦尔/有哈/IAM实测对比
  • Oracle(125)如何执行不完全恢复?
  • Netty笔记07-粘包与半包(上)
  • 新能源汽车出海中的数据合规热点问题
  • 系统分析师--系统可靠性分析与设计
  • Rust编写Windows服务
  • 从“天宫课堂”到人工智能:中国少儿编程的未来在哪里?
  • golang学习笔记12——Go 语言内存管理详解
  • 软件测试工程师面试整理-数据库与SQL
  • 微信小程序使用 ==== 粘性布局
  • Ubuntu 常用指令和作用解析
  • 16. MyBatis的延迟加载机制是什么?如何配置?有哪些优缺点?
  • 股票程序化交易赚钱吗,证监会如何监测股票多账户关联交易
  • Vue 创建自定义指令 以及创建自定义指令相关属性说明
  • DFS 算法:洛谷B3625迷宫寻路