iOS如何从Uiview中呈现Modal ViewController

我有一个UIView子类,现在我需要显示一个视图控制器,但UIView没有方法来呈现视图控制器。 这是我的问题谢谢

这是我的uiview子类中的一段代码

 -(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ if ([tabella isEqualToString:@"Articoli"]) { NSDictionary *itm=(NSDictionary*)[comanda objectAtIndex:indexPath.row]; Articoli *aboutViewController = [[Articoli alloc] initWithNibName:@"Articoli" bundle:nil]; aboutViewController.modalPresentationStyle = UIModalPresentationFormSheet; aboutViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical; aboutViewController.idarticolo=[itm objectForKey:@"idarticolo"]; CGRect aboutSheetFrame = aboutViewController.view.frame; UIViewController *viewController = [UIViewController new]; viewController.view = self; //here xcode give me a red error [self presentViewController:viewController animated:YES completion:nil] ; aboutSheetFrame =CGRectZero; aboutViewController.view.superview.bounds = aboutSheetFrame; } } 

当你需要UIView实例和UIViewController之间的通信时,有一些你应该坚持的已知的iOS概念。 正如你已经知道, UIView不能真正呈现一个新的控制器(缺lesspresetViewController:animated:completion方法或navigationController控制器属性,都存在于UIViewController )。

视图应该是你的代码中最可重用的部分,所以你必须想出一种方法来devise你的视图,完全不知道他们在哪里。 他们通常只知道用户交互。

所以首先,你必须做的是重构你的观点。

  1. 如果你的UIView应该是一个UIControl (有一些目标select器),你需要在控制器中使用add target从视图交互中获取callback。
  2. 您可以使用UITableViewUICollectionView使用的委托模式,该模式是作为协议而devise的。
  3. 您可以使用添加到视图中的手势识别器(例如UITapGestureRecognizer ),以便控制器了解用户交互。

你甚至可以混合搭配那些build筑模式。

但是你应该仔细研究 iOS编程的基础知识,以更好地理解这一点。

另外,我在你的代码中看到的第一个错误是你创build了一个通用的UIViewController ,当你真的应该创build它的自定义子类,在Storyboard中定义和单独的UIViewController子类。

我看到的第二个错误是,您的UIView响应做tableView:didSelectRowAtIndexPath:方法,实际上应该不会发生。 所有这些代码必须移回到一个UIViewController子类。

您可以使用下面的代码在没有任何视图层次结构问题的情况下执

的ObjectiveC

 UIViewController *currentTopVC = [self currentTopViewController]; currentTopVC.presentViewController......... - (UIViewController *)currentTopViewController { UIViewController *topVC = [[[[UIApplication sharedApplication] delegate] window] rootViewController]; while (topVC.presentedViewController) { topVC = topVC.presentedViewController; } return topVC; } 

迅速

 var topVC = UIApplication.sharedApplication().keyWindow?.rootViewController while((topVC!.presentedViewController) != nil){ topVC = topVC!.presentedViewController } topVC?.presentViewController........ 

PresentViewController是不是UIViewUIViewController类的方法,你可以做一件事情,创buildUIViewController实例,并将其视图设置为你有的视图,然后呈现它。 像下面的东西

 YourCustomView *customView = [[YourCustomView alloc]initWithFrame:someFrame]; UIViewController *viewController = [UIViewController new]; viewController.view = customView; //From currentViewController present this [self presentViewController:viewController animated:YES completion:nil] ; 

根据您的要求自定义此代码

但是正如你所看到的,你需要把这个事件传递给viewController,所以最好实现委托方法,并且在你调用当前viewController的地方调用在ViewController中实现的delegate,并且将presentViewController的customView设置为view属性

您还可以从导航控制器对象中呈现您的视图控制器

在App Delegate或任何地方创build全局导航对象,您可以从视图访问navigationcontroller对象

 @property (strong, nonatomic) UINavigationController *gblNavigation; 

//从NavigationController对象中呈现viewcontroller

 [gblNavigation presentViewController:YOUR_VC_Object animated:YES completion:nil]; 

您不能从视图中呈现视图控制器。 您只能从视图控制器呈现视图控制器。

苹果希望意见是愚蠢的。 那就是视图应该只知道如何显示内容。 视图不应该响应用户交互:应该传递给视图控制器。

您可能需要考虑使用委托模式,目标操作或类似的function,以允许视图控制器控制交互。