DSh*_*hah 5 animation objective-c calayer uiview ios
我有以下屏幕:
当我单击"获取更多"按钮时,它将添加新的圆形按钮.我在添加了UIView
所有圆形按钮的位置添加了Pan Gesture,然后UIBezierPath
仅从圆形按钮中绘制一个.到目前为止,一切正常.
现在,我想要以下内容:
UIView
名为playGroundView的父级,它包含所有的圆形按钮.这将为所有这些按钮绘制Bezier路径.请参阅PlayGround UIView子类的下面代码:
@interface PlayGroundView : UIView
@property (nonatomic, weak) PlayGroundViewController *playViewController;
@end
#import "PlayGroundView.h"
#import "RoundedButton.h"
#import "PlayGroundViewController.h"
@interface PlayGroundView () {
UIBezierPath *path;
BOOL isDrawPointInside;
}
@end
@implementation PlayGroundView
#pragma mark - View Methods -
- (id)initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder])
[self commonInit];
return self;
}
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame])
[self commonInit];
return self;
}
- (void)drawRect:(CGRect)rect {
[[UIColor redColor] setStroke];
[path stroke];
}
#pragma mark - Action Methods -
- (void)pan:(UIPanGestureRecognizer *)pan {
CGPoint currentPoint = [pan locationInView:self];
// NSLog(@"currentPoint: %@", NSStringFromCGPoint(currentPoint));
if (pan.state == UIGestureRecognizerStateBegan) {
NSMutableArray *buttonAry = [NSMutableArray array];
buttonAry = self.playViewController.rBtnOpponentPlayerList;
[buttonAry addObjectsFromArray:self.playViewController.rBtnPlayerList];
for (int i=0; i<buttonAry.count; i++) {
UIButton *btn = [buttonAry objectAtIndex:i];
CGRect nearByRect = CGRectMake(btn.frame.origin.x - 20, btn.frame.origin.y - 20, btn.frame.size.width + 40, btn.frame.size.height + 40);
if (CGRectContainsPoint(nearByRect, currentPoint)) {
isDrawPointInside = YES;
[path moveToPoint:btn.center];
// NSLog(@"point is inside....");
}
}
}
if (pan.state == UIGestureRecognizerStateChanged) {
if (isDrawPointInside) {
[path addLineToPoint:currentPoint];
[self setNeedsDisplay];
}
}
if (pan.state == UIGestureRecognizerStateEnded) {
isDrawPointInside = NO;
// NSLog(@"pan ended");
}
}
#pragma mark - Helper Methods -
- (void)commonInit {
path = [UIBezierPath bezierPath];
path.lineWidth = 3.0;
// Capture touches
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
pan.maximumNumberOfTouches = pan.minimumNumberOfTouches = 1;
[self addGestureRecognizer:pan];
// Erase with long press
[self addGestureRecognizer:[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(erase)]];
}
- (void)erase {
path = [UIBezierPath bezierPath];
path.lineWidth = 3.0;
[self setNeedsDisplay];
}
@end
Run Code Online (Sandbox Code Playgroud)
我仍然无法管理所有圆形按钮状态.让我知道在移动时管理圆形按钮的所有步骤的最佳方法.
我提到过:http://nachbaur.com/blog/core-animation-part-4
我的完整演示代码可从以下网址获得:https://www.dropbox.com/s/f0ri0bff8ioxtpz/FreeHandDrawingDemo%202.zip?dl=0
为了实现这一点,我使用了 UIBezierPath+Points 类。除此之外,在我的代码中使用了以下类和逻辑:
在PlayGroundView中,我编辑了drawRect方法中的代码,其余代码是相同的:
- (void)drawRect:(CGRect)rect {
[[UIColor redColor] setStroke];
for (int i=0; i<[self subviews].count; i++) {
RoundButton *tmpPlayerButton = [self.subviews objectAtIndex:i];
for (UIBezierPath *bezierPath in tmpPlayerButton.allPathsOfPlayer) {
[bezierPath strokeWithBlendMode:kCGBlendModeNormal alpha:1.0];
}
}
[path stroke];
}
Run Code Online (Sandbox Code Playgroud)
在我的 ViewController 类中,在“获取更多按钮”中,下面的代码如下:
- (IBAction)getBallPressed:(id)sender {
[self moveBalls];
// self.playView.viewController = self;
int xPos = self.view.frame.size.width-30;
int yPos = self.view.frame.size.height-30;
int btnXPos = arc4random_uniform(xPos);
int btnYPos = arc4random_uniform(yPos);
RoundButton *newButton = [[RoundButton alloc] initWithFrame:CGRectMake(btnXPos, btnYPos, 30, 30)];
[newButton setBackgroundColor:[UIColor redColor]];
newButton.layer.cornerRadius = newButton.frame.size.height/2;
[newButton setTitle:[self randomStringWithLength:1] forState:UIControlStateNormal];
UILongPressGestureRecognizer *longGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longGestureRecognized:)];
[newButton addGestureRecognizer:longGesture];
[self.playView.playerArray addObject:newButton];
[self.playView addSubview:newButton];
}
- (void)moveBalls {
for (int i=0; i<[self.playView subviews].count; i++) {
RoundButton *playerButton = [self.playView.subviews objectAtIndex:i];
if (playerButton.isEditPath) {
id point = [[[playerButton.allPathsOfPlayer lastObject] points] lastObject];
CGPoint lastPoint = [point CGPointValue];
NSLog(@"lastPoint: %@", NSStringFromCGPoint(lastPoint));
[playerButton setCenter:lastPoint];
}
}
}
Run Code Online (Sandbox Code Playgroud)
在“移动按钮”中,下面的代码使我可以同时移动所有圆形按钮,这是我的确切要求:
- (void)playAnimation {
for (int i=0; i<self.playView.subviews.count; i++) {
//Prepare the animation - we use keyframe animation for animations of this complexity
CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//Set some variables on the animation
pathAnimation.calculationMode = kCAAnimationPaced;
//We want the animation to persist - not so important in this case - but kept for clarity
//If we animated something from left to right - and we wanted it to stay in the new position,
//then we would need these parameters
pathAnimation.fillMode = kCAFillModeForwards;
pathAnimation.removedOnCompletion = NO;
pathAnimation.duration = 2.0;
pathAnimation.repeatCount = 0;
RoundButton *tmpRoundButton;
UIBezierPath *path;
tmpRoundButton = [self.playView.subviews objectAtIndex:i];
for (int j=0; j<tmpRoundButton.allPathsOfPlayer.count; j++) {
if (path)
[path appendPath:[tmpRoundButton.allPathsOfPlayer objectAtIndex:j]];
else
path = [tmpRoundButton.allPathsOfPlayer objectAtIndex:j];
//Now we have the path, we tell the animation we want to use this path - then we release the path
pathAnimation.path = [path CGPath];
[tmpRoundButton.layer addAnimation:pathAnimation forKey:@"moveTheSquare"];
}
[path moveToPoint:[[[path points] firstObject] CGPointValue]];
}
[self.playView setNeedsDisplay];
}
Run Code Online (Sandbox Code Playgroud)