簡體   English   中英

iOS 如何從 Uiview 呈現 Modal ViewController

[英]iOS how present Modal ViewController from Uiview

我有一個UIView的子類,現在我需要顯示一個視圖 controller 但UIView沒有方法來呈現視圖 Z59038ABAZ03F2C6E04 這是我的問題謝謝

這是我的 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不能真正呈現新的 controller (缺少presetViewController:animated:completion方法或navigationController控制器屬性,它們都存在於UIViewController中)。

視圖應該是代碼中最可重用的部分,因此您必須想辦法將視圖設計為完全看不到它們所在的位置。 他們通常只知道用戶交互。

所以首先,你必須做的是重構你的視圖。

  1. 如果您的UIView應該是UIControl (具有某種目標選擇器),則需要在 controller 中使用 add target 從視圖交互中獲取回調。
  2. 您可以使用設計為協議的UITableViewUICollectionView中使用的委托模式。
  3. 您可以使用添加到視圖的手勢識別器(例如UITapGestureRecognizer ),因此 controller 知道用戶交互。

您甚至可以混合和匹配這些架構模式。

但是您應該真正了解iOS 編程基礎知識,以便更好地理解這一點。

此外,我在您的代碼中看到的第一個錯誤是您創建了一個通用UIViewController ,當您真正應該創建它的自定義子類時,在 Storyboard 和UIViewController的單獨子類中定義。

我看到的第二個錯誤是您的UIView響應 do tableView:didSelectRowAtIndexPath:方法,實際上這應該永遠不會發生。 所有這些代碼都必須移回一個UIViewController子類。

您可以使用以下代碼在沒有任何視圖層次結構問題的情況下執行此操作。

客觀C

UIViewController *currentTopVC = [self currentTopViewController];
currentTopVC.presentViewController......... 

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

Swift

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

PresentViewController is method of UIViewController class not of UIView , you can do one thing, create UIViewController instance and set its view to the view you have and then present it. 像下面的東西

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 中實現,並且在將 customView 設置為其視圖屬性的 presentViewController 中

您還可以從導航 controller object 中展示您的視圖控制器

在 App Delegate 或任何地方創建全局導航 Object,您可以從視圖中訪問導航控制器 object

@property (strong, nonatomic) UINavigationController *gblNavigation;

//從 NavigationController object 呈現視圖控制器

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

您無法從視圖中呈現視圖 controller。 您只能從視圖 controller 中呈現視圖 controller。

蘋果希望觀點是愚蠢的。 那就是視圖應該只知道如何顯示內容。 視圖不應響應用戶交互:應傳遞給視圖 controller。

您可能需要考慮使用委托模式、目標操作或類似的東西來允許視圖 controller 控制交互。

iOS 15,兼容低至 iOS 13

基於 Shamsudheen TK 解決方案,適用於將來遇到此問題的任何人。

let presentedWindow = UIApplication.shared.connectedScenes.flatMap { ($0 as? UIWindowScene)?.windows ?? [] }.first { $0.isKeyWindow }
guard let currentViewController = presentedWindow?.rootViewController else {
  return
}
currentViewController.present(UIViewController(nibName: nil, bundle: nil), animated: true)

請注意,connectedScenes 僅在 iOS 13 之后可用。如果您需要支持 iOS 的早期版本,則必須將其放在 if #available(iOS 13, *) 語句中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM