我有一个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