将另一个类的视图添加为 presentViewController 会导致 UIEvents 不起作用
Posted
技术标签:
【中文标题】将另一个类的视图添加为 presentViewController 会导致 UIEvents 不起作用【英文标题】:Adding view from another class as presentViewController causes UIEvents not working 【发布时间】:2017-07-04 02:52:04 【问题描述】:我正在尝试使用有效的 UIElements 构建一个简单的库。我想做的是,从一个类实例创建 UIViewController 对象,并使用 presentViewController 方法将新的 ViewController 推送到当前 VC 堆栈上。
我可以看到 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 堆栈。
【问题讨论】:
查看***.com/questions/32964884/… 你确定这个链接和我的问题有关吗? 尝试设置 CurrentVC.view.clipsToBounds = YES;如果您的 ui 元素消失,则意味着您设置 CurrentVC.view.frame 不正确 我的 UIElements 并没有消失,它们只是不能像 GestureRecognizer、UIButton target 和 @selectors 等一样设置 Target 和 UIEvents。 请问,如果您已经将 fullPageView 的视图添加为子视图,为什么还要在CurrentVC
上显示 fullPageView
?
【参考方案1】:
closeModal
操作在哪里?可能与您的currentVC
相同。如果是这样,您的closeButton
引用了currentVC
,但您已经从那里转到fullPageView
。所以,你的按钮失去了他的参考。
只需创建新控制器,在那里发送imageData
,创建自定义初始化程序,在那里创建新的UIImageView
和UIButton
。这样,您的按钮将引用自己的根,您的问题应该得到解决。
【讨论】:
解决了我的问题,谢谢!从 xcode 创建一个新的视图控制器并在自定义类上分配它解决了固体:D【参考方案2】:您的代码有几个问题,但首先,我会推荐一种不同的方法来完成您想要的。正如您在下面看到的,不推荐使用UIViewController
的实例。相反,请使用 storyboard 来设置您的视图控制器及其组件。您的代码会更小,您的设计将易于理解和更改。
You can read more about UIViewController here
您很少直接创建 UIViewController 类的实例。 相反,您创建 UIViewController 子类的实例并使用 这些对象提供特定的行为和视觉外观 你需要的。
这是另一个潜力。 fullpageCampaign.mainImage
是远程还是本地?如果位于远程,则应考虑改为NSURLSession
。
Read more about NSData:dataWithContentsOfURL here
不要使用这种同步方法来请求基于网络的 URL。为了 基于网络的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
其次,创建一个故事板并将您的广告视图控制器添加到其中。然后将一个图像视图、一个按钮和一个点击手势识别器添加到您的视图控制器。点击手势识别器应该放在图像视图上以从那里捕获点击。您从 Object Library 中拉出所有这些对象。还记得为图像视图启用用户交互。在属性页面上有一个属性。
你现在应该有这样的东西:
注意右上角的类名,它应该是您刚刚创建的新视图控制器类的名称。还要注意从代码实例化视图控制器时需要的情节提要 ID adVC
。
下一步是连接对象。选择图像视图,然后从 Referencing Outlets 下的出口(圆环)拖动到位于视图控制器窗口顶部的视图控制器图标(带有正方形的黄色图标),然后选择 @ 987654337@。手势识别器应该已经连接,如果您在之前放置它时将其放在图像视图上。
接下来,连接关闭按钮的操作。从 Touch Up Inside 插座拖动到视图控制器图标(黄色),然后选择 closeButtonPressed:
方法。
接下来,将点击手势识别器连接到您的代码。从左侧列表中选择它,然后从 Sent Actions 拖动到视图控制器图标并选择 tappedOnAd:
。
最后,您展示广告的代码如下所示。此方法属于您的父视图控制器。
-(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
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"AdPage" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"adVC"];
[vc setImage:[UIImage imageWithData:imageData]];
[self presentViewController:vc animated:YES completion:^];
);
);
【讨论】:
您描述的方法是标准且有效的,但我在架构上的主要方法是创建库,它将是静态的,开发人员不会看到代码、手势和 UIView 元素。根据您的建议,该项目必须是公开的,并且需要使用情节提要实施一些步骤。以上是关于将另一个类的视图添加为 presentViewController 会导致 UIEvents 不起作用的主要内容,如果未能解决你的问题,请参考以下文章
将另一个网站添加为 serverMiddleware 的 Nuxt 模块