以下是我想做的

ios - 通过UIScrollView使基础 View 可单击-LMLPHP

我所拥有的是ScrollView001ScrollView002。布局如下。

- View
  - ScrollView001
  - ScrollView002


ScrollView002,全屏显示,因此ScrollView001明显低于ScrollView002

我这样做是为了达到某种效果,即当我滚动ScrollView002时,我想滚动ScrollView001但速度较低,这已经成功完成了,但是问题是当我尝试单击Car for Gallery时,它没有单击。如果我简单地隐藏ScrollView002,则图库正常运行。

知道如何使基础视图可点击吗?

对于Gallery,我使用的是UICollectionView。



编辑1

滚动之后,我想要下面类似的内容。

ios - 通过UIScrollView使基础 View 可单击-LMLPHP

最佳答案

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

编辑

正如您提到的,您确实尝试了我的方法,但它仍然对您有用:)我决定自己试一下,并意识到它绝对可以用。请看一看 :)

ios - 通过UIScrollView使基础 View 可单击-LMLPHP

我相信这就是您的情况:)我在彼此之上添加了两个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

10-07 16:07