นำเสนอ modal ใน iOS 13 แบบเต็มหน้าจอ


465

ใน iOS 13 มีพฤติกรรมใหม่สำหรับตัวควบคุมมุมมอง modal เมื่อถูกนำเสนอ

ตอนนี้มันไม่เต็มจอตามค่าเริ่มต้นและเมื่อฉันพยายามที่จะเลื่อนลงแอพก็แค่ยกเลิก View Controller โดยอัตโนมัติ

ฉันจะป้องกันพฤติกรรมนี้และกลับไปเป็น modal vc แบบเต็มหน้าจอเก่าได้อย่างไร

พฤติกรรมกิริยา

ขอบคุณ

คำตอบ:


622

ด้วย iOS 13 ดังที่ระบุไว้ในPlatforms State of Unionในช่วง WWDC 2019 Apple ได้เปิดตัวการนำเสนอบัตรเริ่มต้นใหม่ ในการบังคับให้เต็มหน้าจอคุณต้องระบุอย่างชัดเจนด้วย:

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

81
ฉันจะบอกว่านี่จะไม่อยู่นานตามค่าเริ่มต้น fullScreenตัวเลือกที่ควรจะเริ่มต้นที่จะป้องกันการเปลี่ยนแปลง UI ทำลาย
Jakub Truhlář

17
ฉันจะไม่นับมัน ในอดีต Apple มักจะเปลี่ยนค่าเริ่มต้นจะเปิดใช้งานเฉพาะเมื่อคุณเชื่อมโยงกับ SDK ปัจจุบันเท่านั้น เราหวังว่าจะได้รับพฤติกรรมเก่าเมื่อเชื่อมโยงกับรุ่นก่อนหน้า
DrMickeyLauer

11
ฉันสามารถยืนยันได้ว่าแอปที่สร้างจาก Xcode-10 ทำงานบนตัวจำลอง iOS 13 ยังคงเป็นค่าเริ่มต้นเป็นแบบเต็มหน้าจอ ในฐานะที่เป็น @DrMickeyLauer กล่าวว่าการสร้างด้วย Xcode 11 จะเป็นการเปิดแอปในลักษณะการทำงานใหม่ ใช้isModalInPresentationเพื่อป้องกันท่าทางการปัดด้วยการปัด ดูโพสต์บล็อกของฉันสำหรับรายละเอียดเพิ่มเติม: medium.com/@hacknicity/…
Geoff Hackworth

5
ฉันแนะนำให้ใช้. fullScreen แทน. overFullScreen .fullScreen fires viewWillAppear และ viewDidAppear, .overFullScreen ไม่ได้ทำเช่นนั้น
PiterPan

5
เวลาได้ผ่านการและ.automaticรูปแบบได้ตัดสินลงเป็นหนึ่งเริ่มต้นซึ่งเป็น (ส่วนใหญ่ควบคุมมุมมอง) .pageSheetสไตล์ อย่างไรก็ตามตัวควบคุมมุมมองระบบบางตัวอาจแมปกับสไตล์ที่แตกต่าง
Jakub Truhlář

186

ฉันเพิ่มข้อมูลที่อาจเป็นประโยชน์สำหรับใครบางคน ถ้าคุณมีทำต่อกระดานใด ๆ ที่จะกลับไปแบบเก่าคุณจะต้องตั้งค่าชนิดคุณสมบัติการปัจจุบัน Modallyและการนำเสนอคุณสมบัติการแบบเต็มหน้าจอ

ป้อนคำอธิบายรูปภาพที่นี่


2
มีวิธีในตัวสร้างส่วนติดต่อเพื่อตั้ง isModalInPresentation หรือไม่?
แบรดโทมัส

เห็นด้วยกับสิ่งนี้ เปลี่ยนค่าการนำเสนอสำหรับมุมมองที่ละเมิดระดับสูงสุด
David

performSegueนี้เป็นหนึ่งทำงานสำหรับฉันเพราะฉันมี ขอบคุณที่รัก!
Blasanka

95

ฉันมีปัญหานี้ในมุมมองเริ่มต้นทันทีหลังจากเปิดหน้าจอ การแก้ไขสำหรับฉันเนื่องจากฉันไม่มีซีคิวหรือลอจิกที่กำหนดคือการสลับการนำเสนอจากอัตโนมัติเป็นเต็มหน้าจอดังที่แสดงที่นี่:

fix_storyboard_presentation_default_behavior


2
มีวิธีใดบ้างในการทำสิ่งนี้โดยทางโปรแกรมสำหรับมุมมองทั้งหมดแทนที่จะแสดงทีละเรื่องผ่านกระดานเรื่องราว
The1993

@ The1993 คุณพบทางเลือกอื่นหรือไม่
Shobhit Puri

1
@ShobhitPuri ดูวิธีแก้ปัญหาแรกโดย Omreyh ที่นี่stackoverflow.com/a/58255416/4323101
The1993

1
ว้าวนี่คือคำตอบสำหรับปัญหาของฉัน ขอบคุณสำหรับทิป! สำหรับผู้อื่นที่มองสิ่งนี้เช่นกันนี่เป็นการแก้ไขพฤติกรรมที่แปลกหลังจากเปิดแอปจากพื้นหลังอีกครั้ง ในแอปพลิเคชันของฉันการเปิดจากพื้นหลังจะเป็นการซ้อนทับหน้าจอเริ่มต้นของฉัน (ตัวควบคุมมุมมองเริ่มต้น) เป็นรูปแบบการนำเสนอบัตรจากนั้นส่วนใด ๆ มันคงจะดีถ้าฉันปิดแอพ (แตะสองครั้งที่ปุ่มโฮมแล้วปัดขึ้นแล้วเปิดใหม่) แต่การเปิดตัวเพิ่มเติมใด ๆ จะทำให้เกิดพฤติกรรมแปลก ๆ นี้ ขอบคุณอีกครั้ง!
Justin

92

มีหลายวิธีในการทำเช่นนั้นและฉันคิดว่าแต่ละคนสามารถเหมาะสำหรับโครงการหนึ่ง แต่ไม่ใช่โครงการอื่นดังนั้นฉันคิดว่าฉันจะเก็บไว้ที่นี่บางทีคนอื่นจะทำงานในกรณีอื่น

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

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)
   }
}

การใช้งาน: ภายใน
ของคุณเพิ่มบรรทัดนี้: AppDelegateapplication(_ application: didFinishLaunchingWithOptions)

UIViewController.swizzlePresent()

การใช้วิธีนี้คุณไม่จำเป็นต้องทำการเปลี่ยนแปลงใด ๆ กับการเรียกปัจจุบันเนื่องจากเรากำลังแทนที่การใช้วิธีการปัจจุบันในรันไทม์
หากคุณจำเป็นต้องรู้ว่าอะไรคือ swizzling คุณสามารถตรวจสอบลิงค์นี้: https://nshipster.com/swift-objc-runtime/


ฉันมี viewControllers จำนวนมากในโครงการของฉัน แต่ไม่มีคลาสพื้นฐานฉันไม่ต้องการให้คุณมีวิธีแก้ไขปัญหาใด ๆ ที่มีการเปลี่ยนแปลงขั้นต่ำในรหัส
กูรู

ฉันใช้ swizzling แต่ฉันเพิ่ม. pageSheet ให้เป็นเงื่อนไข .... ถ้า viewControllerToPresent.modalPresentationStyle == .pageSheet || viewControllerToPresent.modalPresentationStyle == .automatic {viewControllerToPresent.modalPresentationStyle = .fullScreen}
Crash

แถบสถานะจะซ่อนเมื่อฉันเพิ่มโซลูชันที่ใช้หมายเลข 1
Ganesh Pawar

