通过 TouchMoved 进行缩放:

发布于 2025-01-07 21:03:40 字数 2347 浏览 0 评论 0原文

我有一个使用 UIBezierPath 制作的 饼图 。我现在需要这些单独的路径(饼图)是可扩展的。我相信您需要一个视图才能使用捏缩放,所以我认为 TouchMoved: 是可行的方法(除非有解决方法)。

任何建议或帮助表示赞赏!

更新/进度代码

MySliceClass.m

+ (UIBezierPath *)sliceRadius:(float)radius andStartingAngle:(float)startingAngle andFinishingAngle:(float)finishingAngle
{
  static UIBezierPath *path = nil;
  path = [UIBezierPath bezierPath];
  CGPoint center = {300,300};
  [path moveToPoint:center];
  [path addArcWithCenter:center radius:radius startAngle:radians(startingAngle) endAngle:radians(finishingAngle) clockwise:YES];
  [path closePath];
  path.lineWidth = 1;

  [[UIColor redColor] setFill];
  [path fill];

  return path;
}

MySliceView.m

- (void)drawRect:(CGRect)rect 
{
  NSArray *arrayOfSlices = [NSArray arrayWithObjects:
                            slice01 = [WordplaySlice sliceRadius:200 andStartingAngle:0.5 andFinishingAngle:29.5],
                            slice02 = [WordplaySlice sliceRadius:200 andStartingAngle:30.5 andFinishingAngle:59.5],
                            slice03 = [WordplaySlice sliceRadius:200 andStartingAngle:60.5 andFinishingAngle:89.5],
                            slice04 = [WordplaySlice sliceRadius:200 andStartingAngle:90.5 andFinishingAngle:119.5],
                            slice05 = [WordplaySlice sliceRadius:200 andStartingAngle:120.5 andFinishingAngle:149.5],
                            slice06 = [WordplaySlice sliceRadius:200 andStartingAngle:150.5 andFinishingAngle:179.5],
                            slice07 = [WordplaySlice sliceRadius:200 andStartingAngle:180.5 andFinishingAngle:209.5],
                            slice08 = [WordplaySlice sliceRadius:200 andStartingAngle:210.5 andFinishingAngle:239.5],
                            slice09 = [WordplaySlice sliceRadius:200 andStartingAngle:240.5 andFinishingAngle:269.5],
                            slice10 = [WordplaySlice sliceRadius:200 andStartingAngle:270.5 andFinishingAngle:299.5],
                            slice11 = [WordplaySlice sliceRadius:200 andStartingAngle:300.5 andFinishingAngle:329.5],
                            slice12 = [WordplaySlice sliceRadius:200 andStartingAngle:330.5 andFinishingAngle:359.5], nil];                             
}

I have a pie chart which is made using UIBezierPath's. I now need those individual paths (pie pieces) to be scalable. I believe you need a view to be able to use pinch scaling, so I think touchesMoved: is the way to go (unless there's a workaround).

Any advice or help is appreciated!

Updated/Progress code

MySliceClass.m

+ (UIBezierPath *)sliceRadius:(float)radius andStartingAngle:(float)startingAngle andFinishingAngle:(float)finishingAngle
{
  static UIBezierPath *path = nil;
  path = [UIBezierPath bezierPath];
  CGPoint center = {300,300};
  [path moveToPoint:center];
  [path addArcWithCenter:center radius:radius startAngle:radians(startingAngle) endAngle:radians(finishingAngle) clockwise:YES];
  [path closePath];
  path.lineWidth = 1;

  [[UIColor redColor] setFill];
  [path fill];

  return path;
}

MySliceView.m

- (void)drawRect:(CGRect)rect 
{
  NSArray *arrayOfSlices = [NSArray arrayWithObjects:
                            slice01 = [WordplaySlice sliceRadius:200 andStartingAngle:0.5 andFinishingAngle:29.5],
                            slice02 = [WordplaySlice sliceRadius:200 andStartingAngle:30.5 andFinishingAngle:59.5],
                            slice03 = [WordplaySlice sliceRadius:200 andStartingAngle:60.5 andFinishingAngle:89.5],
                            slice04 = [WordplaySlice sliceRadius:200 andStartingAngle:90.5 andFinishingAngle:119.5],
                            slice05 = [WordplaySlice sliceRadius:200 andStartingAngle:120.5 andFinishingAngle:149.5],
                            slice06 = [WordplaySlice sliceRadius:200 andStartingAngle:150.5 andFinishingAngle:179.5],
                            slice07 = [WordplaySlice sliceRadius:200 andStartingAngle:180.5 andFinishingAngle:209.5],
                            slice08 = [WordplaySlice sliceRadius:200 andStartingAngle:210.5 andFinishingAngle:239.5],
                            slice09 = [WordplaySlice sliceRadius:200 andStartingAngle:240.5 andFinishingAngle:269.5],
                            slice10 = [WordplaySlice sliceRadius:200 andStartingAngle:270.5 andFinishingAngle:299.5],
                            slice11 = [WordplaySlice sliceRadius:200 andStartingAngle:300.5 andFinishingAngle:329.5],
                            slice12 = [WordplaySlice sliceRadius:200 andStartingAngle:330.5 andFinishingAngle:359.5], nil];                             
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

柏林苍穹下 2025-01-14 21:03:40

我认为如果为每个切片创建一个视图并使用 UIPinchGestureRecognizer,您会发现更容易。方法如下。

首先,我们需要一个 UIView 子类来绘制一个切片。它还应该重写 pointInside:withEvent: 来忽略落在切片外部的触摸(即使触摸位于视图的矩形边界内)。

因此,我们将创建一个名为 SliceView 的类。它使用 CAShapeLayer 进行切片绘制:

@interface SliceView : UIView

@property (nonatomic) CGFloat padding;
@property (nonatomic) CGFloat startRadians;
@property (nonatomic) CGFloat endRadians;
@property (nonatomic, strong) UIColor *fillColor;

@end

@implementation SliceView

@synthesize padding = _padding;
@synthesize startRadians = _startRadians;
@synthesize endRadians = _endRadians;
@synthesize fillColor = _fillColor;

我们通过覆盖 layerClass< 来告诉它使用 CAShapeLayer 而不是普通的 CALayer /代码> 方法。我们还将添加一个方便的方法,以 CAShapeLayer 的形式返回视图层。

+ (Class)layerClass {
    return [CAShapeLayer class];
}

- (CAShapeLayer *)shapeLayer {
    return (CAShapeLayer *)self.layer;
}

我们将在 layoutSubviews 中计算切片的路径,因为每当其大小发生更改时,视图都会收到 layoutSubviews 消息。

我们将布置每个切片视图以覆盖整个饼图,但只绘制饼图的楔形部分。每个切片的框架将覆盖整个屏幕(如果饼图是全屏的)。这意味着切片视图知道其圆弧的中心位于其边界的中心。但随后我们使用一点三角函数来在相邻切片之间添加填充。

我们还调整图层的锚点;这是当您缩放或旋转图层时图层中不会移动的点。我们希望锚点位于最靠近中心的切片的角处。

- (void)layoutSubviews {
    CAShapeLayer *layer = self.shapeLayer;
    CGRect bounds = self.bounds;
    CGFloat radius = MIN(bounds.size.width, bounds.size.height) / 2 - 2 * _padding;
    CGPoint center = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds));
    CGFloat sine = sinf((_startRadians + _endRadians) * 0.5f);
    CGFloat cosine = cosf((_startRadians + _endRadians) * 0.5f);
    center.x += _padding * cosine;
    center.y += _padding * sine;
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:center];
    [path addArcWithCenter:center radius:radius startAngle:_startRadians endAngle:_endRadians clockwise:YES];
    [path closePath];
    layer.path = path.CGPath;

    // Move my anchor point to the corner of my path so scaling will leave the corner in the same place.
    CGPoint cornerInSuperview = [self convertPoint:center toView:self.superview];
    layer.anchorPoint = CGPointMake(center.x / bounds.size.width, center.y / bounds.size.height);
    self.center = cornerInSuperview;
}

当与切片相关的任何视图属性发生更改时,我们需要重新计算概述切片的路径。当切片的填充颜色更改时,我们需要将该更改传递到图层。所以我们将重写属性设置器。

- (void)setPadding:(CGFloat)padding {
    _padding = padding;
    [self setNeedsLayout];
}

- (void)setStartRadians:(CGFloat)startRadians {
    _startRadians = startRadians;
    [self setNeedsLayout];
}

- (void)setEndRadians:(CGFloat)endRadians {
    _endRadians = endRadians;
    [self setNeedsLayout];
}

- (void)setFillColor:(UIColor *)color {
    _fillColor = color;
    self.shapeLayer.fillColor = color.CGColor;
}

最后,我们重写 pointInside:withEvent: ,以便命中测试仅在触摸实际上位于切片路径内部时才将触摸分配给切片视图。这很重要,因为所有切片视图都将有一个覆盖整个屏幕的框架。

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    return CGPathContainsPoint(self.shapeLayer.path, NULL, point, NO);
}

@end

现在我们有了一个方便的 SliceView 类,我们可以使用它来绘制带有可缩放切片的饼图。在 iPhone 屏幕上很难将两根手指放入切片中,因此我们将让用户点击切片来选择它,然后在任意位置捏合以缩放所选切片。 (该界面还使其可以在模拟器中进行测试。)

@implementation ViewController {
    __weak SliceView *_selectedSlice;
}

我们将用红色绘制未选定的切片,用蓝色绘制选定的切片。

+ (UIColor *)unselectedSliceFillColor {
    return UIColor.redColor;
}

+ (UIColor *)selectedSliceFillColor {
    return UIColor.blueColor;
}

当用户点击切片时,我们需要更改先前选择和新选择的颜色,并记录新选择。

- (IBAction)sliceWasTapped:(UITapGestureRecognizer *)tapper {
    _selectedSlice.fillColor = self.class.unselectedSliceFillColor;
    _selectedSlice = (SliceView *)tapper.view;
    _selectedSlice.fillColor = self.class.selectedSliceFillColor;
}

当用户捏合时,我们会调整所选切片(如果有)的变换。

- (IBAction)pinched:(UIPinchGestureRecognizer *)pincher {
    if (!_selectedSlice)
        return;
    CGFloat scale = pincher.scale;
    pincher.scale = 1;
    _selectedSlice.transform = CGAffineTransformScale(_selectedSlice.transform, scale, scale);
}

最后,我们需要实际创建切片视图和手势识别器。我们为每个切片创建一个点击识别器,并在背景视图上附加一个“全局”捏合识别器。

- (void)viewDidLoad {
    static int const SliceCount = 12;
    CGRect bounds = self.view.bounds;
    for (int i = 0; i < SliceCount; ++i) {
        SliceView *slice = [[SliceView alloc] initWithFrame:bounds];
        slice.startRadians = 2 * M_PI * i / SliceCount;
        slice.endRadians = 2 * M_PI * (i + 1) / SliceCount;
        slice.padding = 4;
        slice.fillColor = self.class.unselectedSliceFillColor;
        slice.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        [self.view addSubview:slice];

        UITapGestureRecognizer *tapper = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(sliceWasTapped:)];
        [slice addGestureRecognizer:tapper];
    }

    UIPinchGestureRecognizer *pincher = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinched:)];
    [self.view addGestureRecognizer:pincher];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

@end

它看起来像这样:

SliceView demo screen shot

您可以在此处下载我的测试项目:http://dl.dropbox.com/u/26919672/pie.zip

更新

为了回应您询问限制规模的评论,我建议向 SliceView:

@property (nonatomic) CGFloat minScale;
@property (nonatomic) CGFloat maxScale;
@property (nonatomic) CGFloat scale;

