目标c如何为整个应用程序上的所有UIbuttons设置独家触摸

Posted

技术标签:

【中文标题】目标c如何为整个应用程序上的所有UIbuttons设置独家触摸【英文标题】:objective c how to set exclusive touch for all UIbuttons on the whole app 【发布时间】:2014-06-11 08:16:55 【问题描述】:

我的应用程序有很多按钮

我想同时设置 Exclusive Touch 所有这些。或应用中的所有视图

我们可以单独设置

[button setExclusiveTouch:YES];

但我想一次设置应用程序中的所有按钮

我们可以设置所有视图独占触摸吗?

任何人有任何想法请建议我。

【问题讨论】:

你能不能只创建一个UIButton 的子类,然后你可以覆盖initbuttonWithType: 方法,并在创建按钮时将setExclusiveTouch: 设置为默认值YES . 然后他需要更改应用程序中所有已创建按钮的引用.. 你为什么要这样做?你就不能用别的办法解决你的问题吗? @Apurv 并不是真的他只能做#define UIButton MyButton,所以只要MyButton 类是UIButton 的子类,它就应该用MyButton 替换所有UIButtons,但保持UIButton 名称(我希望你明白我的意思)我以前在我的一个应用程序中做过这个,但是因为我不在我的 Mac 附近来测试这个我刚刚做了评论 我试过了.. 但是当我做#define UIButton MyButton 然后在@interface MyButton : UIButton 的声明中,它会尝试用 MyButton 替换基类(UIButton).. 【参考方案1】:

最优雅且设计合理的方法是使用appearance 代理,该代理旨在为给定的 UI 组件设置一个已定义的行为或外观。

[[UIButton appearance] setExclusiveTouch:YES];

更多信息:Apple Documentation - UIAppearance和NSHipster - UIAppearance

【讨论】:

请添加更多关于您的代码的作用和工作原理的解释,而不是单行代码【参考方案2】:

你可以试试这个

// Not tested
for (UIView * button in [myView subviews]) 
    if([button isKindOfClass:[UIButton class]])
        [((UIButton *)button) setExclusiveTouch:YES];

【讨论】:

【参考方案3】:

如果您真的想为整个应用程序中的所有 UIButtons + 子类设置exclusiveTouch 而不仅仅是单个视图,您可以使用method swizzling。

您使用 objc 运行时覆盖 willMoveToSuperview 并在那里设置独占触摸。 这是非常可靠的,我在使用这种技术时从来没有遇到过任何问题。

我特别喜欢为UISwitch 这样做,因为开关的触摸处理可能有点棘手,exclusiveTouch 将有助于避免同时点击不同开关引起的错误

从上面的链接中获取的示例并进行了更改,以便设置 exclusiveTouch

#import <objc/runtime.h>


@implementation UIButton (INCButton)

+ (void)load

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^
        Class class = [self class];

        SEL originalSelector = @selector(willMoveToSuperview:);
        SEL swizzledSelector = @selector(inc_willMoveToSuperview:);

        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);

        BOOL didAddMethod =
        class_addMethod(class,
                    originalSelector,
                    method_getImplementation(swizzledMethod),
                    method_getTypeEncoding(swizzledMethod));

        if (didAddMethod) 
            class_replaceMethod(class,
                            swizzledSelector,
                            method_getImplementation(originalMethod),
                            method_getTypeEncoding(originalMethod));
         else 
            method_exchangeImplementations(originalMethod, swizzledMethod);
        
    );


- (void)inc_willMoveToSuperview:(UIView *)newSuperview

    // This is correct and does not cause an infinite loop!
    // See the link for an explanation 
    [self inc_willMoveToSuperview:newSuperview];

    [self setExclusiveTouch:YES];


@end

为您要更改的每个类创建一个类别并插入此代码。

【讨论】:

在 appstore 应用中使用此代码有什么问题吗?我的意思是如果我们使用这种技术,苹果会拒绝吗? 没有。这不使用任何私有 API。它只是开发应用程序时通常不需要使用的较低级别的运行时代码;) 不客气。但是,您真的应该点击我在回答中提供的NSHipster 的链接。在这里仅仅复制粘贴代码是不够的——你应该真正理解你在调配方法时到底在做什么——这是一个很好的建议! 是的。我浏览了这篇文章。这是一篇写得很好的文章,它以一种简单而完美的方式解释了这种令人兴奋的技术。我现在是 nshipster 的订阅者。我只是喜欢那个网站。【参考方案4】:

为什么这么难?建立一个类别

@implementation UIButton (ExclusiveTouch)

- (BOOL)isExclusiveTouch

    return YES;


@end

【讨论】:

【参考方案5】:

循环遍历最顶层视图的子视图(递归),并为每个 UIButton 类型的对象应用独占触摸

【讨论】:

以上是关于目标c如何为整个应用程序上的所有UIbuttons设置独家触摸的主要内容,如果未能解决你的问题,请参考以下文章

如何为这些 UIButtons 设置边距

如何为具有动态宽度的 UIButtons 设置背景?

自定义 uitableviewcell 中的 Uibuttons

K6 负载测试 - 如何为整个测试运行创建顺序 ID

目标 C 中选择器上的 EXC_BAD_ACCESS

如何为 MWS 上的产品 Feed 提交创建 Item 节点?