【问题标题】:call method from subclass of UIImageview从 UIImageview 的子类调用方法
【发布时间】:2011-04-27 17:22:51
【问题描述】:

我有两个 .m 文件。第一个是主要代码,第二个是 UIImageView 的子类,以便我可以检测触摸。
在主 .m 文件中,我添加了一个进度条和一个 customimageview 两个滚动视图的子视图。

我需要的是,当用户触摸 customimageview 时,进度条会向上移动并且双击会减少 [注意:customimageview 必须在第二个 .m 中识别其触摸,因为它们位于必须处理滚动视图和其他控件]

在主 .m 文件中,我有两种方法:

- (void)pumpsingletap {  
   progbm.progress +=0.1;  
}  

- (void)pumpdoubletap {  
   progbm.progress -=0.1;  
}  

然后在子类 uiimageview 我有:

//inside touches method
if ([touch view].tag == 555) {  
   NSLog(@"pump touched");  
   switch ([allTouches count]) {  
         case 1: {  
                switch ([touch tapCount]) {  
                     //---single tap---  
                     case 1: {  
                     NSLog(@"single pump touch");  
                     [self performSelector:@selector(pumpsingletap) withObject:nil afterDelay:.4];  
                     } break;  
                     //---double tap---  
                     case 2: {  
                     NSLog(@"double pump touch");  
                     [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(pumpsingletap) object:nil];  
                     [self performSelector:@selector(pumpdoubletap) withObject:nil afterDelay:.4];  
                     } break;  
               }  
           }  
       }  
  }

所以 NSlog 出现了,所以触摸识别不是问题。但是 performSelector 倒下了。由于 customimageview pumpingletap 不起作用。

那么我如何调用子类中的方法。

//更新//

所以我在我的子类中添加了以下代码

mainMethod* callingMethod = [[mainMethod alloc] init];  
[callingMethod performSelector:@selector(pumpsingletap) withObject:nil afterDelay:.4];  

然后在我用于 pumpingletap 的主要方法中,我将其更改为:

- (void)pumpsingletap { 
   NSLog(@"single pump method called");
   progbm.progress +=0.1;  
} 

出现了调用单泵方法的 NSLog,但进度条 progbm - 没有移动。所以我已经解决了我的呼叫问题 - 现在只需要弄清楚为什么进度条没有移动!

【问题讨论】:

  • 确保您的进度条已在界面生成器中连接

标签: iphone class methods touch subclass


【解决方案1】:

如果我正确地遵循了代码,那么您就是在 self 上执行选择器,但 self 是您派生的 UIImageView 类(所以您可能会在此时崩溃?)。您需要在主文件中的类上执行选择器。将引用传递给您的派生类。或者,您可以创建一个委托,在您的主类中实现它,将您的主类传递给 UIImageView,然后通过委托调用(甚至还有其他方法可以做到这一点(键值观察),但其中一种应该可以工作)。

【讨论】:

  • 用主文件的类调用选择器的代码行是什么。
【解决方案2】:

我不确定这是否是问题所在,但您不需要在 case 语句周围加上括号。另外我不明白为什么你会在开关中进行开关。做一个if-elseif-else语句,可能会更容易理解。

除此之外,据我了解,您有一个具有进度条和 customimageview 作为属性的视图控制器,并且您有应该调用的方法以响应某些操作(点击或双击 customimageview)但它们在视图控制器中。解决这个问题的常用方法是使用目标动作机制。 UIControls 通过封装目标-动作对并将它们存储在由事件类型 (UIControlEvent) 键入的字典中来实现目标动作机制。这是一个稍微简单的版本。

在您的 UIImageView 子类的 .h 文件中,在 @interface 之前写下:

typedef enum {
     ControlEventTap = 0,
     ControlEventDoubleTap 
} ControlEvent;

然后在 .m 文件中在 @implementation 之前添加:

@interface TargetActionPair : NSObject {
     id target;    
     SEL action;
} 

@property (nonatomic, assign) id target;
@property (nonatomic, assign) SEL action;

@end

@implementation TargetActionPair

@synthesize target, action;

@end

然后,将 NSMutableArray 实例变量(但不是属性)和 - (void)setTarget:(id)t action:(SEL)a forEvent:(ControlEvent)e 方法添加到您的 customimageview 实现中。

该方法应如下所示:

- (void)setTarget:(id)t action:(SEL)a forEvent:(ControlEvent)e {
    TargetActionPair *tar_act = [[TargetActionPair alloc] init];
    tar_act.target = t;
    tar_act.action = a;
    // actionsArray is the mutable array instance variable and must be allocated and set in the init method for customimageview.
    [actionsArray replaceObjectAtIndex:(NSUInteger)e withObject:tar_act];
    [tar_act release];
}

然后您可以将您的触摸处理代码替换为:

if ([touch view].tag == 555) {
    NSUInteger tapcount = [touch tapCount];
    if (([alltouches count] == 1) && (tapcount <= [actionsArray count])) {
        TargetActionPair *tar_act = [actionsArray objectAtIndex:tapcount-1];
        [tar_act.target performSelector:tar_act.action withObject:nil afterDelay:.4];
        if (tapcount == 2) {
            TargetActionPair *tar_act2 = [actionsArray objectAtIndex:tapcount-2];
            [NSObject cancelPreviousPerformRequestsWithTarget:tar_act2.target selector:tar_act2.action object:nil];
        }
    }
}

使用此代码,您只需在包含 customimageview 的视图控制器的 viewDidLoad 方法中为每个控件事件设置目标和操作。所以调用看起来像这样:

[self.customimageview setTarget:self action:@selector(pumpsingletap) forEvent:ControlEventTap];
[self.customimageview setTarget:self action:@selector(pumpdoubletap) forEvent:ControlEventDoubleTap];

不要忘记在你的 dealloc 方法中释放 actionsArray 并且在释放视图控制器时要非常小心,因为 customimageview 不会保留它。

希望这对您有所帮助,祝您的应用好运。

【讨论】:

    【解决方案3】:

    最后我通过使用 NSNotificationCenter 解决了这个问题

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-09
      • 2011-10-24
      • 1970-01-01
      • 2011-11-22
      • 2011-01-05
      • 2012-02-22
      • 2012-04-18
      相关资源
      最近更新 更多