简体   繁体   中英

Adding an action to a custom button

I have a custom button animation and its inside a view. Now I'm having problems adding an action to the button. Here is the code. LogOut is the button and i don't know how to add an action on it to log a user out.

class exampleViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    self.view.backgroundColor = UIColor.white
    self.addCircleView()
    // Do any additional setup after loading the view, typically from a nib.
}

func addCircleView() {
    var circleView1 = VMButtonCircleFun(frame: CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(60), height: CGFloat(60)))
    circleView1.addCircleLayer(withType: VMMakeLocation.top.rawValue)
    circleView1.strokeColor = UIColor(red: 243/255, green: 106/255, blue: 106/255, alpha: 1.0)
    circleView1.center = CGPoint(x: CGFloat(self.view.bounds.width / 2 - 100), y: CGFloat(self.view.bounds.height / 2))
    circleView1.setIconButton(UIImage(named: "Layer 14.png")!, withType: VMMakeLocation.top.rawValue, with: UIColor(red: 127/255, green: 140/255, blue: 141/255, alpha: 1.0))
    circleView1.setLineWidthValue(1.0)
    self.view.addSubview(circleView1)
    circleView1.buildButton()
    circleView1.addTarget(self, action: #selector(self.logout), forControlEvents: .TouchUpInside)
}

func logout()
{
    //TODO MAKE YOUR LOGOUT STUFFS
}

Replace all the code in VMButtonCircleFun.h, and VMButtonCircleFun.m by this one and check the code updated of the UIViewController,

the problem was that your custom class call the selector on it own class, instead of using a custom target, so I defined a method to add custom target in this case your ViewController and call there the selector

UPDATED

VMButtonCircleFun.h

//
//  VMButtonCircleFun.h
//  VMButtonCircleFun
//
//  Created by Vu Mai on 6/2/15.
//  Copyright (c) 2015 VuMai. All rights reserved.
//

#import <UIKit/UIKit.h>
typedef NS_ENUM(NSInteger, VMMakeLocation) {
    VMMakeLocationTop = 1,
    VMMakeLocationBottom
};

@interface VMButtonCircleFun : UIView
@property(nonatomic) UIColor *strokeColor;
- (void)addCircleLayerWithType:(NSInteger)type;
- (void)setStrokeEnd:(CGFloat)strokeEnd animated:(BOOL)animated;
-(void)buildButton;
-(void)setIconButton:(UIImage *)icon withType:(NSInteger)type withColor:(UIColor*)color;
-(void)setLineWidthValue:(float)lineWidthTemp;
-(void)addAction:(SEL)selector;
-(void)addTarget:(id)target;

@end

UPDATED

VMButtonCircleFun.m

//
//  VMButtonCircleFun.m
//  VMButtonCircleFun
//
//  Created by Vu Mai on 6/2/15.
//  Copyright (c) 2015 VuMai. All rights reserved.
//

#import "VMButtonCircleFun.h"

@interface VMButtonCircleFun()

@property(nonatomic) CAShapeLayer *circleLayer;
@property (nonatomic) CAShapeLayer *lineLayerTopToBottom;
@property (nonatomic) CAShapeLayer *lineLayerBottomToHide;

@property (nonatomic, strong) UIImageView *imgIcon;
@property (nonatomic) float lineWidth;
@property (nonatomic, weak) id target;
@end

@implementation VMButtonCircleFun

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.lineWidth = 2.0f;
    }
    return self;
}

#pragma mark - Instance Methods

- (void)setStrokeEnd:(CGFloat)strokeEnd animated:(BOOL)animated
{
    self.circleLayer.strokeEnd = strokeEnd;
}

#pragma mark - Property Setters

- (void)setStrokeColor:(UIColor *)strokeColor
{
    self.circleLayer.strokeColor = strokeColor.CGColor;
    self.lineLayerBottomToHide.strokeColor = strokeColor.CGColor;
    self.lineLayerTopToBottom.strokeColor = strokeColor.CGColor;
    _strokeColor = strokeColor;
}

-(void)setLineWidthValue:(float)lineWidthTemp
{
    self.lineWidth = lineWidthTemp;
}

#pragma mark - Private Instance methods

