问题描述:

I just trying to get to QLPreviewController.view. Indeed, I want to catch a tap event on its view to show/hide toolbar etc. I am trying:

QLPreviewController* qlpc = [QLPreviewController new];

qlpc.delegate = self;

qlpc.dataSource = self;

qlpc.currentPreviewItemIndex=qlIndex;

[navigator pushViewController:qlpc animated:YES];

qlpc.title = [path lastPathComponent];

[qlpc setToolbarItems:[NSArray arrayWithObjects:self.dirBrowserButton,self.space, self.editButton, self.btnSend, nil] animated:YES];

UITapGestureRecognizer* gestTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showControls:)];

gestTap.cancelsTouchesInView=NO;

[qlpc.view addGestureRecognizer:[gestTap autorelease]];

[qlpc release];

And nothing happens

If I attach UITapRecognizer onto navigationController.view, it fires only if I touch toolbar/navbar. UISwipeGestureRecognizer works fine in that case.

I tried to attach a transparent overlay view and add gesture recognizers on it, but no luck.

Well, I saw some apps that implements such a feature so obviously it is possible, but how?

Sorry, I googled all day long and didn't find any solution. Please, help me.

网友答案:

I found none of the answers here to work, but the one that did for me was to subclass QLPreviewController and override viewDidAppear as so:

- (void)viewDidAppear:(BOOL)animated
{ 
    UITapGestureRecognizer *gestTap  = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showControls:)];
    gestTap.cancelsTouchesInView = NO;
    [self.view addGestureRecognizer:[gestTap autorelease]];
}
网友答案:

With your solution, does the QLPreviewController's view still recieve touches? I've tried to do something similar (I'm stealing the view from QLPreviewController to use it) and it looks like my overlay view doesn't let anything pass trough to the view lying behind it.

网友答案:

I have been working on this problem today and the suggestion to override -(void)contentWasTappedInPreviewContentController:(id)item {} is close but when you do you mess with the preview controllers handling.

So I stopped overriding that method and instead created a RAC signal that fires whenever the method is called. This does not mess with the default behavior of QL. I am doing it in a subclass of the QLPreviewController but that shouldn't be necessary.

I have a property on my class:

 @property RACSignal *contentTapped;

Then in my init method of my subclass of QLPreviewController:

_contentTapped = [self   rac_signalForSelector:@selector(contentWasTappedInPreviewContentController:)];

Now in another class or even internally you can use the signal like this:

previewController.contentTapped subscribeNext:^(id x) {
    // Put your handler here!
}];
网友答案:

Ok, solution is very simple. just added an overlay view onto keyWindow. Attached gesture recognizers onto overlay and it works.

        QLPreviewController* qlpc = [QLPreviewController new];
    qlpc.delegate = self;
    qlpc.dataSource = self;
    qlpc.currentPreviewItemIndex=qlIndex;
    [navigator pushViewController:qlpc animated:YES];
    qlpc.title = [path lastPathComponent];
    UIView* overlay = [[[UIView alloc] initWithFrame:navigator.view.bounds] autorelease];
    [[[UIApplication sharedApplication] keyWindow] addSubview:overlay];
    [overlay setNeedsDisplay];
    [qlpc setToolbarItems:[NSArray arrayWithObjects:self.dirBrowserButton,self.space, self.editButton, self.btnSend, nil] animated:YES];
    UITapGestureRecognizer* gestTap  = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showControls:)];
    gestTap.cancelsTouchesInView=NO;
    [overlay addGestureRecognizer:[gestTap autorelease]];
    [qlpc release];
网友答案:

Here is my solution (to use KVO), where I'm monitoring navigation bar status - and showing toolbar when needed (it seems that it hides toolbar by itself when tapped)

#define kNavigationBarKeyPath @"navigationBar.hidden"

static void * const NavigationBarKVOContext = (void*)&NavigationBarKVOContext;

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [self.navigationController setToolbarHidden:NO];
    [self.navigationController addObserver:self forKeyPath:kNavigationBarKeyPath options:NSKeyValueObservingOptionPrior context:NavigationBarKVOContext];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];

    [self.navigationController removeObserver:self forKeyPath:kNavigationBarKeyPath];
}

And

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ( context == NavigationBarKVOContext ) {
        BOOL prior = [change[NSKeyValueChangeNotificationIsPriorKey] boolValue];
        if ( prior && self.navigationController.toolbarHidden ) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.navigationController setToolbarHidden:NO animated:YES];
            });
        }
    }
}
网友答案:

Subclass QLPreviewController and then override

-(void)contentWasTappedInPreviewContentController:(id)item {}

Thats its !

相关阅读:
Top