重要:您需要将 initWithFrame:initWithCoder: 中的所有三个属性初始化为 1。

然后,实现 scale 设置器来实际执行限制并设置比例:

- (void)setScale:(CGFloat)scale {
    _scale = MAX(minScale, MIN(scale, maxScale));
    self.transform = CGAffineTransformMakeScale(_scale, _scale);
}

pinched: 中,您可以更新视图的 scale 属性直接设置视图的 transform 属性:

- (IBAction)pinched:(UIPinchGestureRecognizer *)pincher {
    if (!_selectedSlice)
        return;
    CGFloat scale = pincher.scale;
    pincher.scale = 1;
    _selectedSlice.scale = _selectedSlice.scale * scale;
}

I think you will find it easier if you create a view for each slice, and use a UIPinchGestureRecognizer. Here's how.

First, we need a UIView subclass that draws one slice. It should also override pointInside:withEvent: to ignore a touch that lands outside the slice (even if the touch is inside the view's rectangular bounds).

So we'll make a class called SliceView. It uses CAShapeLayer to do the slice drawing:

@interface SliceView : UIView

@property (nonatomic) CGFloat padding;
@property (nonatomic) CGFloat startRadians;
@property (nonatomic) CGFloat endRadians;
@property (nonatomic, strong) UIColor *fillColor;

@end

@implementation SliceView

@synthesize padding = _padding;
@synthesize startRadians = _startRadians;
@synthesize endRadians = _endRadians;
@synthesize fillColor = _fillColor;

We tell it to use a CAShapeLayer instead of a plain CALayer by overriding the layerClass method. We'll also add a handy method that returns the view's layer as a CAShapeLayer.

+ (Class)layerClass {
    return [CAShapeLayer class];
}

- (CAShapeLayer *)shapeLayer {
    return (CAShapeLayer *)self.layer;
}

We'll compute the path of the slice in layoutSubviews, because the view receives the layoutSubviews message any time its size is changed.

We're going to lay out each slice view to cover the entire pie, but only draw its wedge of the pie. Each slice's frame will cover the entire screen (if the pie is full-screen). That means the slice view knows that the center of its arc is at the center of its bounds. But then we use a little trigonometry to put in the padding between adjacent slices.

We also adjust the anchor point of the layer; this is the point in the layer that doesn't move when you scale or rotate the layer. We want the anchor point to be at the corner of the slice nearest the center.

- (void)layoutSubviews {
    CAShapeLayer *layer = self.shapeLayer;
    CGRect bounds = self.bounds;
    CGFloat radius = MIN(bounds.size.width, bounds.size.height) / 2 - 2 * _padding;
    CGPoint center = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds));
    CGFloat sine = sinf((_startRadians + _endRadians) * 0.5f);
    CGFloat cosine = cosf((_startRadians + _endRadians) * 0.5f);
    center.x += _padding * cosine;
    center.y += _padding * sine;
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:center];
    [path addArcWithCenter:center radius:radius startAngle:_startRadians endAngle:_endRadians clockwise:YES];
    [path closePath];
    layer.path = path.CGPath;

    // Move my anchor point to the corner of my path so scaling will leave the corner in the same place.
    CGPoint cornerInSuperview = [self convertPoint:center toView:self.superview];
    layer.anchorPoint = CGPointMake(center.x / bounds.size.width, center.y / bounds.size.height);
    self.center = cornerInSuperview;
}

When any of the view's properties relating to the slice are changed, we need to recompute the path outlining the slice. And when the fill color of the slice is changed, we need to pass that change along to the layer. So we'll override the property setters.

- (void)setPadding:(CGFloat)padding {
    _padding = padding;
    [self setNeedsLayout];
}

- (void)setStartRadians:(CGFloat)startRadians {
    _startRadians = startRadians;
    [self setNeedsLayout];
}

- (void)setEndRadians:(CGFloat)endRadians {
    _endRadians = endRadians;
    [self setNeedsLayout];
}

- (void)setFillColor:(UIColor *)color {
    _fillColor = color;
    self.shapeLayer.fillColor = color.CGColor;
}

Finally, we override pointInside:withEvent: so that hit-testing will only assign a touch to a slice view if the touch is actually inside the path of the slice. This is critical since all of the slice views will have a frame that covers the whole screen.

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    return CGPathContainsPoint(self.shapeLayer.path, NULL, point, NO);
}

@end

Now that we have a handy SliceView class, we can use it to draw a pie chart with zoomable slices. It's hard to fit two fingers into a slice on an iPhone screen, so we'll let the user tap a slice to select it, and pinch anywhere to scale the selected slice. (This interface also makes it testable in the simulator.)

@implementation ViewController {
    __weak SliceView *_selectedSlice;
}

We'll draw unselected slices in red and the selected slice in blue.

+ (UIColor *)unselectedSliceFillColor {
    return UIColor.redColor;
}

+ (UIColor *)selectedSliceFillColor {
    return UIColor.blueColor;
}

When the user taps a slice, we'll need to change the colors of the prior selection and the new selection, and record the new selection.

- (IBAction)sliceWasTapped:(UITapGestureRecognizer *)tapper {
    _selectedSlice.fillColor = self.class.unselectedSliceFillColor;
    _selectedSlice = (SliceView *)tapper.view;
    _selectedSlice.fillColor = self.class.selectedSliceFillColor;
}

When the user pinches, we adjust the transform of the selected slice, if there is one.

- (IBAction)pinched:(UIPinchGestureRecognizer *)pincher {
    if (!_selectedSlice)
        return;
    CGFloat scale = pincher.scale;
    pincher.scale = 1;
    _selectedSlice.transform = CGAffineTransformScale(_selectedSlice.transform, scale, scale);
}

Finally, we need to actually create the slice views and the gesture recognizers. We create one tap recognizer for each slice, and one “global” pinch recognizer attached to the background view.

- (void)viewDidLoad {
    static int const SliceCount = 12;
    CGRect bounds = self.view.bounds;
    for (int i = 0; i < SliceCount; ++i) {
        SliceView *slice = [[SliceView alloc] initWithFrame:bounds];
        slice.startRadians = 2 * M_PI * i / SliceCount;
        slice.endRadians = 2 * M_PI * (i + 1) / SliceCount;
        slice.padding = 4;
        slice.fillColor = self.class.unselectedSliceFillColor;
        slice.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        [self.view addSubview:slice];

        UITapGestureRecognizer *tapper = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(sliceWasTapped:)];
        [slice addGestureRecognizer:tapper];
    }

    UIPinchGestureRecognizer *pincher = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinched:)];
    [self.view addGestureRecognizer:pincher];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

@end

And here's what it looks like:

SliceView demo screen shot

You can download my test project here: http://dl.dropbox.com/u/26919672/pie.zip

UPDATE

In response to your comment asking about limiting the scale, I would suggest adding some more properties to SliceView:

@property (nonatomic) CGFloat minScale;
@property (nonatomic) CGFloat maxScale;
@property (nonatomic) CGFloat scale;

Important: You will need to initialize all three properties to 1 in initWithFrame: and initWithCoder:.

Then, implement the scale setter to actually enforce the limits and set the scale:

- (void)setScale:(CGFloat)scale {
    _scale = MAX(minScale, MIN(scale, maxScale));
    self.transform = CGAffineTransformMakeScale(_scale, _scale);
}

In pinched:, you update the scale property of the view instead of setting the view's transform property directly:

- (IBAction)pinched:(UIPinchGestureRecognizer *)pincher {
    if (!_selectedSlice)
        return;
    CGFloat scale = pincher.scale;
    pincher.scale = 1;
    _selectedSlice.scale = _selectedSlice.scale * scale;
}
嘿哥们儿 2025-01-14 21:03:40

首先,将切片存储在数组中可能是一个更好的主意。

其次,定义一个类 MySliceClass (可以继承自 UIBezierPath)也是一个更好的主意。此类具有定义切片的属性:startingAngleendAngle

现在,您不仅改进了代码,而且调整切片大小也变得更加容易。

您必须向类 MySliceClass 添加一个参数 radius,每次触摸切片时,您都会更改其半径,并调用 [self setNeedsDisplay] 以便调用方法 drawRect

最后,您还应该将初始化移至视图的初始化方法中,因为这样做时,每次绘制视图时都会创建新的切片。

编辑这是一个示例实现

@implementation Slice // Subclass of NSObject

@synthesize radius, startAngle, endAngle, center;

- (void)draw
{
    UIBezierPath *path = nil;
    path = [UIBezierPath bezierPath];
    [path moveToPoint:center];
    [path addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
    [path closePath];
    path.lineWidth = 1;

    [[UIColor redColor] setFill];
    [path fill];
}

@end

@implementation SliceView

@synthesize slices;

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        int numSlices = 12; // you can change this
        slices = [NSMutableArray array];
        for (int i = 0; i < numSlices; i++) {
            Slice *slice = [[Slice alloc] init];
            slice.center = self.center;
            slice.radius = 100;
            slice.startAngle = (2*M_PI / numSlices) * i;
            slice.endAngle = (2*M_PI / numSlices) * (i+0.9);
        }
    }
    return self;
}

- (void)drawRect:(CGRect)rect
{
    [[UIColor redColor] setFill];
    for (Slice *slice in slices) {
    [slice draw];
    }
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:self];
    CGFloat d = sqrtf(powf(point.x-self.center.x, 2) + powf(point.y-self.center.y, 2));

    int index = atan2f(point.x-self.center.x, point.y-self.center.y) * self.slices.count / (2*M_PI);
    Slice *slice = [slices objectAtIndex:index];
    slice.radius = d;
}

@end

我没有测试此代码,因此可能存在一些错误。但我希望你可以从这里开始。

First, it is probably a better idea to store the slices in an array.

Second, it is also a better idea to define a class MySliceClass (that may inherit from UIBezierPath). This class has properties that define a slice: startingAngle, endAngle.

Now not only you improved your code, but it becomes easier to resize the slices.

You have to add a parameter radius to the class MySliceClass, and every time a slice is touched, you change its radius, and call [self setNeedsDisplay] so that the method drawRect gets called.

Finally, you should also move the initialization to the initialization method of your view because the way you do it, you create new slices every time you draw the view.

EDIT Here is an example implementation

@implementation Slice // Subclass of NSObject

@synthesize radius, startAngle, endAngle, center;

- (void)draw
{
    UIBezierPath *path = nil;
    path = [UIBezierPath bezierPath];
    [path moveToPoint:center];
    [path addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
    [path closePath];
    path.lineWidth = 1;

    [[UIColor redColor] setFill];
    [path fill];
}

@end

And

@implementation SliceView

@synthesize slices;

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        int numSlices = 12; // you can change this
        slices = [NSMutableArray array];
        for (int i = 0; i < numSlices; i++) {
            Slice *slice = [[Slice alloc] init];
            slice.center = self.center;
            slice.radius = 100;
            slice.startAngle = (2*M_PI / numSlices) * i;
            slice.endAngle = (2*M_PI / numSlices) * (i+0.9);
        }
    }
    return self;
}

- (void)drawRect:(CGRect)rect
{
    [[UIColor redColor] setFill];
    for (Slice *slice in slices) {
    [slice draw];
    }
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:self];
    CGFloat d = sqrtf(powf(point.x-self.center.x, 2) + powf(point.y-self.center.y, 2));

    int index = atan2f(point.x-self.center.x, point.y-self.center.y) * self.slices.count / (2*M_PI);
    Slice *slice = [slices objectAtIndex:index];
    slice.radius = d;
}

@end

I didn't test this code, so there might be some errors. But you can start from this I hope.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文