- (void)addCircleLayerWithType:(NSInteger)type
{
    CGFloat radius;
    CGFloat lineWidth = self.lineWidth;
    CGRect screenRect = [[UIScreen mainScreen] bounds];
//    CGFloat screenWidth = screenRect.size.width;
    CGFloat screenHeight = screenRect.size.height;
    CGRect rect;
    UIBezierPath *path1 = [UIBezierPath bezierPath];
    UIBezierPath *path2 = [UIBezierPath bezierPath];
    switch (type) {
        case VMMakeLocationTop:
            radius = CGRectGetWidth(self.bounds)/2 - lineWidth/2;
            rect = CGRectMake(lineWidth/2, lineWidth/2, radius * 2, radius * 2);
            [path1 moveToPoint:CGPointMake(CGRectGetWidth(self.bounds)/2, -screenHeight)];
            [path1 addLineToPoint:CGPointMake(CGRectGetWidth(self.bounds)/2, 1)];

            [path2 moveToPoint:CGPointMake(CGRectGetWidth(self.bounds)/2, 1)];
            [path2 addLineToPoint:CGPointMake(CGRectGetWidth(self.bounds)/2, -screenHeight)];
            break;

        case VMMakeLocationBottom:
            radius = CGRectGetWidth(self.bounds)/2 - lineWidth/2;
            rect = CGRectMake(CGRectGetWidth(self.bounds)-lineWidth/2,CGRectGetHeight(self.bounds)-lineWidth/2, radius * -2, radius * -2);


            [path1 moveToPoint:CGPointMake(CGRectGetWidth(self.bounds)/2, +screenHeight)];
            [path1 addLineToPoint:CGPointMake(CGRectGetWidth(self.bounds)/2, CGRectGetHeight(self.bounds)-1)];

            [path2 moveToPoint:CGPointMake(CGRectGetWidth(self.bounds)/2, CGRectGetHeight(self.bounds)-1)];
            [path2 addLineToPoint:CGPointMake(CGRectGetWidth(self.bounds)/2, +screenHeight)];
            break;

        default:
            break;
    }

    self.circleLayer = [CAShapeLayer layer];
    self.circleLayer.path = [UIBezierPath bezierPathWithRoundedRect:rect
                                                       cornerRadius:radius].CGPath;
    self.circleLayer.strokeColor = self.tintColor.CGColor;
    self.circleLayer.fillColor = nil;
    self.circleLayer.lineWidth = lineWidth;
    self.circleLayer.lineCap = kCALineCapRound;
    self.circleLayer.lineJoin = kCALineJoinRound;
    [self.circleLayer setStrokeEnd:0.0f];
    [self.layer addSublayer:self.circleLayer];

    self.lineLayerTopToBottom = [CAShapeLayer layer];

    self.lineLayerTopToBottom.path = path1.CGPath;
    self.lineLayerTopToBottom.lineWidth = self.lineWidth;
    [self.lineLayerTopToBottom setStrokeEnd:1.0f];
    self.lineLayerTopToBottom.strokeColor = [UIColor darkGrayColor].CGColor;
    [self.layer addSublayer:self.lineLayerTopToBottom];\

    self.lineLayerBottomToHide = [CAShapeLayer layer];
    self.lineLayerBottomToHide.path = path2.CGPath;
    self.lineLayerBottomToHide.lineWidth = self.lineWidth;
    [self.lineLayerBottomToHide setStrokeEnd:1.0f];
    self.lineLayerBottomToHide.strokeColor = [UIColor darkGrayColor].CGColor;
    [self.lineLayerBottomToHide setOpacity:0];
    [self.layer addSublayer:self.lineLayerBottomToHide];

    [UIView setAnimationDelegate:self];
}

-(void)setIconButton:(UIImage *)icon withType:(NSInteger)type withColor:(UIColor*)color
{
    self.imgIcon = [[UIImageView alloc] initWithImage:icon];
    [self.imgIcon setFrame:CGRectMake(0, 0, CGRectGetWidth(self.bounds)-CGRectGetWidth(self.bounds)/2, CGRectGetHeight(self.bounds)-CGRectGetHeight(self.bounds)/2)];

    self.imgIcon.image = [icon imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
    [self.imgIcon setContentMode:UIViewContentModeScaleAspectFit];
    [self.imgIcon setTintColor:color];
    switch (type) {
        case VMMakeLocationTop:
            [self.imgIcon setCenter:CGPointMake(CGRectGetWidth(self.bounds)/2, CGRectGetHeight(self.bounds)/2 -5 )];
            break;
        case VMMakeLocationBottom:
            [self.imgIcon setCenter:CGPointMake(CGRectGetWidth(self.bounds)/2, CGRectGetHeight(self.bounds)/2 +5 )];
            break;

        default:
            break;
    }

    [self.imgIcon setAlpha:0];
    [self addSubview:self.imgIcon];
}

-(void)addAction:(SEL)selector
{
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self.target action:selector];
    [self addGestureRecognizer:tap];
}

