从 UIImageview 的子类调用方法

发布于 2024-11-02 16:41:26 字数 1890 浏览 4 评论 0原文

我有两个 .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失败了。由于自定义图像视图泵单个水龙头不起作用。

那么如何调用子类中的方法呢?

//更新//

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

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

然后在我的pumpsingletap的主要方法中将其更改为:

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

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

I have two .m files. The first is the main code, The second is a subclass of UIImageView so that i can detect touches.
In the main .m file I have added a progress bar and a customimageview both subviews of a scrollview.

What I need is that when a user touches the customimageview that the progress bar moves up and a double tap decreases the [Note: the customimageview has to have its touches recognised in the second .m because of them being in a subview of a scrollview and other controls are having to be handled]

In the main .m file I have a two methods:

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

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

then in the subclassed uiimageview i have:

//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;  
               }  
           }  
       }  
  }

So the NSlog's appear so the touch recognition isn't an issue. But the performSelector falls over. As the customimageview pumpsingletap doesnt work.

So how do i call the method in the subclass.

//update//

so I have added in the following code, in my subclass

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

then in my main method for pumpsingletap i changed it to:

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

The NSLog for single pump method called appeared but the progress bar progbm - didn't move. so i have solved my calling issue - just need to now work out why the progress bar isnt moving!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

面犯桃花 2024-11-09 16:41:26

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

If I'm following the code correctly, you are performing the selector on self, but self is your derived UIImageView class (so you probably crash at that point?). You need to perform selector on the class in your main file. Pass a reference to that to your derived class. Alternately, you could create a delegate, implement it in your main class, pass your main class to the UIImageView and then call through the delegate (there are even other ways to do it (key-value observation), but one of these should work).

驱逐舰岛风号 2024-11-09 16:41:26

我不确定这是否是问题所在,但您不需要在 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 实例变量(但不是property) 和您的 customimageview 实现的 - (void)setTarget:(id)t action:(SEL)a forEvent:(ControlEvent)e 方法。

该方法应如下所示:

- (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 不会保留它。

我希望这会有所帮助,祝您的应用程序好运。

I'm not sure if this is the problem, but you don't need brackets around case statements. Also I don't get why you would make a switch within a switch. Just make an if-elseif-else statement, it'll probably be easier to understand.

Other than this, from what I understand, you have a view controller with both a progress bar and a customimageview as properties, and you have methods that should be called in response to certain actions, (tapping or double tapping the customimageview) but they're in the view controller. The usual way to solve this is by using the target action mechanism. UIControls implement the target action mechanism by encapsulating target-action pairs and storing them in a dictionary, keyed by the event type (UIControlEvent). Here's a slightly simpler version.

In the .h file for your subclass of UIImageView, before the @interface write this:

typedef enum {
     ControlEventTap = 0,
     ControlEventDoubleTap 
} ControlEvent;

Then in the .m file add this before the @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

Then, add an NSMutableArray instance variable, (but not a property) and a - (void)setTarget:(id)t action:(SEL)a forEvent:(ControlEvent)e method to your customimageview implementation.

The method should look like this:

- (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];
}

Then you can replace your touch handling code with:

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];
        }
    }
}

With this code you simply set the target and action for each control event in the viewDidLoad method of the view controller that contains the customimageview. So the calls would look like this:

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

DON'T FORGET to release the actionsArray in your dealloc method and to be very careful about releasing the view controller since the customimageview doesn't retain it.

I hope this helps, best of luck on your app.

梦里°也失望 2024-11-09 16:41:26

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

In the end I solved the issue by using NSNotificationCenter

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文