zoukankan      html  css  js  c++  java
  • iOS Button按钮 热区的放大

     一,苹果提出的有时候不太好用  二,运行时更改 往下看

        Apple的iOS人机交互设计指南中指出,按钮点击热区应不小于44x44pt,否则这个按钮就会让用户觉得“很难用”,因为明明点击上去了,却没有任何响应。

    但我们有时做自定义Button的时候,设计图上的给出按钮尺寸明显要小于这个数。例如我之前做过的自定义Slider上的Thumb只有12x12pt,做出来后我发现自己根本点不到按钮……

    这个问题在WWDC 2012 Session 216视频中提到了一种解决方式。它重写了按钮中的pointInside方法,使得按钮热区不够44×44大小的先自动缩放到44×44,再判断触摸点是否在新的热区内。

     

    //官方在视频中给出的示例源码
    - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)withEvent
    {
        CGFloat widthDelta = 44.0 - bounds.size.width;
        CGFloat heightDelta = 44.0 - bounds.size.height;
        bounds = CGRectInset(bounds, -0.5 * widthDelta, -0.5 * heightDelta);
        return CGRectContainsPoint(bounds, point);
    }

    Apple的iOS人机交互设计指南中指出,按钮点击热区应不小于44x44pt,否则这个按钮就会让用户觉得“很难用”,因为明明点击上去了,却没有任何响应。

    但我们有时做自定义Button的时候,设计图上的给出按钮尺寸明显要小于这个数。例如我之前做过的自定义Slider上的Thumb只有12x12pt,做出来后我发现自己根本点不到按钮……

    这个问题在WWDC 2012 Session 216视频中提到了一种解决方式。它重写了按钮中的pointInside方法,使得按钮热区不够44×44大小的先自动缩放到44×44,再判断触摸点是否在//官方在视频中给出的示例源码

     不过这里有两个小问题:

    • 当定义的Button.frame大于44×44时,这里仍然会将热区缩小至44×44,从而导致超过44×44的按钮热区失去响应。

    • bounds变量未定义

    修正后的代码如下:

    - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event
    {
        CGRect bounds = self.bounds;
        //若原热区小于44x44,则放大热区,否则保持原大小不变
    	CGFloat widthDelta = MAX(44.0 - bounds.size.width, 0);
    	CGFloat heightDelta = MAX(44.0 - bounds.size.height, 0);
    	bounds = CGRectInset(bounds, -0.5 * widthDelta, -0.5 * heightDelta);
    	return CGRectContainsPoint(bounds, point);
    }
    

    二: 运行时模式  UIButton+LP  

    //  UIButton+LP.h

    #import <UIKit/UIKit.h>

     @interface UIButton (LP)

    @property(nonatomic,assign)CGFloat enlargedEdge;

    //-(void)setEnlargedEdge:(CGFloat)enlargedEdge;

    //-(float)enlargeEdge;

    -(void)setEnlargedEdgeWithTop:(CGFloat)top left:(CGFloat)left bottom:(CGFloat)bottom right:(CGFloat)right;

    @end

    //  UIButton+LP.m

    #import "UIButton+LP.h"

    #import <objc/runtime.h>

    @implementation UIButton (LP)

    staticchar topEdgeKey;

    staticchar leftEdgeKey;

    staticchar bottomEdgeKey;

    staticchar rightEdgeKey;

    -(void)setEnlargedEdge:(CGFloat)enlargedEdge

    {

        [selfsetEnlargedEdgeWithTop:enlargedEdge left:enlargedEdge bottom:enlargedEdge right:enlargedEdge];

    }

    -(float)enlargeEdge

    {

        return [(NSNumber *)objc_getAssociatedObject(self, &topEdgeKey) floatValue];

    }

    -(void)setEnlargedEdgeWithTop:(CGFloat)top left:(CGFloat)left bottom:(CGFloat)bottom right:(CGFloat)right

    {

        objc_setAssociatedObject(self, &topEdgeKey, [NSNumbernumberWithFloat:top], OBJC_ASSOCIATION_RETAIN_NONATOMIC);

         objc_setAssociatedObject(self, &leftEdgeKey, [NSNumbernumberWithFloat:left], OBJC_ASSOCIATION_RETAIN_NONATOMIC);

         objc_setAssociatedObject(self, &bottomEdgeKey, [NSNumbernumberWithFloat:bottom], OBJC_ASSOCIATION_RETAIN_NONATOMIC);

         objc_setAssociatedObject(self, &rightEdgeKey, [NSNumbernumberWithFloat:right], OBJC_ASSOCIATION_RETAIN_NONATOMIC);

    }

    -(CGRect)enlargedRect

    {

        NSNumber * topEdge = objc_getAssociatedObject(self, &topEdgeKey);

        NSNumber * leftEdge = objc_getAssociatedObject(self, &leftEdgeKey);

        NSNumber * bottomEdge = objc_getAssociatedObject(self, &bottomEdgeKey);

        NSNumber * rightEdge = objc_getAssociatedObject(self, &rightEdgeKey);

        if(topEdge && leftEdge && bottomEdge && rightEdge){

            CGRect enlargedRect = CGRectMake(self.bounds.origin.x - leftEdge.floatValue, self.bounds.origin.y - topEdge.floatValue, self.bounds.size.width + rightEdge.floatValue + leftEdge.floatValue ,self.bounds.size.height + topEdge.floatValue + bottomEdge.floatValue);

            return enlargedRect;

        }else{

            returnself.bounds;

        }

    }

    -(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

    {

        if(self.alpha <= 0.01 || !self.userInteractionEnabled ||self.hidden){

            returnnil;

        }

        CGRect enlargedRect = [selfenlargedRect];

        returnCGRectContainsPoint(enlargedRect, point)?self:nil;

    }

    @end

     

  • 相关阅读:
    计算机安装Fedora操作系统——Win10+Linux双系统
    性能测试——压力测试指标
    系统吞吐量(TPS)、用户并发量、性能测试概念和公式
    在 数学吧 看到一个 极限题
    东方学帝 和 K歌之王 的 科学观 和 科学方法 的 对比
    走一走 欧拉先生 走过 的 路
    推导一个 经典物理 里 的 黑洞 的 坍缩半径
    四色定理 太简单了 , 来 玩 n 维空间 里 的 x 色定理
    今天看到了一个 求 平面图形 Centroid 的 办法
    记录一下这几天的一些讨论
  • 原文地址:https://www.cnblogs.com/tangyuanby2/p/5764070.html
Copyright © 2011-2022 走看看