简体   繁体   English

自定义代表不响应iOS

[英]Custom Delegate Not Responding iOS

I've setup a delegate to take the old and new position of a gauge. 我设置了一个代表来担任仪表的新旧位置。 However, I can't seem to get a response from the delegate. 但是,我似乎无法从委托人那里得到答复。 I could be missing something but I've done a bunch of research and it seems like everything is in order. 我可能会丢失一些东西,但是我做了很多研究,看来一切都井然有序。

MeterView.h 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 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 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 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

This code: 这段代码:

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

creates 2 instances of your view, but it doesn't add them to a view, so they will never be seen. 创建视图的2个实例,但是不会将它们添加到视图中,因此将永远不会看到它们。

So, you probably have some other view instances that are on view and don't have delegates, and these views which have delegates but aren't on display. 因此,您可能还有一些其他视图实例在视图上并且没有委托,而这些视图有委托但没有显示。 Presumably from an XIB / storyboard as you have outlets. 大概是从XIB /情节提要中获得的。

Connect the views that are on display to the delegate using the outlets rather than creating new instances. 使用出口而不是创建新实例将显示的视图连接到委托。

If you make the delegate property in the view an IBOutlet itself then you can connect the view controller as the delegate in the XIB / storyboard and you don't need to worry about the delegate in code at all... 如果您将视图中的委托属性设置为IBOutlet本身,则可以将视图控制器作为XIB /情节提要中的委托进行连接,而无需担心代码中的委托...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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