如何正确使用swipeWithEvent来导航webView,Obj-C [英] How to properly use swipeWithEvent to navigate a webView, Obj-C

查看:218
本文介绍了如何正确使用swipeWithEvent来导航webView,Obj-C的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过使用事件swipeWithEvent来实现在我的webView中导航回第四个的能力。但是,我不知道我怎么想使用这个。



我有一个主要的webView,以及两个导航回到第四个的方法。这里的一个大问题是,我不知道如何写这个问题。我只需要知道如何识别我的webView上的滑动手势,并调用我的两个方法。类似于Safari,Google Chrome和Mozilla Firefox。非常感谢。



EDIT
我实施了这些方法,允许我向后和向前滑动。

   - (void)swipeWithEvent:(NSEvent *)event {
NSLog(@Swipe With Event);
CGFloat x = [event deltaX];
// CGFloat y = [event deltaY];

if(x!= 0){
(x> 0)? [self goBack:self]:[self goForward:self];
}
}


- (BOOL)recognizeTwoFingerGestures
{
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
return [defaults boolForKey:@AppleEnableSwipeNavigateWithScrolls];
}

- (void)beginGestureWithEvent:(NSEvent *)event
{
if(![self recognizeTwoFingerGestures])
return;

NSSet * touches = [event touchesMatchingPhase:NSTouchPhaseAny inView:nil];

self.twoFingersTouches = [[NSMutableDictionary alloc] init];

(NSTouch * touch in touches){
[twoFingersTouches setObject:touch forKey:touch.identity];
}
}

- (void)endGestureWithEvent:(NSEvent *)event
{
if(!twoFingersTouches)

NSSet * touches = [event touchesMatchingPhase:NSTouchPhaseAny inView:nil];

// release twoFingersTouches early
NSMutableDictionary * beginTouches = [twoFingersTouches copy];
self.twoFingersTouches = nil;

NSMutableArray * magnitudes = [[NSMutableArray alloc] init];

(NSTouch * touch in touches)
{
NSTouch * beginTouch = [beginTouches objectForKey:touch.identity];

if(!beginTouch)continue;

float magnitude = touch.normalizedPosition.x - beginTouch.normalizedPosition.x;
[magnitudes addObject:[NSNumber numberWithFloat:magnitude]];
}

//需要至少两个点
if([magnitudes count]< 2)return;

float sum = 0;

for(NSNumber * magnitude in magnitude)
sum + = [float floatValue];

//在Lion中处理自然方向
BOOL naturalDirectionEnabled = [[[NSUserDefaults standardUserDefaults] valueForKey:@com.apple.swipescrolldirection] boolValue];

if(naturalDirectionEnabled)
sum * = -1;

//看看绝对和是否足够长,可以认为是一个完整的手势
float absoluteSum = fabsf(sum);

if(absoluteSum< kSwipeMinimumLength)return;

//处理实际滑动
if(sum> 0)
{
[self goForward:self];
} else
{
[self goBack:self];
}


}

代码没有做任何事情。

解决方案

对于现代操作系统(Lion及以上版本),这是一个那些我如何做Y与Y?问题的答案是不使用Y。



-swipeWithEvent:用于实现10.6-风格的触控板滑动,其中屏幕上的内容不随着滑动移动。大多数Mac跟踪轨没有配置为允许这种刷卡了;在Trackpad pref窗格中的在页面之间滑动首选项必须设置为用三根手指滑动,以使其可用,这既不是默认设置也不是用户更改的常见设置。



狮子式的流体挥击而不是滚动事件。您的Xcode SDK中的PictureSwiper示例项目是一个很好的开始,但作为概述,您可以这样做:


  1. 如果你只需要支持Mountain Lion,在历史堆栈模式中使用 NSPageController ,并跳过剩下的这个混乱。


  2. 这是一团糟;


  3. 不要说我没有警告你。


  4. 覆盖<$ c $

    c> -wantsScrollEventsForSwipeTrackingOnAxis:为适当的轴返回 YES 。如果您使用Safari样式的返回/前进导航,则 NSEventGestureAxisHorizo​​ntal


  5. 呼吸;这是一个doozy。


  6. 在您的自定义视图中覆盖 -scrollWheel:。您的覆盖应调用 -trackSwipeEventWithOptions:dampenAmountThresholdMin:max:usingHandler:。大致来说,阻尼量阈值最小值是用户可以向左滑动的数据的查看量,最大值是其可以向右滑动的数量。处理程序是一个块,当用户刷卡时重复调用;它应该:


    1. 放置一个NSImageView,其中包含您要返回/前进到网页视图的页面的屏幕截图。

    2. 移动Web视图以匹配用户的移动。注意,gestureAmount参数与阻尼量阈值一样,是(分数和可能为负数)项目数;您必须乘以视图宽度才能正确定位网络视图。

    3. 如果手势阶段是NSEventPhaseEnded,请评估gestureAmount以确定用户是否完成了手势。如果他们没有,动画的web视图回到原地;


正如你所看到的,实际上实现处理程序非常复杂,我甚至没有描述所有的细节。即使有所有这些细节,一个高度熟练的程序员可能需要花几天时间得到这个正确的。 10.7 SDK中的PictureSwiper示例是一个很好的开始。 (10.8版本的PictureSwiper使用 NSPageController ,就像你应该做的那样。)


I want to implement the ability to navigate back and fourth in my webView by using the Event swipeWithEvent. However, I have no idea how I am suppose to use this.

I have one main webView, and two methods that navigate back and fourth. A big problem here is that I'm not exactly sure how to write this question. I just need to know how to recognize swipe gestures on my webView and call my two methods. Similar to what Safari, Google Chrome, and Mozilla Firefox do. Thanks.

EDIT I have implemented these methods which are suppose to allow me to swipe back and forward.

- (void)swipeWithEvent:(NSEvent *)event {
    NSLog(@"Swipe With Event");
    CGFloat x = [event deltaX];
    //CGFloat y = [event deltaY];

    if (x != 0) {
        (x > 0) ? [self goBack:self] : [self goForward:self];
    }
}


-(BOOL)recognizeTwoFingerGestures
{
    NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
    return [defaults boolForKey:@"AppleEnableSwipeNavigateWithScrolls"];
}

- (void)beginGestureWithEvent:(NSEvent *)event
{
    if (![self recognizeTwoFingerGestures])
        return;

    NSSet *touches = [event touchesMatchingPhase:NSTouchPhaseAny inView:nil];

    self.twoFingersTouches = [[NSMutableDictionary alloc] init];

    for (NSTouch *touch in touches) {
        [twoFingersTouches setObject:touch forKey:touch.identity];
    }
}

- (void)endGestureWithEvent:(NSEvent *)event
{
    if (!twoFingersTouches) return;

    NSSet *touches = [event touchesMatchingPhase:NSTouchPhaseAny inView:nil];

    // release twoFingersTouches early
    NSMutableDictionary *beginTouches = [twoFingersTouches copy];
    self.twoFingersTouches = nil;

    NSMutableArray *magnitudes = [[NSMutableArray alloc] init];

    for (NSTouch *touch in touches)
    {
        NSTouch *beginTouch = [beginTouches objectForKey:touch.identity];

        if (!beginTouch) continue;

        float magnitude = touch.normalizedPosition.x - beginTouch.normalizedPosition.x;
        [magnitudes addObject:[NSNumber numberWithFloat:magnitude]];
    }

    // Need at least two points
    if ([magnitudes count] < 2) return;

    float sum = 0;

    for (NSNumber *magnitude in magnitudes)
        sum += [magnitude floatValue];

    // Handle natural direction in Lion
    BOOL naturalDirectionEnabled = [[[NSUserDefaults standardUserDefaults] valueForKey:@"com.apple.swipescrolldirection"] boolValue];

    if (naturalDirectionEnabled)
        sum *= -1;

    // See if absolute sum is long enough to be considered a complete gesture
    float absoluteSum = fabsf(sum);

    if (absoluteSum < kSwipeMinimumLength) return;

    // Handle the actual swipe
    if (sum > 0)
    {
        [self goForward:self];
    } else
    {
        [self goBack:self];
    }


}

However, this code isn't doing anything. It doesn't appear to be getting called at all.

解决方案

For modern OSes (Lion and newer), this is one of those "How do I do X with Y?" questions where the answer is "Don't use Y."

-swipeWithEvent: is used to implement 10.6-style trackpad swiping, where the content on the screen doesn't move with the swipe. Most Mac trackpads are not configured to allow this kind of swiping anymore; the "Swipe between pages" preference in Trackpad pref pane has to be set to "swipe with three fingers" for it to be available, and that's neither the default setting nor a common setting for users to change.

Lion-style "fluid swipes" instead come in as scroll events. The PictureSwiper sample project in your Xcode SDK is a good place to start, but as an overview, here's what you do:

  1. If you only need to support Mountain Lion, use an NSPageController in history stack mode and skip the rest of this mess.

  2. And it is a mess; you may want to consider only supporting fluid swipes on Mountain Lion.

  3. Don't say I didn't warn you.

  4. Create a custom view that is a superview to whatever views you want to be swipeable.

  5. Override -wantsScrollEventsForSwipeTrackingOnAxis: to return YES for the appropriate axis. If you're doing Safari-style back/forward navigation, that's NSEventGestureAxisHorizontal.

  6. Take a deep breath; this one's a doozy.

  7. Override -scrollWheel: in your custom view. Your override should call -trackSwipeEventWithOptions:dampenAmountThresholdMin:max:usingHandler:. Roughly, the dampen amount threshold minimum is how many viewfuls of data the user can swipe to the left, and the maximum is how many they can swipe to the right. The handler is a block that's called repeatedly as the user swipes; it should:

    1. Place an NSImageView with a screenshot of the page you're going back/forward to behind the web view.
    2. Move the web view to match the user's movements. Note that the gestureAmount parameter is, like the dampen amount thresholds, a (fractional and possibly negative) number of items; you have to multiply it by the view width to correctly position the web view.
    3. If the gesture phase is NSEventPhaseEnded, evaluate the gestureAmount to determine if the user completed the gesture. If they didn't, animate the web view back into place; if they did, put it back in place with no animation and navigate to the new page.

As you can see, actually implementing the handler is very involved, and I haven't even described all of the specifics. Even with all of these details, a highly skilled programmer will probably have to spend a few days getting this just right. The PictureSwiper sample in the 10.7 SDK is a good place to start. (The 10.8 version of PictureSwiper uses NSPageController. Just like you ought to do.)

这篇关于如何正确使用swipeWithEvent来导航webView,Obj-C的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