【问题标题】:Using presentViewController from UIView从 UIView 使用 presentViewController
【发布时间】:2013-03-25 19:05:56
【问题描述】:

我正在为我的 iOS 应用程序创建一个标题栏,并在 UIView 中创建它。我遇到的唯一问题是“主页按钮”。当home键被按下时,需要跳转到首页,也就是ViewController。

但是,[self presentViewController:vc animated:NO completion:NULL]; 似乎不适用于 UIView。

我该如何解决这个问题?

- (void) createTitlebar {

    CGRect titleBarFrame = CGRectMake(0, 0, 320, 55);

    //Create the home button on the top right of the page. When clicked, it will navigate to the home page of the application
    homeButton = [UIButton buttonWithType:UIButtonTypeCustom];
    homeButton.frame = CGRectMake(275, 10, 40, 40);
    [homeButton setTag:1];
    [homeButton setImage:[UIImage imageNamed:@"homeIcon.png"] forState:UIControlStateNormal];
    [homeButton addTarget:self action:@selector(homeButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
    [self addSubview:homeButton];
}

- (IBAction)homeButtonPressed:(id)sender{

    //Transition to the submit button page
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    ViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"ViewController"];
    [vc setModalPresentationStyle:UIModalPresentationFullScreen];
    [self presentViewController:vc animated:NO completion:NULL];
}

【问题讨论】:

  • 您是否将选择器添加到您的按钮? IE。按钮是否知道执行哪种方法?其次,尝试使用 popToRootViewControllerAnimated 来避免循环。
  • 我遇到的错误消息是 - 'TitleBar' 没有可见的@interface 声明选择器 presentViewController:animated:completion
  • 这个 homeButtonPressed: 方法定义在哪里?它在任何视图控制器或某个视图中吗?
  • 确保您的 ViewController 是 UIViewController 子类。
  • 它是一个UIViewController 子类

标签: ios objective-c xcode ios6 presentviewcontroller


【解决方案1】:

您可以在不使用委托模式的情况下执行此操作。给你

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........

【讨论】:

  • 经过至少 20 次委托模式以在我的应用程序中从我的视图呈现视图控制器后,我真的厌倦了这样做。因此,这个答案对我来说就像沙漠中的绿洲。非常感谢
  • 很高兴听到:)
  • 这行得通,谢谢。但是我确实有一个情况。有没有办法可以用 viewController 代替 keyWindow 作为 topVC?
【解决方案2】:

只有 UIViewController 可以呈现另一个视图控制器,所以如果你需要从视图中显示一个视图控制器,有几种方法,其中一种是这样的:

创建一个视图控制器,你的父视图位于它的代表

ParentView *view = [ParentView new];
...
view.delegate = self;

然后,在该委托的 ParentView 调用方法中

- (IBAction)homeButtonPressed:(id)sender {
    [self.delegate buttonPressed];
}

然后,在您的 VC 实现中

 -(void)buttonPressed {
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    ViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"ViewController"];
    [vc setModalPresentationStyle:UIModalPresentationFullScreen];
    [self presentViewController:vc animated:NO completion:NULL];
}

如果您需要将此代码保留在 UIView 中并避免委托,您可以做一个这样的技巧(我个人不喜欢它,但它应该可以工作)

-(void)buttonPressed{
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    ViewController *vc = [storyboard      instantiateViewControllerWithIdentifier:@"ViewController"];
    [vc setModalPresentationStyle:UIModalPresentationFullScreen];
    [(UIViewController*)self.nextResonder presentViewController:vc animated:NO completion:NULL];
}

【讨论】:

  • 我收到消息 Property delegate not found on object of type .. 对于 UIView 和 UIViewController
  • 哦,对不起,我忘了提这个 - 你必须像这样在 ParentView.h 中创建这个属性:@property(nonatomic,weak) id delegate
  • 是 (IBAction)homeButtonPressed 还是 -(void)buttonPressed 调用?你也为 UIButton 设置了目标动作吗?
  • 我是在编写代码以在 UIView 或 UIViewController 中进行委托吗?
  • 在 UIViewController 中,您将其设置为 UIView 的委托。在您的代码中也找不到这样的东西 [homeButton addTarget:self action:@selector(homeButtonPressed:)];?你确定按钮知道调用什么方法吗?
【解决方案3】:

这是 Shamsudheen 回答的更惯用的 Swift 3 版本:

extension UIApplication {

    static func topViewController() -> UIViewController? {
        guard var top = shared.keyWindow?.rootViewController else {
            return nil
        }
        while let next = top.presentedViewController {
            top = next
        }
        return top
    } 
}

然后你可以打电话:

UIApplication.topViewController()?.present(...)

【讨论】:

    【解决方案4】:

    使用 Swift 4 - 4.2 添加到 Shamsudheen TK 的答案。

    var topVC = UIApplication.shared.keyWindow?.rootViewController
        while((topVC!.presentedViewController) != nil) {
            topVC = topVC!.presentedViewController
        }
        let customViewController = CustomViewController()
        topVC?.present(customViewController, animated: true, completion: nil)
    

    使用 UINavigationController: 这里还有一个附加功能 -> 您可以将 UINavigationController 与您的 customViewController 一起传递。

     var topVC = UIApplication.shared.keyWindow?.rootViewController
        while((topVC!.presentedViewController) != nil) {
            topVC = topVC!.presentedViewController
        }
        let customViewController = CustomViewController()
        let navController = UINavigationController(rootViewController: CustomViewController)
        topVC?.present(navController, animated: true, completion: nil)
    

    【讨论】:

      【解决方案5】:

      你可以试试下面的代码

       UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
       ViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"ViewController"];
       UIViewController *vc1 = [UIApplication sharedApplication].keyWindow.rootViewController;
       [vc1 presentViewController:vc animated:YES completion:nil]; 
      

      【讨论】:

        【解决方案6】:

        使用 Swift 5 (ios 13+)

        guard let topVC = UIApplication.shared.windows.filter({$0.isKeyWindow}).first?.rootViewController else { return }
            let customViewController = CustomViewController()
            topVC.present(customViewController, animated: true, completion: nil)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多