-(void)addTarget:(id)target
{
    self.target = target;
}

-(void)buildButton
{
    CABasicAnimation * swipeLine = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    [swipeLine setValue:@"topToBottom" forKey:@"id"];
    swipeLine.delegate = self;
    swipeLine.duration=1;
    swipeLine.fromValue=[NSNumber numberWithDouble:0.0f];
    swipeLine.toValue=  [NSNumber numberWithDouble:1.0f];
    swipeLine.fillMode = kCAFillModeForwards;
    swipeLine.timingFunction= [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    swipeLine.removedOnCompletion=NO;
    self.lineLayerTopToBottom.strokeEnd = 1.0f;
    [self.lineLayerTopToBottom addAnimation:swipeLine forKey:@"topToBottom"];

}

-(void)animationLineBottomToHide
{

    CABasicAnimation * swipeLine1 = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    [swipeLine1 setValue:@"bottomToHide" forKey:@"id"];
    swipeLine1.duration=1;
    swipeLine1.fromValue=[NSNumber numberWithDouble:1.0f];
    swipeLine1.toValue=  [NSNumber numberWithDouble:0.0f];
    swipeLine1.fillMode = kCAFillModeForwards;
    swipeLine1.timingFunction= [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    swipeLine1.removedOnCompletion=YES;
    self.lineLayerBottomToHide.strokeEnd = 0.0f;
    [self.lineLayerBottomToHide addAnimation:swipeLine1 forKey:@"bottomToHide"];
}

-(void)animationLineCircle
{
    CABasicAnimation * swipe = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    [swipe setValue:@"drawCircle" forKey:@"id"];
    swipe.duration=1;
    swipe.fromValue=[NSNumber numberWithDouble:0.0f];
    swipe.toValue=  [NSNumber numberWithDouble:1.0f];
    swipe.fillMode = kCAFillModeForwards;
    swipe.timingFunction= [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
    swipe.removedOnCompletion=NO;
    self.circleLayer.strokeEnd = 1;
    [self.circleLayer addAnimation:swipe forKey:@"drawCircle"];

    [UIView animateWithDuration:0.5 delay:0.5 options:UIViewAnimationOptionCurveEaseIn animations:^{
        [self.imgIcon setAlpha:1];
        [self.imgIcon setCenter:CGPointMake(CGRectGetWidth(self.bounds)/2, CGRectGetHeight(self.bounds)/2)];
    } completion:^(BOOL finished) {

    }];
}

-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    if([[anim valueForKey:@"id"] isEqual:@"topToBottom"]) {
        [self.lineLayerBottomToHide setOpacity:1];
        [self.lineLayerTopToBottom setOpacity:0];
        [self animationLineBottomToHide];
        [self animationLineCircle];
    }
}

@end

Example ViewController, updated

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        var circleView1 = VMButtonCircleFun(frame: CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(60), height: CGFloat(60)))
        circleView1.addCircleLayer(withType: VMMakeLocation.top.rawValue)
        circleView1.strokeColor = UIColor(red: 243/255, green: 106/255, blue: 106/255, alpha: 1.0)
        circleView1.center = CGPoint(x: CGFloat(self.view.bounds.width / 2 - 100), y: CGFloat(self.view.bounds.height / 2))
        //circleView1.setIconButton(UIImage(named: "Layer 14.png")!, withType: VMMakeLocation.top.rawValue, with: UIColor(red: 127/255, green: 140/255, blue: 141/255, alpha: 1.0))
        circleView1.setLineWidthValue(1.0)
        self.view.addSubview(circleView1)
        circleView1.buildButton()
        circleView1.addTarget(self)
        circleView1.addAction(#selector(self.logout))
    }

    func logout()
    {
        debugPrint("LOGOUT")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

I hope this helps you, now works like charm

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM