Iphone UIButton子类显示错误

Iphone UIButton子类显示错误,iphone,cocoa-touch,uibutton,Iphone,Cocoa Touch,Uibutton,我有一个通过NIB文件创建的按钮。我从UIButton派生了一个类,替换了NIB文件中的类名 现在我的按钮显示没有背景。文本就在那里,文本的字体和颜色都是正确的,它会像预期的那样对点击做出反应,但背景似乎是透明的。在NIB中,它不是透明的——除了类名之外,我没有更改任何属性 这个子类很简单——它什么都不重写(目前)。拜托,我做错什么了 我需要UIButton的子类的原因是,在某些情况下,我希望能够将文本从按钮拖动到其他位置。如果有其他方法可以在UIKit提供的视图中处理拖放操作,我愿意听听。检查

我有一个通过NIB文件创建的按钮。我从
UIButton
派生了一个类,替换了NIB文件中的类名

现在我的按钮显示没有背景。文本就在那里,文本的字体和颜色都是正确的,它会像预期的那样对点击做出反应,但背景似乎是透明的。在NIB中,它不是透明的——除了类名之外,我没有更改任何属性

这个子类很简单——它什么都不重写(目前)。拜托,我做错什么了


我需要UIButton的子类的原因是,在某些情况下,我希望能够将文本从按钮拖动到其他位置。如果有其他方法可以在UIKit提供的视图中处理拖放操作,我愿意听听。

检查NIB文件中按钮的状态。
可能您正在查看的是“活动”状态或其他东西,而不是更常见的uicontrol状态正常。

老实说,不确定子类出了什么问题,但“网络”(包括SO)中充满了关于将UIButton子类化的警告故事,以及您不应该如何子类化

所以我将使用四种触摸处理方法。以下函数将提供的按钮方法替换为my实现(取自MyButton类),同时将旧方法保存在不同选择器下的system button类中:

//Does NOT look at superclasses
static bool MethodInClass(Class c, SEL sel)
{
    unsigned n,i ;
    Method *m = class_copyMethodList(c, &n);
    for(i=0;i<n;i++)
    {
        if(sel_isEqual(method_getName(m[i]), sel))
           return true;
    }
    return false;
}

static void MountMethod(Class &buc, SEL SrcSel, SEL SaveSlotSel)
{
    IMP OldImp = [buc instanceMethodForSelector:SrcSel];
    IMP NewImp = [[MyButton class] instanceMethodForSelector:SrcSel];
    if(OldImp && NewImp)
    {
        //Save the old implementation. Might conflict if the technique is used
        //independently on many classes in the same hierarchy
        Method SaveMe = class_getInstanceMethod(buc, SaveSlotSel);
        if(SaveMe == NULL)
            class_addMethod(buc, SaveSlotSel, OldImp, "v@:@@");
        else
            method_setImplementation(SaveMe, OldImp);

        //Note: the method's original implemenation might've been in the base class
        if(MethodInClass(buc, SrcSel))
        {
            Method SrcMe = class_getInstanceMethod(buc, SrcSel);
            if(SrcMe)
                method_setImplementation(SrcMe, NewImp);
        }
        else //Add an override in the current class
            class_addMethod(buc, SrcSel, NewImp, "v@:@@");
    }
}
这样做的缺点是,为所有按钮安装所述方法,而不仅仅是为所需的按钮安装所述方法。在MyButton的实现中,还有一个额外的检查,即是否要为此特定按钮启用拖放功能。为此,我使用了关联对象


一个要点是touchesXXX方法在UIControl类中实现,而不是在UIButton中实现。因此,我的第一个简单的swizzling实现将取代UIControl中的方法,而不是button类。当前的实现不采用任何一种方式。此外,它没有对按钮的运行时类进行任何假设。可以是UIButton,也可以是任何东西(在真实的iOS中,它是UIRoundedRectButton)。

否,所有状态的背景和alpha都已设置。
Class buc = [bu class];
MountMethod(buc, @selector(touchesBegan:withEvent:), @selector(MyButton_SavedTouchesBegan:withEvent:));
    MountMethod(buc, @selector(touchesCancelled:withEvent:), @selector(MyButton_SavedTouchesCancelled:withEvent:));
    MountMethod(buc, @selector(touchesEnded:withEvent:), @selector(MyButton_SavedTouchesEnded:withEvent:));
    MountMethod(buc, @selector(touchesMoved:withEvent:), @selector(MyButton_SavedTouchesMoved:withEvent:));