从另一个类添加视图作为presentViewController导致UIEvents无法正常工作

时间:2017-07-04 02:52:05

标签: ios objective-c uiview uiviewcontroller

我正在尝试使用UIElements构建一个简单的库。我想要做的是,从一个类实例创建UIViewController对象,并使用presentViewController方法在当前VC堆栈上推送新的ViewController。

我可以看到UIElements已成功添加到堆栈中,但GestureRecognizer和UIButton的目标不起作用。当我查看ViewDebug时,这些设置为<NSNull null>

这是我的类方法,我正在创建UI并放置当前视图堆栈。

-(void)displayAd{

    dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
        //Background Thread
        NSData * imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:fullpageCampaign.mainImage]];

        dispatch_async(dispatch_get_main_queue(), ^(void){
            //Run UI Updates
            fullPageView = [[UIViewController alloc] init];
            fullPageView.view.frame = CurrentVC.view.bounds;
            fullPageView.view.backgroundColor = [UIColor redColor];
            UIImageView *staticImageView = [[UIImageView alloc] init];
            staticImageView.frame = CurrentVC.view.frame;

            UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapDetected)];
            singleTap.numberOfTapsRequired = 1;
            [staticImageView addGestureRecognizer:singleTap];
            staticImageView.userInteractionEnabled = YES;
            [fullPageView.view addSubview:staticImageView];

            staticImageView.image = [UIImage imageWithData:imageData];
            [CurrentVC.view addSubview:fullPageView.view];
            //[fullPageView didMoveToParentViewController:self];
            [CurrentVC presentViewController:fullPageView animated:YES completion:^{
                NSLog(@"Tagon Ads is about to showing.");
                UIButton *closeButton = [self createButtonWithAssetName:@"tagonAssets.bundle/close_button" TargetMethod:@"closeModal" andView:staticImageView];
                [staticImageView addSubview:closeButton];
                [CurrentVC.view bringSubviewToFront:closeButton];
            }];
        });
    });
}

CurrentVC是我通过我的库方法作为参数发送的当前viewController,以便向其添加新的viewController堆栈。

2 个答案:

答案 0 :(得分:1)

closeModal行动在哪里?可能与您的currentVC相同。如果是这样,您的closeButton引用了currentVC,但您已经从那里转到fullPageView。所以,你的按钮失去了他的参考。

只需创建新的控制器,在那里发送imageData,创建自定义初始值设定项,在其中创建新的UIImageViewUIButton。通过这种方式,您的按钮将成为引用自己的根,您的问题应该得到解决。

答案 1 :(得分:0)

您的代码存在一些问题,但首先,我建议采用不同的方法来完成您想要的任务。如您所见,使用UIViewController的实例不是推荐的方法。而是使用 storyboard 来设置视图控制器及其组件。您的代码将更小,您的设计将易于理解和更改。

You can read more about UIViewController here

  

您很少直接创建UIViewController类的实例。   相反,您可以创建UIViewController子类的实例并使用   那些提供特定行为和视觉外观的物体   你需要的。

这是另一种潜力。 fullpageCampaign.mainImage是远程还是本地居住?如果位于远程位置,则应考虑改为NSURLSession

Read more about NSData:dataWithContentsOfURL here

  

请勿使用此同步方法来请求基于网络的网址。对于   基于网络的URL,此方法可以阻止当前线程为数十   慢速网络上的秒数,导致用户体验不佳,以及   在iOS中,可能会导致您的应用被终止。

另一个小问题是您将按钮添加到图像视图。虽然这没关系,并且在允许用户交互图像视图时可能有效,但更简洁的方法是创建一个UIView容器来保存图像视图和按钮。然后,容器也可以是您将点击手势识别器附加到的视图。这样,图像视图就可以保持纯粹的图像。

故事板方法

首先,创建一个UIIViewController的子类。看起来应该是这样的:

FullPageViewController.h

#import <UIKit/UIKit.h>

@interface FullPageViewController : UIViewController

- (void)setImage:(UIImage *)adImage;

@end

FullPageViewController.m

#import "FullPageViewController.h"

@interface FullPageViewController ()

@property (weak, nonatomic) IBOutlet UIImageView *adImageView;

@end

@implementation FullPageViewController

- (void)setImage:(UIImage *)adImage {
    self.adImageView.image = adImage;
}

- (IBAction)tappedOnAd:(UIGestureRecognizer *)sender {
    if (sender.state == UIGestureRecognizerStateEnded) {
        // Do your ad thing here
    }
}

- (IBAction)closeButtonPressed:(UIButton *)sender {
    [self dismissViewControllerAnimated:YES completion:nil];
}

@end

其次,创建一个故事板并将广告视图控制器添加到其中。然后向视图控制器添加图像视图,按钮和点击手势识别器。应该在图像视图上放下点击手势识别器以从那里捕获点击。您可以从右侧的对象库中提取所有这些对象。还要记住为图像视图启用用户交互。酒店页面上有一处房产。

你现在应该有这样的东西:

Storyboard for ad page

请注意右上角的类名,它应该是您刚刚创建的新视图控制器类的名称。还要注意从代码实例化视图控制器时所需的故事板ID adVC

下一步是连接对象。选择图像视图,然后从引用插座下的插座(环)拖动到位于视图控制器窗口顶部的视图控制器图标(带方框的黄色图标),然后选择{ {1}}。手势识别器应该已经连接,如果您在之前放置它时将其放在图像视图上。

Connecting the image view

接下来,连接关闭按钮的操作。从Touch Up Inside插座拖动到视图控制器图标(黄色),然后选择adImageView方法。

Connecting the close button

接下来,将点击手势识别器连接到您的代码。从左侧列表中选择它,然后从已发送操作拖动到视图控制器图标,然后选择closeButtonPressed:

Connecting the gesture recognizer

最后,展示广告的代码看起来像这样。此方法属于您的父视图控制器。

tappedOnAd: