【问题标题】:Pinch to zoom respecting pinch location (Like in Safari)捏合以缩放尊重捏合位置(如在 Safari 中)
【发布时间】:2013-12-06 11:23:24
【问题描述】:

所以我实际上有一张我想水平缩放的图像,但也能够尊重捏合的位置。所以如果你在左边捏,它会放大到左边。理想情况下,你捏的点会留在你的手指上。

我的情况更具体一些,我在图表上绘制数据,因此我将处理一组数据并获取一个子集。但是,我确信数学是相似的。 (但是,我不能像我发现的大多数示例那样只使用仿射变换)

有什么想法吗?

【问题讨论】:

  • 你是否在 iOS 上使用 core-plot (code.google.com/p/core-plot)?
  • 是的......默认的 pinchzoom 东西似乎放大了我的整个图表(就像整个轴一样!我只想缩放 x 轴,但更多的是它上面的数据......作为盛大计划是将聚集的数据转化为更多的原始数据)

标签: ios math nsarray core-plot pinchzoom


【解决方案1】:

默认的捏合手势处理程序围绕手势点缩放图形。使用绘图空间委托将缩放限制在一个轴上。

【讨论】:

  • 但这不只是缩放图形,而不是真正重绘它吗?
  • 它会在您缩放时重绘图表。
  • 所以实现- (BOOL)plotSpace:(CPTPlotSpace *)space shouldScaleBy:(CGFloat)interactionScale aboutPoint:(CGPoint)interactionPoint然后做什么?
  • 但是,这更像是缩放而不是数据操作。理想情况下,数据 x 轴将根据需要重新绘制更多次要/主要点。
  • 将缩放限制为单轴的更好的委托方法是-plotSpace:willChangePlotRangeTo:forCoordinate:。除了调整绘图范围外,您还可以随着范围的变化更新代理中的轴标签属性。
【解决方案2】:

你使用 UIScrollView 吗?据我所知,您将免费获得此行为。

【讨论】:

  • 不——我不知道。我正在使用CorePlot 绘制数据。所以真的要放大一个数组,所以需要找到新的开始索引和新的长度,这样我就可以在我的数组上调用subarrayWithRange
【解决方案3】:

我为标准UIViews 构建了以下解决方案,其中UIScrollViewCGAffineTransform 缩放不合适,因为我不希望视图的子视图倾斜。我还将它与 CorePlot 折线图一起使用。

缩放以用户开始捏合的点为中心。

这是一个简单的实现:

@interface BMViewController ()

@property (nonatomic, assign) CGFloat pinchXCoord; // The point at which the pinch occurs
@property (nonatomic, assign) CGFloat minZoomProportion; // The minimum zoom proportion allowed. Used to control minimum view width
@property (nonatomic, assign) CGFloat viewCurrentXPosition; // The view-to-zoom’s frame’s current origin.x value.
@property (nonatomic, assign) CGFloat originalViewWidth, viewCurrentWidth; // original and current frame width of the view.

@end

@implementation BMViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Setup the pinch gesture recognizer
    UIPinchGestureRecognizer *pinchZoomRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchZoomGestureDetected:)];
    [self.view addGestureRecognizer:pinchZoomRecognizer];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    self.originalViewWidth = self.view.frame.size.width;
    self.viewCurrentWidth = self.originalViewWidth;
}

- (void)pinchZoomGestureDetected:(UIPinchGestureRecognizer *)recognizer
{
    CGPoint pinchLocation = [recognizer locationInView:self.view];
    if (recognizer.state == UIGestureRecognizerStateBegan) {
        self.viewCurrentWidth = self.view.frame.size.width;
        self.viewCurrentXPosition = self.view.frame.origin.x;

        // Set the pinch X coordinate to a point relative to the bounds of the view
        self.pinchXCoord = pinchLocation.x - self.viewCurrentXPosition;
        self.minZoomProportion = self.originalViewWidth / self.viewCurrentWidth;
    }

    CGFloat proportion = recognizer.scale;
    CGFloat width = self.viewCurrentWidth * MAX(proportion, self.minZoomProportion); // Set a minimum zoom width (the original size)
    width = MIN(self.originalViewWidth * 4, width); // Set a maximum zoom width (original * 4)
    CGFloat rawX = self.viewCurrentXPosition + ((self.viewCurrentWidth - width) * (self.pinchXCoord / self.viewCurrentWidth)); // Calculate the new X value
    CGRect frame = self.view.frame;
    CGFloat newXValue = MIN(rawX, 0); // Don't let the view move too far right
    newXValue = MAX(newXValue, self.originalViewWidth - width); // Don't let the view move too far left
    self.view.frame = CGRectMake(newXValue, frame.origin.y, width, frame.size.height);
    NSLog(@"newXValue: %f, width: %f", newXValue, width);
}

@end

这就是调整UIView的水平轴大小所需要做的一切。

对于 Core-Plot,假设 CPTGraphHostingViewUIViewController 正在调整大小的视图的子视图。 CPTGraphHostingView 在其框架/边界发生更改时重绘,因此,在包含视图的 layoutSubviews 方法中,更改 CPTGraphHostingView 和绘图区域的框架相对于其父级的边界(这是您应该调整大小的视图)。像这样的:

self.graphHostingView.frame = self.bounds;
self.graphHostingView.hostedGraph.plotAreaFrame.frame = self.bounds;

我没有尝试在图表缩放时更改数据,但我无法想象这会太难。在包含视图的layoutSubviews 中,在CPTGraph 上调用reloadData

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-26
    • 2014-10-23
    • 1970-01-01
    • 1970-01-01
    • 2013-07-11
    • 1970-01-01
    • 1970-01-01
    • 2017-09-23
    相关资源
    最近更新 更多