我有三个视图控制器,它们是UIScrollView的一部分。我希望能够在三个视图之间滑动,尽管其中一个视图控制器有一个UIPanGestureRecognizer。我使用这个pan手势识别器,允许用户上下拖动手指来增加和降低矩形UIView的高度。因此,这个UIPanGestureRecognizer只需要知道向上/向下的摇摄,滚动视图可以使用水平摇摄。
这方面的一个例子是,就像主屏幕一样;你可以左右滑动,也可以向下滑动以获得聚光灯。我想要这种机制。
这是我的密码:
- (void)pan:(UIPanGestureRecognizer *)aPan; // When pan guesture is recognised
{
CGPoint location = [aPan locationInView:self.view]; // Location of finger on screen
CGRect secondRect = CGRectMake(210.0, 45.0, 70.0, 325.0); // Rectangles of maximimum bar area
CGRect minuteRect = CGRectMake(125.0, 45.0, 70.0, 325.0);
CGRect hourRect = CGRectMake(41.0, 45.0, 70.0, 325.0);
if (CGRectContainsPoint(secondRect, location)) { // If finger is inside the 'second' rectangle
CGPoint currentPoint = [aPan locationInView:self.view];
currentPoint.y -= 80; // Make sure animation doesn't go outside the bars' rectangle
if (currentPoint.y < 0) {
currentPoint.y = 0;
}
else if (currentPoint.y > 239) {
currentPoint.y = 239;
}
currentPoint.y = 239.0 - currentPoint.y;
CGFloat pointy = currentPoint.y - fmod(currentPoint.y, 4.0);
[UIView animateWithDuration:0.01f // Animate the bars to rise as the finger moves up and down
animations:^{
CGRect oldFrame = secondBar.frame;
secondBar.frame = CGRectMake(oldFrame.origin.x, (oldFrame.origin.y - (pointy - secondBar.frame.size.height)), oldFrame.size.width, (pointy));
}];
CGFloat result = secondBar.frame.size.height - fmod(secondBar.frame.size.height, 4.0);
secondInt = (result / 4.0); // Update labels with new time
self->secondLabel.text = [NSString stringWithFormat:@"%02d", secondInt];
}对于三个独立的矩形UIViews,代码基本上是重复的。
如果有人能告诉我如何让主屏幕式的摇摄/滑动进入我的应用程序,那就太好了!!
发布于 2013-11-14 20:36:47
好吧,下面是简短的答案:
您必须使用UIGestureRecognizer的方法-requireGestureRecognizerToFail:。
,这是一个很长的答案:
如果的pan手势识别器失败,您必须使滚动视图的pan手势识别器成功。然而,这个手势(TimerViewController的手势)应该只有当初始运动垂直时才能成功。如果是水平移动,则应该失败。要实现这一点,我们必须对UIPanGestureRecognizer进行子类化,并对其进行修改以满足这些需求。下面是您必须做的事情:
VerticalPanGestureRecognizer添加到项目中。TimerViewController。ScrollViewController。VerticalPanGestureRecognizer.h
#import <UIKit/UIKit.h>
#import <UIKit/UIGestureRecognizerSubclass.h>
@interface VerticalPanGestureRecognizer : UIPanGestureRecognizer
@endVerticalPanGestureRecognizer.m
#import "VerticalPanGestureRecognizer.h"
@interface VerticalPanGestureRecognizer ()
@property (nonatomic, assign) CGPoint origLoc;
@end
@implementation VerticalPanGestureRecognizer
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
self.origLoc = [[touches anyObject] locationInView:self.view.superview];
[super touchesBegan:touches withEvent:event];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
if (self.state == UIGestureRecognizerStatePossible) {
CGPoint loc = [[touches anyObject] locationInView:self.view.superview];
CGFloat deltaX = fabs(loc.x - self.origLoc.x);
CGFloat deltaY = fabs(loc.y - self.origLoc.y);
if (deltaY < deltaX)
self.state = UIGestureRecognizerStateFailed;
}
[super touchesMoved:touches withEvent:event];
}
@endTimerViewController.h
// Your imports here
@interface TimerViewController : UIViewController
{
// Your ivars here
}
// Add the following property
@property (nonatomic, strong) UIPanGestureRecognizer *pan;
// Your methods here
@endTimerViewController.m
#import "TimerViewController.h"
#import "VerticalPanGestureRecognizer.h"
@implementation TimerViewController
@synthesize pan = _pan;
// prefersStatusBarHidden method here
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil // Initialise view controller
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Instantiate the pan gesture as "VerticalPanGestureRecognizer"
self.pan = [[VerticalPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)]; // Create recogniser for a pan guesture
self.pan.maximumNumberOfTouches = self.pan.minimumNumberOfTouches = 1;
[self.view addGestureRecognizer:self.pan];
}
return self;
}
// The rest of your code here
@endScrollViewController.m
- (void)viewDidLoad
{
// Your code here
TimerViewController *tvc = [[TimerViewController alloc]init];
CGRect frame = tvc.view.frame;
frame.origin.x = 320;
tvc.view.frame = frame;
// Add the following line
[self.scrollView.panGestureRecognizer requireGestureRecognizerToFail:tvc.pan];
[self addChildViewController:tvc];
[self.scrollView addSubview:tvc.view];
[tvc didMoveToParentViewController:self];
// More code here
}这种新方法非常有效。我测试过了。如果你还有其他问题,请告诉我。
干杯!
更新
为了回答你在评论上发布的问题,下面是你必须做的事情:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
BarsViewController *bvc = [[BarsViewController alloc]init];
[self addChildViewController:bvc];
[self.scrollView addSubview:bvc.view];
[bvc didMoveToParentViewController:self];
TimerViewController *tvc = [[TimerViewController alloc]init];
CGRect frame = tvc.view.frame;
frame.origin.x = 320;
tvc.view.frame = frame;
[self.scrollView.panGestureRecognizer requireGestureRecognizerToFail:tvc.pan];
[self addChildViewController:tvc];
[self.scrollView addSubview:tvc.view];
[tvc didMoveToParentViewController:self];
StopwatchViewController *svc = [[StopwatchViewController alloc] init];
frame = svc.view.frame;
frame.origin.x = 320*2;
svc.view.frame = frame;
[self addChildViewController:svc];
[self.scrollView addSubview:svc.view];
[svc didMoveToParentViewController:self];
self.scrollView.contentSize = CGSizeMake(320*3, self.view.frame.size.height);
self.scrollView.pagingEnabled = YES;
[self.scrollView setShowsHorizontalScrollIndicator:NO];
}再次,我测试了它,它是有效的。您只需为栏添加手势识别器即可。
https://stackoverflow.com/questions/19985654
复制相似问题