2009-10-13 74 views
5

我怎樣才能得到一個非矩形的按鈕?具有非矩形形狀的iPhone按鈕?

例如我有一個具有alpha透明度的PNG圖像。 如何在不使用透明色的情況下將按鈕的形狀設置爲此圖像。

+0

更多細節它你正在尋找的東西可能會讓你想要更快地走到哪裏。 – fbrereto

回答

8

像別人說你應該有登記觸摸事件合理的表面,但我敢肯定你知道,有你的原因,所以我就告訴你我是如何做的:

我需要不久之前就做到了這一點,我所做的就是Sixten Otto剛剛提出的建議。有在我原來的問題在某一個點獲得你的圖像的阿爾法值(「UPDATE」一節)一些提示:

How to create a transparent window with non-rectangular buttons?

編輯:我建議在這個例子中繼承UIControl以下,但如果除了「非矩形」之外,你不需要在按鈕上有任何特殊的行爲,只需設置一個與你的PNG設置的無邊界UIButton就可以完成這項工作並且需要較少的工作。通過對UIControl進行繼承,您可以更好地控制控件的行爲,儘管這樣做是「艱難的」。

我建議你子類UIControl並重寫觸摸事件方法,然後檢查點擊點下的阿爾法,如果alpha == 0不處理事件。對於繪圖,您可以覆蓋drawRect:並使用NSImage的方法在控件的框架中繪製圖像。

首先你需要加載圖像,並得到了它的位圖表示:

buttonImage = [NSImage imageNamed:@"myButtonImage"]; 
buttonImageRep = [[buttonImage representations] objectAtIndex:0]; 

然後你就可以把它畫到控件的觀點:(其中stateImage是一個指針,必須根據要繪製的圖像如果該按鈕被按下或沒有)

- (void)drawRect:(NSRect)aRect { 
[stateImage drawInRect:[self bounds] fromRect:NSMakeRect(0.0,0.0,[buttonImage size].width,[buttonImage size].height) 
     operation:NSCompositeSourceOver fraction:1.0]; 
} 

在這一點上,你已經繪製了你的按鈕,你的PNG圖像。您可以覆蓋觸摸事件的方法,如果字母不爲0處理事件:

NSColor *colorUnderMouse = [buttonImageRep colorAtX:mouse.x y:mouse.y]; 
float alpha = [colorUnderMouse alphaComponent]; 

這就是我沒有和它奇妙的作品。希望這可以幫助!

N.B:我的例子是Mac,但它也應該在iPhone上工作,也許稍作修改。

7

參考這聽起來像你正在尋找按鈕的可點擊區域完全符合您使用的PNG。

如果這就是你要找的,我首先會說不要那樣做。使用手指按壓iPhone,通常沒有精確度來區分這樣的小區域。

但是,如果你堅持這個想法,那麼解決方案是根本不使用按鈕,而是處理父框架中的單擊並手動解釋單擊的X/Y值以確定它是否在某些(在圓形邊緣按鈕的情況下,可能包括檢查4個圓圈和2個矩形的結果)

編輯: 實現你的原始問題的一部分,我注意到你提到你想處理功能會自動基於Alpha通道。雖然我會推薦我的邊界區域的方法,但理論上可以通過對PNG進行採樣來測試Alpha通道,其偏移量取決於按鈕的原點。甚至可能在正常按鈕的單擊事件中執行此操作。

2

由於Guvante says,依靠精確觸摸確實不是一個好主意。例如,Apple建議使用controls be at least 44px across

我推薦使用UIButton類型UIButtonTypeCustom,將按鈕的圖像設置爲您的PNG,並註冊觸摸事件(see here for more on event handling)。然後,在您的操作方法中,您可以將觸摸的座標移出事件,並根據圖像的alpha測試這些座標,以查看是否應將其視爲「真實」觸摸。

1

另一種選擇可能是將按鈕分成多個矩形部分。

1

@Form正確使用'drawRect'來實現按鈕的自定義形狀。

不過還好method內或內部沒有按鈕觸摸考試使用的

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event; 

您可以創建按鈕,透明的,在一些地方的一面。

如果您不能使用自定義圖像按鈕(例如,如果你畫按鈕文本),你可以使用新的method繪製子視圖層次成圖像:在什麼

- (BOOL)drawViewHierarchyInRect:(CGRect)rect afterScreenUpdates:(BOOL)afterUpdates;