热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

全屏显示iOS13中的模态

如何解决《全屏显示iOS13中的模态》经验,为你挑选了11个好方法。

在iOS 13 Beta 1中,出现模态视图控制器时有新行为。现在默认情况下它不是全屏显示,当我尝试向下滑动时,该应用程序会自动关闭View Controller。

如何防止这种行为并回到旧的好全屏模式vc?

谢谢



1> pascalbros..:

如WWDC 2019期间平台联盟中所述,使用iOS 13,Apple引入了新的默认卡演示文稿。为了强制全屏,您必须使用以下命令明确指定它:

let vc = UIViewController()
vc.modalPresentatiOnStyle= .fullScreen //or .overFullScreen for transparency
self.present(vc, animated: true, completion: nil)


我会说这不会在默认情况下持续很长时间。“ fullScreen”选项应为默认设置,以防止破坏UI更改。
我不会指望这一点。过去,Apple经常更改默认设置,仅在与当前SDK链接后才激活默认设置。与以前的版本链接时,我们将“希望”获得旧的行为。
我可以确认在iOS 13模拟器上运行的Xcode-10构建的应用程序仍默认为全屏显示。正如@DrMickeyLauer所说,使用Xcode 11进行构建会使该应用程序采用新的行为。使用`isModalInPresentation`阻止取消滑动手势。有关更多详细信息,请参见我的博客文章:https://medium.com/@hacknicity/view-controller-presentation-changes-in-ios-13-ac8c901ebc4e
时间已经过去,.automatic样式已确定为默认样式,(对于大多数视图控制器而言)为.pageSheet样式。但是,某些系统视图控制器可能会将其映射为其他样式。
我建议使用.fullScreen而不是.overFullScreen。.fullScreen触发viewWillAppear和viewDidAppear,.overFullScreen则不执行

2> 小智..:

我添加了对某人可能有用的信息。如果您有任何故事板segue,那么要回到旧样式,需要将kind属性设置为Present Modally并将Presentation属性设置为Full Screen



3> davidbates..:

在启动屏幕之后的初始视图中,我遇到了这个问题。因为没有定义顺序或逻辑,所以对我的解决方法是将演示文稿从自动切换到全屏,如下所示:



4> Abedalkareem..:

有多种方法可以做到这一点,我认为每个项目都可以适合一个项目,但又不适合另一个项目,所以我认为我会保留在这里,也许其他人会遇到不同的情况。

1-覆盖存在

如果您有一个BaseViewController,则可以覆盖该present(_ viewControllerToPresent: animated flag: completion:)方法。

class BaseViewController: UIViewController {

  // ....

  override func present(_ viewControllerToPresent: UIViewController,
                        animated flag: Bool,
                        completion: (() -> Void)? = nil) {
    viewControllerToPresent.modalPresentatiOnStyle= .fullScreen
    super.present(viewControllerToPresent, animated: flag, completion: completion)
  }

  // ....
}

使用这种方式,您无需对任何present调用进行任何更改,因为我们只是覆盖了该present方法。

2-扩展名:

extension UIViewController {
  func presentInFullScreen(_ viewController: UIViewController,
                           animated: Bool,
                           completion: (() -> Void)? = nil) {
    viewController.modalPresentatiOnStyle= .fullScreen
    present(viewController, animated: animated, completion: completion)
  }
}

用法:

presentInFullScreen(viewController, animated: true)

3-对于一个UIViewController

let viewCOntroller= UIViewController()
viewController.modalPresentatiOnStyle= .fullScreen
present(viewController, animated: true, completion: nil)

4-从情节提要

选择一个序列并将演示文稿设置为FullScreen

5-晃动

extension UIViewController {

  static func swizzlePresent() {

    let orginalSelector = #selector(present(_: animated: completion:))
    let swizzledSelector = #selector(swizzledPresent)

    guard let orginalMethod = class_getInstanceMethod(self, orginalSelector), let swizzledMethod = class_getInstanceMethod(self, swizzledSelector) else{return}

    let didAddMethod = class_addMethod(self,
                                       orginalSelector,
                                       method_getImplementation(swizzledMethod),
                                       method_getTypeEncoding(swizzledMethod))

    if didAddMethod {
      class_replaceMethod(self,
                          swizzledSelector,
                          method_getImplementation(orginalMethod),
                          method_getTypeEncoding(orginalMethod))
    } else {
      method_exchangeImplementations(orginalMethod, swizzledMethod)
    }

  }

  @objc
  private func swizzledPresent(_ viewControllerToPresent: UIViewController,
                               animated flag: Bool,
                               completion: (() -> Void)? = nil) {
    if #available(iOS 13.0, *) {
      if viewControllerToPresent.modalPresentatiOnStyle== .automatic {
        viewControllerToPresent.modalPresentatiOnStyle= .fullScreen
      }
    }
    swizzledPresent(viewControllerToPresent, animated: flag, completion: completion)
   }
}

用法:
在您的AppDelegate内部application(_ application: didFinishLaunchingWithOptions)添加以下行:

UIViewController.swizzlePresent()

使用这种方法,您不需要在任何当前调用上进行任何更改,因为我们正在运行时替换当前方法的实现。
如果您想知道什么在泛滥,可以查看以下链接:https : //nshipster.com/swift-objc-runtime/



5> 9to5ios..:

对于Objective-C用户

只需使用此代码

 [vc setModalPresentationStyle: UIModalPresentationFullScreen];

或者,如果要在iOS 13.0中添加它,请使用

 if (@available(iOS 13.0, *)) {
     [vc setModalPresentationStyle: UIModalPresentationFullScreen];
 } else {
     // Fallback on earlier versions
 }


UIModalPresentationFullScreen可与iOS 3.2及更高版本一起使用。因此,如果没有其他条件,则无需添加。
这也适用于早期的ios版本,但是答案很好
由于某些原因,仅在iOS 13.1.2中,仅在Obj-c类中,此方法不起作用,而modalPresentationStyle仅显示pageSheet。这会发生在其他人身上吗?

6> kuzdu..:

提示:如果您对存在于ViewController内嵌的的调用present ,则NavigationController必须将设置为NavigationController.fullScreen而不是VC。

您可以像@davidbates一样执行此操作,也可以通过编程方式(例如@pascalbros)来执行。

一个示例场景:

    //BaseNavigationController: UINavigationController {}
    let baseNavigatiOnController= storyboard!.instantiateViewController(withIdentifier: "BaseNavigationController")
    var navigatiOnController= UINavigationController(rootViewController: baseNavigationController)
    navigationController.modalPresentatiOnStyle= .fullScreen
    navigationController.topViewController as? LoginViewController
    self.present(navigationViewController, animated: true, completion: nil)



7> Maxime Ashur..:

我在iOS 13上使用了swizzling

import Foundation
import UIKit

private func _swizzling(forClass: AnyClass, originalSelector: Selector, swizzledSelector: Selector) {
    if let originalMethod = class_getInstanceMethod(forClass, originalSelector),
       let swizzledMethod = class_getInstanceMethod(forClass, swizzledSelector) {
        method_exchangeImplementations(originalMethod, swizzledMethod)
    }
}

extension UIViewController {

    static let preventPageSheetPresentation: Void = {
        if #available(iOS 13, *) {
            _swizzling(forClass: UIViewController.self,
                       originalSelector: #selector(present(_: animated: completion:)),
                       swizzledSelector: #selector(_swizzledPresent(_: animated: completion:)))
        }
    }()

    @available(iOS 13.0, *)
    @objc private func _swizzledPresent(_ viewControllerToPresent: UIViewController,
                                        animated flag: Bool,
                                        completion: (() -> Void)? = nil) {
        if viewControllerToPresent.modalPresentatiOnStyle== .pageSheet
                   || viewControllerToPresent.modalPresentatiOnStyle== .automatic {
            viewControllerToPresent.modalPresentatiOnStyle= .fullScreen
        }
        _swizzledPresent(viewControllerToPresent, animated: flag, completion: completion)
    }
}

然后把这个

UIViewController.preventPageSheetPresentation

某处

例如在AppDelegate中

func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]?) -> Bool {

    UIViewController.preventPageSheetPresentation
    // ...
    return true
}



8> Di Nerd..:

如果您的UITabController具有带嵌入式导航控制器的屏幕,则必须将UITabController Presentation设置为FullScreen,如下图所示



9> Mahesh Cheli..:

这是一个简单的解决方案,无需编码一行。

在情节提要中选择视图控制器

选择属性检查器

如下图所示,将演示文稿“自动”设置为“全屏”

此更改使iPad应用程序的行为符合预期,否则新屏幕将在弹出窗口的中央显示。



10> 小智..:

所有其他答案都足够了,但是对于像我们这样的大型项目来说,无论是在代码还是在情节提要中进行导航,这都是一项艰巨的任务。

对于那些正在积极使用Storyboard的人。这是我的建议:使用Regex。

以下格式不适用于全屏页面:


以下格式适合全屏页面:


以下与VS CODE兼容的正则表达式会将所有旧样式页面转换为新样式页面。如果您使用其他正则表达式引擎/文本编辑器,则可能需要转义特殊字符。

搜索正则表达式


替换正则表达式




11> 小智..:

这是Objective-C的解决方案

UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
ViewController *vc = [storyBoard instantiateViewControllerWithIdentifier:@"ViewController"];

vc.modalPresentatiOnStyle= UIModalPresentationFullScreen;

[self presentViewController:vc animated:YES completion:nil];


推荐阅读
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • 采用IKE方式建立IPsec安全隧道
    一、【组网和实验环境】按如上的接口ip先作配置,再作ipsec的相关配置,配置文本见文章最后本文实验采用的交换机是H3C模拟器,下载地址如 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • ASP.NET MVC中Area机制的实现与优化
    本文探讨了在ASP.NET MVC框架中,如何通过Area机制有效地组织和管理大规模应用程序的不同功能模块。通过合理的文件夹结构和命名规则,开发人员可以更高效地管理和扩展项目。 ... [详细]
  • 实体映射最强工具类:MapStruct真香 ... [详细]
  • 本文详细介绍如何在Linux系统中配置SSH密钥对,以实现从一台主机到另一台主机的无密码登录。内容涵盖密钥对生成、公钥分发及权限设置等关键步骤。 ... [详细]
  • 本文详细介绍了Grand Central Dispatch (GCD) 的核心概念和使用方法,探讨了任务队列、同步与异步执行以及常见的死锁问题。通过具体示例和代码片段,帮助开发者更好地理解和应用GCD进行多线程开发。 ... [详细]
  • 深入解析SpringMVC核心组件:DispatcherServlet的工作原理
    本文详细探讨了SpringMVC的核心组件——DispatcherServlet的运作机制,旨在帮助有一定Java和Spring基础的开发人员理解HTTP请求是如何被映射到Controller并执行的。文章将解答以下问题:1. HTTP请求如何映射到Controller;2. Controller是如何被执行的。 ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ... [详细]
  • 本文详细介绍了中央电视台电影频道的节目预告,并通过专业工具分析了其加载方式,确保用户能够获取最准确的电视节目信息。 ... [详细]
  • 本文详细探讨了JDBC(Java数据库连接)的内部机制,重点分析其作为服务提供者接口(SPI)框架的应用。通过类图和代码示例,展示了JDBC如何注册驱动程序、建立数据库连接以及执行SQL查询的过程。 ... [详细]
  • dotnet 通过 Elmish.WPF 使用 F# 编写 WPF 应用
    本文来安利大家一个有趣而且强大的库,通过F#和C#混合编程编写WPF应用,可以在WPF中使用到F#强大的数据处理能力在GitHub上完全开源Elmis ... [详细]
  • 本文介绍如何在Spring Boot项目中集成Redis,并通过具体案例展示其配置和使用方法。包括添加依赖、配置连接信息、自定义序列化方式以及实现仓储接口。 ... [详细]
author-avatar
手机用户2502902993
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有