自定义委托不响应iOS

时间:2014-03-13 20:15:41

标签: ios iphone objective-c delegates

我已经设置了一个代表来接受一个仪表的旧位置和新位置。但是,我似乎无法得到代表的回应。我可能会遗漏一些东西,但我做了一堆研究,似乎一切都井然有序。

MeterView.h

#import <UIKit/UIKit.h>
#import "KTOneFingerRotationGestureRecognizer.h"

@protocol MeterViewDelegate;


@interface MeterView : UIView{

    IBOutlet UIImageView *gauge;
    IBOutlet UIImageView *needle;
    float rotation, oldPos, newPos;
    KTOneFingerRotationGestureRecognizer *rgest;
}

@property (nonatomic, weak) id<MeterViewDelegate> delegate;

- (IBAction)handleMovedNeedle;

@end

@protocol MeterViewDelegate <NSObject>

- (void)meterView:(MeterView*)view OldValue:(float)oldval NewValue:(float)newval;

@end

MeterView.m

#import "MeterView.h"
#import <QuartzCore/QuartzCore.h>


@implementation MeterView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {

    }
    return self;
}

-(void)handleMovedNeedle{
    if ([self.delegate respondsToSelector:@selector(meterView:OldValue:NewValue:)]) {
        [self.delegate meterView:self OldValue:oldPos NewValue:newPos];
    }
    else{
        NSLog(@"Delegate call FAIL, needle moved from %f, to %f", oldPos,newPos);
    }
}

-(void)awakeFromNib{

    gauge = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"gauge.png"]];
    needle = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"needle.png"]];
    needle.frame = CGRectMake(0,gauge.frame.size.height-(needle.frame.size.height/2), gauge.frame.size.width, needle.frame.size.height);

    [self addSubview:gauge];
    [self addSubview:needle];
    rotation = 0;
    rgest = [[KTOneFingerRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotate:)];
    rgest.center = CGPointMake(CGRectGetMidX([needle bounds]) + needle.frame.origin.x, CGRectGetMidY([needle bounds]) + needle.frame.origin.y);

    [self addGestureRecognizer:rgest];

}

- (void)rotate:(UIRotationGestureRecognizer *)recognizer {
    switch (recognizer.state) {
        case UIGestureRecognizerStateBegan: {
            oldPos = ([(NSNumber *)[needle.layer valueForKeyPath:@"transform.rotation.z"] floatValue]/3.14)*100;
        }
            break;
        case UIGestureRecognizerStateChanged: {

            CGFloat angle = [(NSNumber *)[needle.layer valueForKeyPath:@"transform.rotation.z"] floatValue];

            angle += [recognizer rotation];
            if (angle >= 0 && angle <= M_PI) {
                [needle setTransform:CGAffineTransformRotate([needle  transform], [recognizer rotation])];
                rotation += [recognizer rotation];
            }

        }
            break;
        case UIGestureRecognizerStateEnded: {
            newPos = ([(NSNumber *)[needle.layer valueForKeyPath:@"transform.rotation.z"] floatValue]/3.14)*100;
            [self handleMovedNeedle];

        }
            break;
        default:
            break;
    }

}

@end

ViewController.h

#import <UIKit/UIKit.h>
#import "MeterView.h"
#import "KTOneFingerRotationGestureRecognizer.h"

@interface ViewController : UIViewController<MeterViewDelegate>{

    IBOutlet MeterView *secondMeter;
    IBOutlet MeterView *thirdMeter;

}

@end

ViewController.m

#import "ViewController.h"
#import <QuartzCore/QuartzCore.h>

#define DEG2RAD(degrees) (degrees * 0.01745327) // degrees * pi over 180
#define RAD2DEG(radians) (radians * 57.2957795) // radians * 180 over pi

@interface ViewController ()

@end

@implementation ViewController


- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    secondMeter = [[MeterView alloc]initWithFrame:[[UIScreen mainScreen] bounds]];
    secondMeter.delegate = self;
    thirdMeter = [[MeterView alloc]initWithFrame:[[UIScreen mainScreen] bounds]];
    thirdMeter.delegate =self;
}

-(void)meterView:(MeterView *)view OldValue:(float)oldval NewValue:(float)newval{
    NSLog(@"Delegate call SUCCESS, need moved from %f, to %f", oldval,newval);
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

1 个答案:

答案 0 :(得分:2)

此代码:

secondMeter = [[MeterView alloc]initWithFrame:[[UIScreen mainScreen] bounds]];
secondMeter.delegate = self;
thirdMeter = [[MeterView alloc]initWithFrame:[[UIScreen mainScreen] bounds]];
thirdMeter.delegate =self;

创建2个视图实例,但不会将它们添加到视图中,因此永远不会看到它们。

因此,您可能有一些其他视图实例在视图中并且没有委托,并且这些视图具有委托但未显示。可能来自XIB /故事板,因为你有出口。

使用插座将显示的视图连接到委托,而不是创建新实例。

如果您在视图中将委托属性设置为IBOutlet本身,那么您可以将视图控制器连接为XIB /故事板中的委托,您根本不需要担心代码中的委托。 ..