0

2 つの同心円があり、その間の距離は一定です。円の部分(内側の黒丸を含む)を触った角度から、一番外側の円の円周上の座標を求めます。

これは のサブクラスでUIControlあり、 touches メソッドを使用して円周上の点を取得します。

正確な角度を取得することに成功したため、最も外側の円の円周上の正確な点を取得しました。

しかし、直径 = distance_between_concentric_circles + 2 * オフセットとなるように、同心円の上にボタンを配置したいと考えています。

このオフセットは、下の画像のように、ボタンのエッジが同心円の領域からはみ出すようにするために使用されます。

丸ボタン

そのボタンを動かすたびに、円形のパスに沿って移動する必要があります。

描きたくないのでUIButtonイメージビューを使っているのですが、一番外側の円の円周上の点と の大きさから左上の座標を求めるのに苦労していUIButtonます。

ボタンを移動できますが、円形パスに正しく配置されていません。

左上の座標を取得して uibutton のフレームを設定する方法があるかどうか、誰か教えてもらえますか?

描かずにやりたい。

4

2 に答える 2

1

おそらく、左上隅を気にせずに、ボタンcenterの (プロパティではなく) プロパティを設定する方が簡単です。frame左上へのオフセットを計算するのは難しくありませんが、centerプロパティを調整する方がはるかに直感的です。


centerまたは、調整や調整をしたくない場合はframe、Quartz 2D を使用して、画面上のある点についてボタンを回転させることができます。

  • ボタンの変更anchorPoint;

  • positionボタンの を、回転するポイントに設定します (また、 を設定したため、anchorPointボタンはその から適切にオフセットされますposition)。と

  • そのアンカーポイントを中心に回転させます。

したがって、QuartzCore.framework をプロジェクトにリンクすると、次のことができます。

#import <QuartzCore/QuartzCore.h>

@interface ViewController ()

@property (nonatomic, strong) CADisplayLink *displayLink;
@property (nonatomic) CFTimeInterval startTime;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self rotateButtonAroundPoint];
}

- (void)rotateButtonAroundPoint
{
    // the point about which I'm rotating and at what radius

    CGPoint center = CGPointMake(self.view.bounds.size.width / 2.0, self.view.bounds.size.height / 2.0);
    CGFloat radius = 100.0;

    // now configure the button's layer accordingly

    self.button.layer.anchorPoint = CGPointMake(0.5, 0.5 + radius / self.button.frame.size.height);
    self.button.layer.position = center;

    // just so I can see what I'm rotating this around

    [self addCircleAt:center radius:5.0 color:[UIColor redColor]];

    // turn on display link to animate it (better than `NSTimer` for animations)

    [self startDisplayLink];
}

- (void)addCircleAt:(CGPoint)center radius:(CGFloat)radius color:(UIColor *)color
{
    CAShapeLayer *layer = [CAShapeLayer layer];
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:0 endAngle:2.0 * M_PI clockwise:YES];

    layer.path = [path CGPath];
    layer.fillColor = [color CGColor];
    [self.view.layer addSublayer:layer];
}

- (void)startDisplayLink
{
    self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink:)];
    self.startTime = CACurrentMediaTime();
    [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}

- (void)stopDisplayLink
{
    [self.displayLink invalidate];
    self.displayLink = nil;
}

- (void)handleDisplayLink:(CADisplayLink *)displayLink
{
    CFTimeInterval elapsed = CACurrentMediaTime() - _startTime;

    self.button.transform = CGAffineTransformMakeRotation(elapsed * 2.0 * M_PI / 5.0); // duration = 5.0 seconds
}

center/を変更するframeか、(この回転ではなく) 変換を行うだけで、計算コストが低くなる可能性があると思いますが、ボタンが回転しているときに実際にボタンを回転させたい場合、これはオプションであり、特定の優雅さを楽しんでいます (ちょうどデカルト座標をまったく気にせずに、それについて設定positionして回転させます)。anchorPoint

于 2013-05-21T17:29:36.270 に答える
0

中心を原点とする円周上の任意の点は で示され(r*cos(theta),r*sin*(theta)) 、原点から離れた円周上の任意の点が円の中心になるので、ボタンの中心を(x+r*cos(theta),y+r*sin*(theta)) (x,y)計算して設定します(x+r*cos(theta),y+r*sin*(theta))

于 2013-05-21T13:12:58.397 に答える