以下是我想要的内容
我所拥有的是ScrollView001
& ScrollView002
。布局如下。
- View
- ScrollView001
- ScrollView002
ScrollView002
全屏,因此ScrollView001
明显低于ScrollView002
。
我这样做有一些效果,即当我滚动ScrollView002
时,我想滚动ScrollView001
但速度较慢,我已成功完成但问题是当我尝试点击Car时对于Gallery,它不是点击。如果我只是隐藏ScrollView002
,那么画廊就像往常一样。
任何想法如何将底层视图设为可点击?
对于Gallery,我使用的是UICollectionView。
滚动后,我想要下面的内容。
答案 0 :(得分: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 :)
修改强>
正如你所提到的,你确实尝试过我的方法,它仍然为你工作:)我决定自己动手,并意识到它的工作非常好。请看看:))
我相信这就是你的情况:)我已经在彼此的顶部添加了两个scrollView。小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的变量来保存在storyboard中它后面的smallScrollView的引用(我非常清楚,持有像这样的引用来查看背后不是一个很棒的设计:)但我相信它是好的足以解释逻辑)
这是我的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")
}
}
修改强>
根据我们的讨论,我意识到你在一个较小的ScrollView上有一个collectionView作为一个子视图,它本身就是全屏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。
现在转到storyboard选择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
答案 1 :(得分:0)
试试这个 拿按钮作为你的车的背景然后是汽车的imageview,这样它可以点击..我认为我没有必要让视图可以看到
答案 2 :(得分:0)
您应该在上方的scrollview上添加tapgesturerecognizer
,然后您可以处理类似的内容,
- (void)handleTap:(UITapGestureRecognizer *)recognizer {
// First get the tap gesture recognizers's location in the entire
// view's window
CGPoint tapPoint = [recognizer locationInView:self.view];
// Then see if it falls within one of your below images' frames
for (UIImageView* image in relevantImages) {
// If the image's coordinate system isn't already equivalent to
// self.view, convert it so it has the same coordinate system
// as the tap.
CGRect imageFrameInSuperview = [image.superview convertRect:image toView:self.view]
// If the tap in fact lies inside the image bounds,
// perform the appropriate action.
if (CGRectContainsPoint(imageFrameInSuperview, tapPoint)) {
// Perhaps call a method here to react to the image tap
[self reactToImageTap:image];
break;
}
}
}
您可以考虑使用your car
或代替imageview。
希望这会有所帮助:)