我有一個UIPickerView,當不使用時淡出到20%alpha。我希望用戶能夠觸摸選取器並使其淡入。響應toutentBegin在UIPickerView而不是UIView
如果我在主視圖上放置了touchesBegan方法,但只有在用戶觸摸視圖時才能使用。我嘗試了UIPickerView子類,並在那裏有一個touchesBegan,但它不起作用。
我猜這是與響應者鏈有關,但似乎無法解決。
我有一個UIPickerView,當不使用時淡出到20%alpha。我希望用戶能夠觸摸選取器並使其淡入。響應toutentBegin在UIPickerView而不是UIView
如果我在主視圖上放置了touchesBegan方法,但只有在用戶觸摸視圖時才能使用。我嘗試了UIPickerView子類,並在那裏有一個touchesBegan,但它不起作用。
我猜這是與響應者鏈有關,但似乎無法解決。
我一直在尋找解決這個問題一個多星期。即使您的問題已超過一年,我也會回答您,希望這可以幫助其他人。
對不起,如果我的語言不是很技術性,但我很新的Objective-C和iPhone的發展。
子類化UIpickerView是正確的做法。但是你必須重寫- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
方法。這是在您觸摸屏幕時調用的方法,它返回將對觸摸做出反應的視圖。換句話說,其方法將被調用的視圖。
UIPickerView有9個子視圖!在UIPickerView類中,- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
不會返回self
(這意味着您在子類中編寫的touchesBegan:withEvent:
不會被調用),但會返回一個子視圖,即索引4處的視圖(稱爲UIPickerTable的未記錄子類)。
訣竅是讓- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
方法返回self
所以你必須在touchesBegan:withEvent:
,touchesMoved:withEvent:
和touchesEnded:withEvent:
方法控制。
在這些方法中,爲了保持UIPickerView的標準功能,你必須記得再次調用它們,但是在UIPickerTable子視圖上。
我希望這是有道理的。我現在不能寫代碼,只要我在家我會編輯這個答案並添加一些代碼。
下面是一些代碼,你想要做什麼:
@interface TouchDetectionView : UIPickerView {
}
- (UIView *)getNextResponderView:(NSSet *)touches withEvent:(UIEvent *)event;
@end
@implementation TouchDetectionView
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UIView * hitTestView = [self getNextResponderView:touches withEvent:event];
[hitTestView touchesBegan:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UIView * hitTestView = [self getNextResponderView:touches withEvent:event];
[hitTestView touchesMoved:touches withEvent:event];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UIView * hitTestView = [self getNextResponderView:touches withEvent:event];
[hitTestView touchesEnded:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
UIView * hitTestView = [self getNextResponderView:touches withEvent:event];
[hitTestView touchesCancelled:touches withEvent:event];
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
return self;
}
- (UIView *)getNextResponderView:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch * touch = [touches anyObject];
CGPoint point = [touch locationInView:self];
UIView * hitTestView = [super hitTest:point withEvent:event];
return (hitTestView == self) ? nil : hitTestView;
}
兩個以上的答案是非常有益的,但我有嵌套一個UIScrollView內一個UIPickerView。當GUI出現時,我還在屏幕上不斷渲染其他地方。問題是,在以下情況下,UIPickerView未完全更新:未選擇的行被輕敲,移動選擇器以使兩行橫跨選擇區域,或拖動一行但手指滑到UIPickerView之外。然後直到移動UIScrollView,拾取器立即更新。這個結果很難看。
問題的原因:我的持續渲染保持了UIPickerView的動畫獲取完成所需的CPU週期,因此顯示正確的當前選擇。我的解決方案 - 這是可行的 - 是這樣的:在UIPickerView的touchesEnded:withEvent:
中,執行一些暫停我的渲染的一段時間。下面的代碼:
#import "SubUIPickerView.h"
@implementation SubUIPickerView
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
[pickerTable touchesBegan:touches withEvent:event];
}
- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
[pickerTable touchesMoved:touches withEvent:event];
}
- (void) touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
[singleton set_secondsPauseRendering:0.5f]; // <-- my code to pause rendering
[pickerTable touchesEnded:touches withEvent:event];
}
- (void) touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event
{
[pickerTable touchesCancelled:touches withEvent:event];
}
- (UIView*) hitTest:(CGPoint)point withEvent:(UIEvent*)event
{
if (CGRectContainsPoint(self.bounds, point))
{
if (pickerTable == nil)
{
int nSubviews = self.subviews.count;
for (int i = 0; i < nSubviews; ++i)
{
UIView* view = (UIView*) [self.subviews objectAtIndex:i];
if ([view isKindOfClass:NSClassFromString(@"UIPickerTable")])
{
pickerTable = (UIPickerTable*) view;
break;
}
}
}
return self; // i.e., *WE* will respond to the hit and pass it to UIPickerTable, above.
}
return [super hitTest:point withEvent:event];
}
@end
,然後頭,SubUIPickerView.h:
@class UIPickerTable;
@interface SubUIPickerView : UIPickerView
{
UIPickerTable* pickerTable;
}
@end
就像我說的,這工作。渲染暫停額外的1/2秒(它已經暫停,當你滑動UIScrollView)允許UIPickerView動畫完成。使用NSClassFromString()意味着你沒有使用任何未公開的API。與響應者鏈混合是沒有必要的。感謝checcco和Tylerc230幫助我想出我自己的解決方案!
集canCancelContentTouches和家長以NO的delaysContentTouches,這爲我工作
感謝它的工作:) – ArunGJ 2011-06-01 08:03:49
這個代碼似乎工作,但如果直接圍繞揀貨機輪在框架上發生的觸摸。這樣做似乎會導致無限循環調用getNextResponderView:withEvent:方法。 – pistachionut 2011-06-05 21:33:47