2014-03-13 70 views
1

我已經設置了一個代表,以測量儀器的舊位置和新位置。但是,我似乎無法獲得代表的回覆。我可能會錯過一些東西,但我已經做了大量的研究,看起來好像一切都是按順序進行的。自定義代表沒有迴應iOS

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 
+0

一切似乎都很好。保持登錄手勢識別器方法,看看他們是否真的被調用。 – Sandeep

+0

你有沒有嘗試過在'MeterView.m'類中使用自動合成屬性'_delegate'而不是'self.delegate' – Sammio2

回答

2

此代碼:

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

創建視圖的兩個實例,但它並沒有將它們添加到一個視圖,所以他們不會被搬上銀幕。

因此,您可能有一些其他視圖實例在視圖中,並且沒有委託,並且這些視圖具有委託但未顯示。可能來自XIB /故事板,因爲你有插座。

使用插座將顯示的視圖連接到委託,而不是創建新的實例。

如果您在視圖中製作委託屬性IBOutlet本身,那麼您可以將視圖控制器作爲XIB /故事板中的委託來連接,並且您不必擔心代碼中的委託...