2

У меня есть три контроллера вида, которые являются частью UIScrollView. Я хочу иметь возможность прокручивать между тремя, хотя один из контроллеров представления имеет UIPanGestureRecognizer. Я использую этот распознаватель жестов, чтобы пользователь мог перетащить палец вверх и вниз, чтобы увеличить и уменьшить высоту прямоугольного 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.

Если кто-нибудь может сказать мне, как получить панорамирование/прокрутку в главном экране в моем приложении, это было бы здорово!

+0

Не могли бы вы поделиться ссылкой на свой проект (github/dropbox), чтобы я мог взглянуть на него? Трудно сказать, что такое эти бары и этикетки. – LuisCien

+0

Вот ссылка на весь проект в DropBox: https://www.dropbox.com/sh/9jqry6y2kr5kltr/VklDgKvoYe Надеюсь, это поможет! Кроме того, у меня возникли проблемы с получением всех трех контроллеров представления в представлении прокрутки, и я не уверен, правильно ли код в ScrollViewController.m, поэтому, если бы вы могли помочь мне в этом, это было бы здорово! – user2397282

+0

Мне не удалось открыть проект. Кажется, что проблема с файлом 'Bars.xcodeproj'. XCode не смог открыть его, и когда я открыл его с помощью TextEdit, он был пуст. – LuisCien

ответ

6

Хорошо, вот короткий ответ:

Вы должны использовать UIGestureRecognizer «s метод -requireGestureRecognizerToFail:.

А вот длинный ответ:

Вы должны сделать панорамирование жест распознаватель вашей точки зрения прокрутки, чтобы добиться успеха только если сковорода жест распознаватель из TimerViewController не удается. Однако этот жест (TimerViewController) должен быть только успешный, если начальный движение вертикальный. Если он горизонтальный, он должен потерпеть неудачу. Для этого мы должны подклассифицировать UIPanGestureRecognizer и изменить его в соответствии с этими потребностями. Вот что вы должны сделать:

  1. игнорировать все изменения, сделанные от моего предыдущего ответа
  2. Добавить VerticalPanGestureRecognizer в проект.
  3. Изменить TimerViewController как показано на рисунке.
  4. Изменить ScrollViewController как показано.

VerticalPanGestureRecognizer.h

#import <UIKit/UIKit.h> 
#import <UIKit/UIGestureRecognizerSubclass.h> 

@interface VerticalPanGestureRecognizer : UIPanGestureRecognizer 

@end 

VerticalPanGestureRecognizer.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]; 
} 

@end 

TimerViewController.h

// Your imports here 

@interface TimerViewController : UIViewController 

{ 
    // Your ivars here 
} 

// Add the following property 
@property (nonatomic, strong) UIPanGestureRecognizer *pan; 

// Your methods here 

@end 

TimerViewController.м

#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 

@end 

ScrollViewController.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 
} 

Этот новый подход прекрасно работает. Я протестировал его. Сообщите мне, если у вас есть дополнительные вопросы.

Cheers!

UPDATE

Чтобы ответить на вопрос, который вы размещены на комментариях, вот что вы должны сделать:

- (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]; 
} 

Опять же, я проверил его и он работает. Вам просто нужно добавить распознаватель жестов для баров

+0

Это работает очень хорошо спасибо! Тем не менее, жест Пан выглядит менее резорбирующим. Например, панель будет изменять высоту только после того, как вы отпустите экран, тогда как раньше она двигалась, когда ваш палец перемещался. Кроме того, если я перемещаю бары, вид прокрутки также перемещается. Возможно ли, чтобы вид прокрутки двигался только в том случае, если палец двигается больше в направлении x, чем в y, а для баров - наоборот? Я думаю, что это может привести к эффекту рабочего стола, который я искал. Кроме этого, большое спасибо! – user2397282

+1

@ пользователь2397282, пожалуйста, см. Мой обновленный ответ. Новый подход работает отлично. Пожалуйста, не забудьте принять ответ. – LuisCien

+0

Ничего себе !! Это точно, как я этого хотел! Я не хочу казаться грубым, но если бы я мог просто попросить одну небольшую помощь? В scrollViewController.m, как добавить мой третий контроллер представления, StopwatchViewController ?? Вы были фантастическими! Спасибо Вам большое!! – user2397282

Смежные вопросы