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你的视图,完全不知道他们在哪里。 他们通常只知道用户交互。
所以首先,你必须做的是重构你的观点。
- 如果你的
UIView
应该是一个UIControl
(有一些目标select器),你需要在控制器中使用add target从视图交互中获取callback。 - 您可以使用
UITableView
或UICollectionView
使用的委托模式,该模式是作为协议而devise的。 - 您可以使用添加到视图中的手势识别器(例如
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
是不是UIView
的UIViewController
类的方法,你可以做一件事情,创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,以允许视图控制器控制交互。