4
Swizzling เป็นวิธีแก้ปัญหาที่ใช้งานได้ดีในขณะที่ อย่างไรก็ตามเมื่อใช้ sdks ภายนอกบางอย่างเช่น FacebookLogin (5.8 ของวันนี้) และ GoogleSignin ฉันได้สังเกตเห็นว่าวิธีนี้แบ่งกระแสเหล่านั้น: เราได้รับหน้าจอสีขาวบน iPad นี่อาจเป็นเพราะความจริงที่ว่าพวกเขาใช้วิธีการของตัวเองร้อนแรง
Tao-Nhan Nguyen

39

ฉันใช้การ swizzling สำหรับ iOS 13

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
}

3
วิธีแก้ปัญหาที่ง่ายที่สุดถ้าคุณมีหลายวิธี
Raisal Calicut

หมายถึงบางที่หมายถึงไฟล์หรือที่ในโครงการทั้งหมด
Yatendra

ที่ใดที่หนึ่งฉันวางไว้ใน appdelegate static letขี้เกียจคุณต้องอ่านมันเพื่อให้มันถูกคำนวณขี้เกียจ var คำนวณเพียงครั้งเดียวฉันใช้มันเพื่อให้มีการรับประกันที่เรียกว่าวแรงครั้งเดียว
Maxime Ashurov

37

สำหรับผู้ใช้ Objective-C

เพียงใช้รหัสนี้

 [vc setModalPresentationStyle: UIModalPresentationFullScreen];

หรือถ้าคุณต้องการที่จะเพิ่มเฉพาะใน iOS 13.0 จากนั้นใช้

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

2
ใช้งานได้กับ iOS เวอร์ชันก่อนหน้านี้เช่นกัน แต่คำตอบก็ดี
Catalin

4
UIModalPresentationFullScreen ใช้งานได้กับ iOS 3.2+ ดังนั้นไม่จำเป็นต้องเพิ่มถ้ามีเงื่อนไขอื่น
flame3

2
ด้วยเหตุผลบางอย่างใน iOS 13.1.2 เฉพาะในคลาส Obj-c สิ่งนี้ไม่ทำงานและ modalPresentationSStyle แสดงเฉพาะ pageSheet เท่านั้น สิ่งนี้เกิดขึ้นกับคนอื่นหรือไม่?
Sevy11

@ Sevy11 ฉันยังไม่ได้อัปเดตเป็น iOS 13.1.2 แต่ทำงานได้ดีที่ 13.1
9to5ios

สวัสดี @ Sevy11 ฉันได้อัปเดต iOS 13.1.2 ของฉันแล้วและใช้งานได้ดีโปรดตรวจสอบที่จุดสิ้นสุดของคุณ
9to5ios

36

หนึ่งในสายการบิน:

modalPresentationStyleจะต้องตั้งอยู่บนnavigationController ซึ่งจะถูกนำเสนอ


iOS 13 และต่ำกว่าเวอร์ชั่น iOS แบบเต็มหน้าจอพร้อมoverCurrentContextและ navigationController

รหัสทดสอบ

let controller = UIViewController()
let navigationController = UINavigationController(rootViewController: controller)
navigationController.modalPresentationStyle = .overCurrentContext
self.navigationController?.present(navigationController, animated: true, completion: nil)

modalPresentationStyleต้องชุดที่navigationController


ชี้แจง: การนำเสนอ viewController จาก navigationController ไม่จำเป็นต้อง modalPresentationStyle ที่จะตั้งค่าบน navigationController แต่จะถูกตั้งค่าบน viewController ที่นำเสนอ อย่างไรก็ตามหากคุณกำลังแสดง navigationController ดังนั้นควรตั้งค่าคุณสมบัติ 'modalPresentationStyle' บน navigationController ไม่ใช่ viewController ในตัว วิธีนี้ใช้ได้กับ iOS 13.3, Xcode 11.3 ดูคำตอบของ Yogesh Bharate
Womble

@Pratik Sodha ความช่วยเหลือเกี่ยวกับเรื่องนี้? stackoverflow.com/questions/61429600/…
david

@Womble ความช่วยเหลือใด ๆ สำหรับstackoverflow.com/questions/61429600/
david

25

ในฐานะที่เป็นคำแนะนำ: ถ้าคุณโทรปัจจุบันไปยังViewControllerที่ฝังอยู่ภายใน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)

21

ฉันต้องทำทั้งสองอย่าง:

  1. กำหนดสไตล์การนำเสนอเป็นแบบเต็มหน้าจอ

    เต็มจอ

  2. ตั้งแถบด้านบนเป็นแถบนำทางแบบโปร่งแสง

แถบด้านบน


เป็นข้อสันนิษฐานที่แปลกประหลาดมากที่ตัวเลือกบางอย่างใน
Simulations


13

นี่คือทางออกที่ง่ายโดยไม่ต้องเข้ารหัสบรรทัดเดียว

  • เลือก View Controller ใน Storyboard
  • เลือกตัวตรวจสอบคุณสมบัติ
  • ตั้งค่าการนำเสนอ "อัตโนมัติ" เป็น "เต็มหน้าจอ" ตามภาพด้านล่าง

การเปลี่ยนแปลงนี้ทำให้พฤติกรรมของแอป iPad เป็นไปตามที่คาดไว้มิฉะนั้นหน้าจอใหม่จะแสดงขึ้นที่กึ่งกลางของหน้าจอเป็นป๊อปอัป

ป้อนคำอธิบายรูปภาพที่นี่


ฉันคิดว่าสิ่งที่สำคัญที่นี่คือคุณทำสิ่งนี้บน NavigationController ซึ่งเป็นสิ่งที่ภาพแสดง แต่ข้อความไม่ได้บอกอย่างนี้
Andy Weinstein

1
ตรวจสอบให้แน่ใจว่าส่วนย่อยที่ตามมาคือ "แสดง" และไม่ใช่ "ปัจจุบัน Modally"
Andy Weinstein

ตกลงดังนั้นอันนี้ดูเหมือนจะทำงานสำหรับฉันเมื่อฉันใช้ตัวควบคุมแถบแท็บเพื่อควบคุมมุมมองอื่น ๆ อย่างไรก็ตามคุณต้องตั้งค่าการนำเสนอ 'ตัวควบคุมแถบแท็บ' ให้เป็นแบบเต็มหน้าจอเนื่องจากจะควบคุมมุมมองอื่นทั้งหมด
Charlie

12

หากคุณมี UITabController ที่มีหน้าจอที่มีตัวควบคุมการนำทางแบบฝังคุณต้องตั้งค่า UITabController การนำเสนอดังแสดงในรูปด้านล่าง

ป้อนคำอธิบายรูปภาพที่นี่


12

นี่คือวิธีแก้ปัญหาสำหรับ Objective-C

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

vc.modalPresentationStyle = UIModalPresentationFullScreen;

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

10

ล่าสุดสำหรับ iOS 13 และ Swift 5.x

let vc = ViewController(nibName: "ViewController", bundle: nil)

vc.modalPresentationStyle = .fullScreen

self.present(vc, animated: true, completion: nil)

9

นี่คือเวอร์ชันแก้ไขของฉันใน ObjectiveC โดยใช้หมวดหมู่ ด้วยวิธีนี้คุณจะมี UIModalPresentationStyleFullScreen ที่เป็นค่าเริ่มต้นจนกว่าจะมีการตั้งค่าอีกอย่างชัดเจน

#import "UIViewController+Presentation.h"
#import "objc/runtime.h"

@implementation UIViewController (Presentation)

- (void)setModalPresentationStyle:(UIModalPresentationStyle)modalPresentationStyle {
    [self setPrivateModalPresentationStyle:modalPresentationStyle];
}

-(UIModalPresentationStyle)modalPresentationStyle {
    UIModalPresentationStyle style = [self privateModalPresentationStyle];
    if (style == NSNotFound) {
        return UIModalPresentationFullScreen;
    }
    return style;
}

- (void)setPrivateModalPresentationStyle:(UIModalPresentationStyle)modalPresentationStyle {
    NSNumber *styleNumber = [NSNumber numberWithInteger:modalPresentationStyle];
     objc_setAssociatedObject(self, @selector(privateModalPresentationStyle), styleNumber, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (UIModalPresentationStyle)privateModalPresentationStyle {
    NSNumber *styleNumber = objc_getAssociatedObject(self, @selector(privateModalPresentationStyle));
    if (styleNumber == nil) {
        return NSNotFound;
    }
    return styleNumber.integerValue;
}

@end

คุณมีไฟล์. h หรือไม่
Pedro Góes

@ PedroGóesใช่ แต่มันมีเพียงการประกาศหมวดหมู่: `` `@interface UIViewController (การนำเสนอ) @ ส่ง` ``
Alexander Kulabukhov

ใช้สิ่งนี้หากคุณไม่ต้องการที่จะจัดการกับทุกตัวควบคุมในกระดานเรื่องราวของคุณ! ประหยัดเวลาขอบคุณ!
AnthoPak

7

คำตอบอื่น ๆ ทั้งหมดนั้นเพียงพอ แต่สำหรับโครงการขนาดใหญ่เช่นเราและที่ซึ่งการนำทางถูกสร้างขึ้นทั้งในโค้ดและกระดานเรื่องราวมันเป็นงานที่ค่อนข้างยุ่งยาก

ป้อนคำอธิบายรูปภาพที่นี่

สำหรับผู้ที่ใช้ Storyboard อย่างกระตือรือร้น นี่คือคำแนะนำของฉัน: ใช้ Regex

รูปแบบต่อไปนี้ไม่ดีสำหรับหน้าเต็มหน้าจอ:

<segue destination="Bof-iQ-svK" kind="presentation" identifier="importSystem" modalPresentationStyle="fullScreen" id="bfy-FP-mlc"/>

รูปแบบต่อไปนี้ดีสำหรับหน้าเต็มหน้าจอ:

<segue destination="7DQ-Kj-yFD" kind="presentation" identifier="defaultLandingToSystemInfo" modalPresentationStyle="fullScreen" id="Mjn-t2-yxe"/>

regex ต่อไปนี้เข้ากันได้กับ VS CODE จะแปลงหน้าสไตล์เก่าทั้งหมดเป็นหน้าสไตล์ใหม่ คุณอาจต้องหลีกเลี่ยงตัวอักษรพิเศษหากคุณใช้เครื่องมือ regex อื่น ๆ / เครื่องมือแก้ไขข้อความ

ค้นหา Regex

<segue destination="(.*)"\s* kind="show" identifier="(.*)" id="(.*)"/>

แทนที่ Regex

<segue destination="$1" kind="presentation" identifier="$2" modalPresentationStyle="fullScreen" id="$3"/>

4

ในขั้นต้นค่าเริ่มต้นคือfullscreenสำหรับ modalPresentationStyle แต่ในiOS 13UIModalPresentationStyle.automaticการเปลี่ยนแปลงในการ

หากคุณต้องการที่จะทำให้การควบคุมมุมมองแบบเต็มหน้าจอคุณจะต้องเปลี่ยนไปmodalPresentationStylefullScreen

อ้างถึงUIModalPresentationStyle เอกสารประกอบของ Appleเพื่อดูรายละเอียดเพิ่มเติมและอ้างถึงแนวทางอินเทอร์เฟซสำหรับผู้ใช้ของ Appleสำหรับจุดที่ควรใช้รูปแบบใด


นี่เป็นคำตอบที่ถูกต้องตั้งแต่ iOS 13.3, Xcode 11.3 สำหรับสถานการณ์ที่คุณต้องการแสดง viewController จาก navigationController modalPresentationSStyle ของ. overFullScreen ยังใช้งานได้ อย่างไรก็ตามหากคุณนำเสนอ navigationController คุณต้องตั้งค่า 'modalPresentationStyle' บน navigationController ไม่ใช่ viewController ไชโย
Womble

3

คุณสามารถทำได้อย่างง่ายดายเปิดกระดานเรื่องราวของคุณเป็นซอร์สโค้ดและค้นหาkind="presentation"ในแท็ก seague ทั้งหมดที่มี kind = presentation เพิ่มคุณสมบัติพิเศษmodalPresentationStyle="fullScreen"


2
let Obj = MtViewController()
Obj.modalPresentationStyle = .overFullScreen
self.present(Obj, animated: true, completion: nil)

// ถ้าคุณต้องการปิดใช้งานการปัดเพื่อปิดมันให้เพิ่มบรรทัด

Obj.isModalInPresentation = true

ตรวจสอบเอกสาร Appleสำหรับข้อมูลเพิ่มเติม


2

ฉันทำได้โดยใช้วิธีการ swizzling (Swift 4.2):

เพื่อสร้างส่วนขยาย UIViewController ดังนี้

extension UIViewController {

    @objc private func swizzled_presentstyle(_ viewControllerToPresent: UIViewController, animated: Bool, completion: (() -> Void)?) {

        if #available(iOS 13.0, *) {
            if viewControllerToPresent.modalPresentationStyle == .automatic || viewControllerToPresent.modalPresentationStyle == .pageSheet {
                viewControllerToPresent.modalPresentationStyle = .fullScreen
            }
        }

        self.swizzled_presentstyle(viewControllerToPresent, animated: animated, completion: completion)
    }

     static func setPresentationStyle_fullScreen() {

        let instance: UIViewController = UIViewController()
        let aClass: AnyClass! = object_getClass(instance)

        let originalSelector = #selector(UIViewController.present(_:animated:completion:))
        let swizzledSelector = #selector(UIViewController.swizzled_presentstyle(_:animated:completion:))

        let originalMethod = class_getInstanceMethod(aClass, originalSelector)
        let swizzledMethod = class_getInstanceMethod(aClass, swizzledSelector)
        if let originalMethod = originalMethod, let swizzledMethod = swizzledMethod {
        method_exchangeImplementations(originalMethod, swizzledMethod)
        }
    }
}

และใน AppDelegate ในแอปพลิเคชัน: didFinishLaunchingWithOptions: เรียกใช้รหัส swizzling โดยโทร:

UIViewController.setPresentationStyle_fullScreen()

1

สิ่งนี้ใช้ได้กับฉัน:

yourViewController.modalPresentationStyle = UIModalPresentationStyle.fullScreen


3
สิ่งนี้จะไม่เพิ่มคำตอบที่มีอยู่ทั้งหมด
rmaddy

1

สร้างหมวดหมู่สำหรับ UIViewController (พูด UIViewController + PresentationStyle) เพิ่มรหัสต่อไปนี้ลงไป

 -(UIModalPresentationStyle)modalPresentationStyle{
     return UIModalPresentationStyleFullScreen;
}

สิ่งนี้จะทำให้ UISearchController + ทริกเกอร์การแก้ไขข้อผิดพลาดบางอย่างได้ยาก
dklt

@dklt นั่นเป็นข้อสังเกตที่ดี ดังนั้นการตั้งค่าคุณสมบัติอย่างชัดเจนจะแก้ปัญหา ไม่มีวิธีแก้ปัญหาที่ง่ายกว่านี้หากใช้ UISearchController
Govind

0

อีกวิธีหนึ่งคือการมีส่วนประกอบ viewcontroller พื้นฐานของคุณเองในแอพของคุณและเพียงแค่ติดตั้งตัวเริ่มต้นที่กำหนดและจำเป็นต้องมีการตั้งค่าพื้นฐานสิ่งต่อไปนี้:

class MyBaseViewController: UIViewController {

//MARK: Initialisers

/// Alternative initializer which allows you to set the modal presentation syle
/// - Parameter modalStyle: the presentation style to be used
init(with modalStyle:UIModalPresentationStyle) {
    super.init(nibName: nil, bundle: nil)
    self.setup(modalStyle: modalStyle)
}

override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    // default modal presentation style as fullscreen
    self.setup(modalStyle: .fullScreen)
}

required init?(coder: NSCoder) {
    super.init(coder: coder)
    // default modal presentation style as fullscreen
    self.setup(modalStyle: .fullScreen)
}

//MARK: Private

/// Setup the view
///
/// - Parameter modalStyle: indicates which modal presentation style to be used
/// - Parameter modalPresentation: default true, it prevent modally presented view to be dismissible with the default swipe gesture
private func setup(modalStyle:UIModalPresentationStyle, modalPresentation:Bool = true){
    if #available(iOS 13, *) {
        self.modalPresentationStyle = modalStyle
        self.isModalInPresentation = modalPresentation
    }
}

หมายเหตุ : ถ้าตัวควบคุมมุมมองของคุณมีอยู่ในตัวควบคุมการนำทางซึ่งมีการนำเสนอจริง ๆ แล้วตัวควบคุมทิศทางควรเข้าใกล้ปัญหาในลักษณะเดียวกัน (หมายถึงการมีส่วนประกอบของตัวควบคุมการนำทางแบบกำหนดเองของคุณในลักษณะเดียวกัน

ทดสอบกับ Xcode 11.1 บน iOS 13.1 และ iOS 12.4

หวังว่ามันจะช่วย


0

ฉันมีปัญหากับวิดีโอที่ไม่แสดงแบบเต็มหน้าจออีกต่อไป เพิ่มบรรทัดนี้ซึ่งบันทึกวัน :-)

videoController.modalPresentationStyle = UIModalPresentationFullScreen;

2
สิ่งนี้จะไม่เพิ่มคำตอบที่มีอยู่ทั้งหมด
rmaddy

0

ทางออกที่ง่ายที่สุดสำหรับฉัน

viewController.modalPresentationStyle = .fullScreen

3
สิ่งนี้จะไม่เพิ่มคำตอบที่มีอยู่ทั้งหมด
rmaddy

0

หากคุณกำลังใช้ UINavigationController และฝัง ViewController เป็นคอนโทรลเลอร์มุมมองรูทดังนั้นคุณจะต้องเจอปัญหาเดียวกัน ใช้รหัสต่อไปนี้เพื่อเอาชนะ

let vc = UIViewController()
let navController = UINavigationController(rootViewController: vc)
navController.modalPresentationStyle = .fullScreen

0
class MyViewController: UIViewController {

    convenience init() {
        self.init(nibName:nil, bundle:nil)
        self.modalPresentationStyle = .fullScreen
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

แทนที่จะเรียกself.modalPresentationStyle = .fullScreenใช้ตัวควบคุมมุมมองทุกครั้งคุณสามารถ subclass UIViewController และใช้งานได้MyViewControllerทุกที่


-1

คำตอบและคำแนะนำข้างต้นถูกต้องด้านล่างเป็นอีกเวอร์ชันหนึ่งและเป็นวิธีที่มีประสิทธิภาพในการใช้โปรแกรม

# 1 สร้างส่วนขยาย UIView

# 2 สร้างวิธี ()

//#1
extension UIViewController {

//#2
func presentLocal(_ viewControllerToPresent: UIViewController, animated flag: 
Bool, completion: (() -> Void)? = nil) {

//Reusing below 2 lines :-)
viewControllerToPresent.modalPresentationStyle = .overCurrentContext
self.present(viewControllerToPresent, animated: flag, completion: completion)

  }
}

เรียกใช้ดังนี้

let vc = MyViewController()
let nc = UINavigationController(rootViewController: vc)
sourceView.presentLocal(nc, animated: true, completion: nil)

หรือ

let vc = MyViewController()
sourceView.presentLocal(vc, animated: true, completion: nil)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.