视图控制器和 UIView 之间的简单委托不起作用

Posted

技术标签:

【中文标题】视图控制器和 UIView 之间的简单委托不起作用【英文标题】:Simple Delegate Between View Controller and UIView Isn't Working 【发布时间】:2013-05-08 22:01:47 【问题描述】:

因此,当在子视图上按下按钮时,我使用一个简单的委托从主视图控制器访问一个功能,该子视图在主视图顶部生成为叠加层。由于某种原因,源视图控制器中定义的函数没有被执行。我已经这样做了 100 次,感觉就像我错过了一些愚蠢的东西。这是代码为什么这不起作用?

Source ViewController's.h:

#import <UIKit/UIKit.h>
#import "ProfileSettingsViewController.h"
#import "ImageViewer.h"

@interface ProfileViewController : UIViewController <UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate, subViewDelegate>

源 viewController.m:

#import <Parse/Parse.h>
#import <QuartzCore/QuartzCore.h>
#import "ImageViewer.h"
#import "ProfileViewController.h"

@interface ProfileViewController () <UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate, subViewDelegate>

@end

//where the ImageViewer object is defined    
@implementation ProfileViewController

    NSMutableArray *dataArray;
    ImageViewer *loadImageViewer;


//where the UIView is initialized
- (void) handleImageTap:(UIGestureRecognizer *)gestureRecognizer

    if ([gestureRecognizer view] == _profilePic)
    
        loadImageViewer = [ImageViewer alloc];
        [loadImageViewer loadImageIntoViewer:self imageToLoad:_profilePic.image];
    
    else if ([gestureRecognizer view] == _coverPhoto)
    

    

目标视图的.h

#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>

@protocol subViewDelegate
-(void)photoFromSubview:(id)sender;
@end

@interface ImageViewer : UIView

@property (nonatomic, assign) id <subViewDelegate> delegate;
@property (nonatomic, copy) UIImage *mainImage;
@property (nonatomic, copy) UIViewController *parentView;

- (void)fromCameraRoll;
- (void)takePhoto;
- (void)removeImageViewer;
- (void)captureImage:(id)sender;
- (void)uploadPhoto:(id)sender;
- (UIImage *)addBackground;
- (ImageViewer *)loadImageIntoViewer:(UIViewController *)superView imageToLoad:(UIImage *)imageToLoad;

@end

目标视图的.m

#import "ImageViewer.h"

@implementation ImageViewer : UIView

//synthesize properties
@synthesize mainImage = _mainImage;
@synthesize parentView = _parentView;

//initialize the image viewer
- (ImageViewer *)loadImageIntoViewer:(UIViewController *)superView imageToLoad:(UIImage *)imageToLoad

    //create a new view with the same frame size as the superView
    ImageViewer *imageViewer = [[ImageViewer alloc] initWithFrame:superView.view.bounds];
    _mainImage = imageToLoad;
    _parentView = superView;

    //if something's gone wrong, abort!
    if(!imageViewer)
    
        return nil;
    

    //add all components and functionalities to the program
    UIImageView *background = [[UIImageView alloc] initWithImage:[imageViewer addBackground]];
    background.alpha = 0.85;
    [imageViewer addSubview:background];
    [imageViewer addSubview:[imageViewer addImageToView:_mainImage superView:superView.view]];
    [imageViewer addSubview:[imageViewer addButtonToView:(superView.view.bounds.origin.x + 10.0) yPos:(superView.view.bounds.origin.x + 10.0) buttonAction:@selector(back:) buttonTitle:@"Back"]];
    [imageViewer addSubview:[imageViewer addButtonToView:(superView.view.bounds.origin.x + 10.0) yPos:((superView.view.center.y/2) + 270.0) buttonAction:@selector(captureImage:) buttonTitle:@"Camera"]];
    [imageViewer addSubview:[imageViewer addButtonToView:(superView.view.bounds.origin.x + 105.0) yPos:((superView.view.center.y/2) + 270.0) buttonAction:@selector(uploadPhoto:) buttonTitle:@"Upload"]];
    [imageViewer addSubview:[imageViewer addButtonToView:(superView.view.bounds.origin.x + 200.0) yPos:((superView.view.center.y/2) + 270.0) buttonAction:@selector(rotatePhoto:) buttonTitle:@"Rotate"]];
    [superView.view addSubview:imageViewer];

    return imageViewer;


//call delegate method
- (void)captureImage:(id)sender

    [self.delegate photoFromSubview:self];

我搞砸了不是吗?

【问题讨论】:

你能检查 - (void)captureImage:(id)sender 中的委托地址并验证它与父视图的值相同吗?这与属性 @property (nonatomic, copy) UIViewController *parentView; 相比如何?在子视图中定义? 【参考方案1】:

调试此问题的最佳方法是使用断点并查看调用了什么以及不调用什么(并检查您的委托是否设置正确)。在我的脑海中,我会说你要么忘记了代表的集合,要么可能是一个出口,如果你正在使用 IB。

编辑:好的,现在在我看来,您的委托属性在错误的类中。该属性应该在您的子视图中,并且从您的父视图创建该子视图时,您应该正确设置委托,如下所示:

mySubview.delegate = self;

【讨论】:

设置代理需要什么? 我已经编辑了评论,在我看来您将委托属性放在错误的类中。 委托属性已经在子视图中,子视图是 ImageViewer 的目标。 ImageViewer 在调用函数时将其自身添加为子视图 我应该只发布我在这方面工作了大约 6 个小时的完整资源吗?我通常需要 10 分钟才能把我的头发拉出来,并且会卖掉我的大部分内脏来获得这种体验 【参考方案2】:

您的 ProfileViewController.h 中似乎缺少 ImageViewer 的声明

@property (nonatomic, weak)  ImageViewer *imageViewer;

您需要在 ProfileViewController.m 中设置委托。

self.imageViewer.delegate = self;

【讨论】:

有没有办法让我发布代码,我认为这是因为我正在以一种非常奇怪的方式加载子视图。我们将不胜感激有关如何正确执行此操作的提示。 当我将它作为属性(非原子,弱)时,我只是将它用作局部变量 ImageViewer *imageViewer 它不加载属性(非原子,强) ImageViewer *imageViewer 有效,但我代表仍然不起作用@VGruenhagen【参考方案3】:

您需要将目标委托设置为自己。

ImageViewer *imageViewer = [[ImageViewer alloc] initWithFrame:superView.view.bounds];
imageViewer.delegate = self;

【讨论】:

我知道得到以下运行时异常 -[ImageViewer photoFromSubview]: unrecognized selector sent to instance 0x1c585ff0 @MarkM【参考方案4】:

当你有一个 UIView 在你初始化对象并调用你设置委托的加载方法之后加载它自己。

imageViewer.delegate = superView;

其中 imageView 是新初始化的视图,不要与对象 self 混淆(self.delegate = superView 不一样),而 superView 是创建 UIView 的父视图。

现在我的最后一个问题是有没有更好的方法来做我所做的事情?我觉得我把情况复杂化了。

【讨论】:

实际上我最终使用 Init 完成了我在 LoadImageIntoViewer 函数中所做的很多事情,这让事情变得更容易了!【参考方案5】:

我在完全相同的情况下遇到完全相同的问题。 经过一番头脑风暴后,我发现了问题并成功解决。

问题是 UIView 对象的范围。因此,要解决此问题,请在 .h 文件中创建一个全局视图对象并将其用作您的目标对象。

@interface profilePageViewController : parentViewController<PhotoUploadViewDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate,ConnectionsDelegate>

    PhotoUploadView *photoUploadView;

而且它肯定会工作,您也可以尝试通过将对象打印到其中,您会发现两个不同的对象。一个在初始化时,另一个在委托调用中。

【讨论】:

以上是关于视图控制器和 UIView 之间的简单委托不起作用的主要内容,如果未能解决你的问题,请参考以下文章

UIView 类中的 Swift 集合视图委托

iOS 的简单委托示例不起作用

自动滚动到顶部在 UITableView 中不起作用

UIView clipsToBounds不起作用

搜索栏子视图不起作用,搜索栏未调用 UITextField 委托方法

使用委托关闭视图不起作用