簡體   English   中英

UIButton 子類顯示錯誤

[英]UIButton subclass displays wrongly

我有一個通過 NIB 文件創建的按鈕。 我從UIButton派生了一個 class ,替換了 NIB 文件中的 class 名稱。

現在我的按鈕顯示沒有背景。 文字在那里,文字字體和顏色是正確的,它按預期對點擊做出反應,但就好像背景是透明的一樣。 在 NIB 中,它不是透明的 - 除了 class 名稱之外,我沒有更改任何屬性。

子類是微不足道的——它什么都不覆蓋(現在)。 請問,我做錯了什么?

我需要 UIButton 的子類的原因是因為我希望能夠在某些情況下將文本從按鈕拖到其他地方。 如果有另一種方法來處理 UIKit 提供的視圖中的拖放,我願意聽到。

檢查 NIB 文件中按鈕的狀態。 您可能正在查看“活動”state 或其他東西,而不是更常見的 UICONTROLSTATENORMAL。

老實說,不確定子類有什么問題,但是“網絡”(包括 SO)充滿了關於子類 UIButton 的警示故事,以及您不應該如何。

所以我將 go 與方法混搭在四種觸摸處理方法上。 以下 function 用我的實現(取自 MyButton 類)替換了提供的按鈕方法,同時將舊方法保存在系統按鈕 class 下的不同選擇器下:

//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@:@@");
    }
}

並這樣稱呼它:

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:));

這具有為所有按鈕安裝所述方法的缺點,而不僅僅是為所需的按鈕。 在 MyButton 的實現中,有一個額外的檢查是否要為這個特定按鈕啟用拖放功能。 為此,我使用了關聯對象。

一點是 touchesXXX 方法是在 UIControl class 中實現的,而不是在 UIButton 中實現的。 所以我的第一個簡單的 swizzling 實現將替換 UIControl 中的方法,而不是按鈕 class。 當前的實現不假設任何一種方式。 此外,它不對按鈕的運行時 class 做任何假設。 可以是 UIButton,可以是任何東西(實際上是 iOS,它是 UIRoundedRectButton)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM