以下是我想做的
我所拥有的是ScrollView001
和ScrollView002
。布局如下。
- View
- ScrollView001
- ScrollView002
ScrollView002
,全屏显示,因此ScrollView001
明显低于ScrollView002
。我这样做是为了达到某种效果,即当我滚动
ScrollView002
时,我想滚动ScrollView001
但速度较低,这已经成功完成了,但是问题是当我尝试单击Car for Gallery时,它没有单击。如果我简单地隐藏ScrollView002
,则图库正常运行。知道如何使基础视图可点击吗?
对于Gallery,我使用的是UICollectionView。
编辑1
滚动之后,我想要下面类似的内容。
最佳答案
Fahim Parkar,
不知道这是您想要的还是我理解不正确的:)我相信您可以利用hitTest:
来解决它:)
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *hitView = [super hitTest:point withEvent:event];
if (hitView && CGRectContainsPoint(ScrollView001.frame, point)) {
return ScrollView001;
}
return hitView;
}
怎么运行的
每当您点击屏幕时,覆盖整个屏幕的scorllView002都会捕获触摸:)因此,将调用ScrollView002的hitTest :)如果无论如何您都可以访问ScrollView001(这应该很容易,因为它们在同一ViewController中),您可以验证触摸点是否在ScrollView001中,如果是,则可以将touchView作为ScrollView001返回。
结果是ScrollView001将得到触摸,而不是ScrollView002 :)
编辑
正如您提到的,您确实尝试了我的方法,但它仍然对您有用:)我决定自己试一下,并意识到它绝对可以用。请看一看 :)
我相信这就是您的情况:)我在彼此之上添加了两个scrollViews。小的scrollView(myScrollView)在较大的全屏scrollView(TestScrollView)下方。
现在,当我点击屏幕时,myScrollView无法触摸到:)
但这就是我们需要的,所以这就是我所做的:)
我创建了一个名为TestScrollView的ScrollView子类,并为顶部的scrollView设置了它:)
TestScrollView.swift
import UIKit
class TestScrollView: UIScrollView {
var scrollViewBehind : UIView!
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func drawRect(rect: CGRect) {
// Drawing code
}
*/
override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
let hitView = super.hitTest(point, withEvent: event)
if hitView != nil && CGRectContainsPoint(scrollViewBehind.frame,point) {
return scrollViewBehind
}
return hitView;
}
}
我创建了一个名为scrollViewBehind的变量,以保存情节提要中位于它后面的smallerScrollView的引用(我非常清楚,拥有像这样的引用以在后面查看不是一个很好的设计:),但是我相信它足以解释逻辑)
这是我的ViewController代码:)
import UIKit
class ViewController: UIViewController,UIGestureRecognizerDelegate {
@IBOutlet var myScrollView: UIScrollView!
@IBOutlet var testScrollView: TestScrollView!
override func viewDidLoad() {
super.viewDidLoad()
testScrollView.scrollViewBehind = myScrollView
let tap = UITapGestureRecognizer(target: self, action: Selector("handleTap"))
tap.delegate = self
myScrollView .addGestureRecognizer(tap)
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func handleTap(){
print("Me tapped")
}
}
编辑
根据我们的讨论,我意识到您有一个collectionView作为较小的ScrollView上的子视图,它本身位于全屏scrollView的后面:)
我保留了上面的答案,就像在Swift中一样,它还解释了如何处理hitTest将控件从上方的scrollView移交给下方的scrollView。虽然它不能完全解决您的问题,但可以给其他人足够的解决方法:)
现在根据您的问题,当用户点击时,上面的scrollView会捕获触摸,并且应该将触摸转发到较小的scrollView顶部的collectionView :)
因此,按照上述相同的方法进行操作:)我创建了ScrollView的子类,让其调用TestScrollView(根据您的要求,答案在目标C中)
TestScrollView.h
#import <UIKit/UIKit.h>
@interface TestScrollView : UIScrollView
@property (nonatomic,strong) UICollectionView *collectionViewBehind;
@property (nonatomic,strong) UIScrollView *scrollViewBehind;
@end
TestScrollView.m
#import "TestScrollView.h"
@implementation TestScrollView
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
UIView *hitView = [super hitTest:point withEvent:event];
CGPoint myPoint = [self convertPoint:point toView:self.scrollViewBehind];
if (hitView != nil && CGRectContainsPoint(self.scrollViewBehind.frame,point)) {
return self.collectionViewBehind;
}
return hitView;
}
@end
如果您正确地注意到TestScrollView具有两个属性,即collectionViewBehind和scrollViewBehind,则用于保存以下scrollView和collectionView的引用:)
上面已经解释了hitTest的作用。虽然,它所做的只是检查接触点是否在scrollView内,它返回collectionView。这样做是将触摸事件传输到collectionView。
现在转到情节提要中,选择topScrollView并将其类设置为TestScrollView。
在加载这些scrollViews的ViewController中,
#import "ViewController.h"
#import "TestScrollView.h"
@interface ViewController ()<UICollectionViewDelegate,UICollectionViewDataSource,UIGestureRecognizerDelegate>
@property (strong, nonatomic) IBOutlet TestScrollView *testScrollView;
@property (strong, nonatomic) IBOutlet UICollectionView *collectionView;
@property (strong, nonatomic) IBOutlet UIScrollView *scrollView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.testScrollView.collectionViewBehind = self.collectionView;
self.testScrollView.scrollViewBehind = self.scrollView;
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"test"];
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
tapGesture.numberOfTapsRequired = 1;
tapGesture.delegate = self;
[self.collectionView addGestureRecognizer:tapGesture];
// Do any additional setup after loading the view, typically from a nib.
}
是的,如果您注意到了,没错,我正在向UICollectionView添加TapGesture识别器。尽管我们设法将触摸切换到UICollectionView,但是我们注意到didSelectItemAtIndexPath从未触发。因此,这是一个小工作。
尽管在这种情况下,在此处不建议将GestureRecognizer添加到collectionView中,但还是可以的,因为我们仅覆盖了一次轻敲,所有其他手势都保持不变。
因此,现在每当用户点击UICollectionView的gestureRecognizer上方的scrollView触发器并调用我们的选择器时:)现在,您要做的就是找出被点击的单元格并以编程方式选择它:)
-(void)handleTap:(UIGestureRecognizer *)recognizer {
[self collectionView:self.collectionView didSelectItemAtIndexPath:[self.collectionView indexPathForItemAtPoint:[recognizer locationInView:self.collectionView]]];
}
终于享受在
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
NSLog(@"Hi indexPath tapped is %@",indexPath);
}
最后,这是项目的链接:https://github.com/sandeeplearner/UnderlayingClickableViews