Mencoba menampilkan UIViewController di UIViewController yang pandangannya tidak ada dalam hierarki jendela

599

Baru mulai menggunakan Xcode 4.5 dan saya mendapatkan kesalahan ini di konsol:

Peringatan: Berusaha menampilkan <finishViewController: 0x1e56e0a0> di <ViewController: 0x1ec3e000> yang pandangannya tidak ada dalam hierarki jendela!

Tampilannya masih disajikan dan semua yang ada di aplikasi berfungsi dengan baik. Apakah ini sesuatu yang baru di iOS 6?

Ini adalah kode yang saya gunakan untuk mengubah antar tampilan:

UIStoryboard *storyboard = self.storyboard;
finishViewController *finished = 
[storyboard instantiateViewControllerWithIdentifier:@"finishViewController"];

[self presentViewController:finished animated:NO completion:NULL];
Kyle Goslan
sumber
3
Saya mengalami masalah yang sama persis, kecuali mencoba memanggil presentViewController:animated:completionpengontrol nav. Apakah Anda melakukan ini di delegasi aplikasi?
tarnfeld
Tidak, saya melakukannya dari satu pengontrol tampilan ke yang lain. Apakah Anda menemukan solusi?
Kyle Goslan
Masalah yang sama pada bagian kode yang selalu berfungsi sebelum menggunakan Xcode 4.5, saya menyajikan UINavigationController, tapi sekali lagi ini selalu berhasil sebelumnya.
Emanuele Fumagalli
Saya memiliki masalah yang sama, tidak terpecahkan. Melakukannya dari delegasi aplikasi, dan rootviewcontroller memanggil "presentViewController" dengan menggunakan UITabBarController.
darksider
3
juga, jika memanggil metode ini sebelum memanggil makeKeyAndVisible, pindahkan setelah itu
mike_haney

Jawaban:

1296

Dari mana Anda memanggil metode ini? Saya punya masalah di mana saya mencoba untuk menyajikan pengontrol tampilan modal dalam viewDidLoadmetode. Solusi bagi saya adalah memindahkan panggilan ini keviewDidAppear: metode.

Asumsi saya adalah bahwa pandangan pengontrol tampilan tidak dalam hierarki tampilan jendela pada titik yang telah dimuat (ketika viewDidLoadpesan dikirim), tetapi berada dalam hierarki jendela setelah disajikan (ketika viewDidAppear:pesan dikirim) .


Peringatan

Jika Anda melakukan panggilan ke presentViewController:animated:completion:dalam viewDidAppear:Anda dapat mengalami masalah di mana pengontrol tampilan modal selalu disajikan setiap kali tampilan pengontrol tampilan muncul (yang masuk akal!) Dan pengontrol tampilan modal yang disajikan tidak akan pernah hilang. .

Mungkin ini bukan tempat terbaik untuk menyajikan pengontrol tampilan modal, atau mungkin beberapa kondisi tambahan perlu dijaga yang memungkinkan pengontrol tampilan tampilan untuk memutuskan apakah harus menghadirkan pengontrol tampilan modal atau tidak.

James Bedford
sumber
6
@James Anda benar, tampilan tampaknya tidak ada dalam hierarki sampai setelah viewWillAppear telah diselesaikan dan sekali viewDidAppear dipanggil. Jika ini pertanyaan saya, saya akan menerima jawaban ini;)
Matt Mc
6
@ James, terima kasih. Menggunakan ViewDidAppear memecahkan masalah untuk saya juga. Masuk akal.
Ali
44
Saya berharap saya bisa membenarkan ini dua kali. Saya baru saja mengalami masalah ini dan datang ke utas untuk menemukan bahwa saya telah terbalik sejak terakhir kali saya melihat ini.
Schrockwell
7
Perhatikan bahwa ketika Anda mengubah VC di viewDidAppear, ini menyebabkan eksekusi segue, dengan Animation. Menyebabkan flash / tampilan latar belakang.
Vincent
2
Ya triknya adalah viewWillAppear: (BOOL) animasi karena sudah benar. Satu hal lagi yang penting Anda harus memanggil super dalam metode ini, seperti [super viewDidAppear: animated]; tanpa ini tidak akan berfungsi.
BootMaker
66

Penyebab potensial lainnya:

Saya mengalami masalah ini ketika saya tidak sengaja menampilkan pengontrol tampilan yang sama dua kali. (Sekali dengan performSegueWithIdentifer:sender:yang dipanggil ketika tombol ditekan, dan yang kedua dengan segue terhubung langsung ke tombol).

Secara efektif, dua segue diaktifkan pada saat yang sama, dan saya mendapatkan kesalahan: Attempt to present X on Y whose view is not in the window hierarchy!

Chris Nolet
sumber
4
Saya memiliki kesalahan yang sama, dan jawaban Anda di sini membantu saya mencari tahu apa yang sedang terjadi, memang kesalahan ini, memperbaikinya karena Anda Pak, terima kasih, +1
samouray
1
Saya menghapus segue lama dan menghubungkan VC ke VC. Apakah ada cara untuk menghubungkan tombol ke storyBoard ke VC karena cara itu terus membuat kesalahan bagi saya?
MCB
Saya memiliki kesalahan yang sama, jawaban Anda memecahkan masalah saya, terima kasih atas perhatian Anda. Salam.
iamburak
1
lol, tidak sengaja saya juga membuat dua vc: from button dan performSegue, terima kasih atas tipnya !!!
Borzh
1
Dalam kasus saya, saya menelepon present(viewController, animated: true, completion: nil)dalam satu lingkaran.
Samo
38

viewWillLayoutSubviewsdan viewDidLayoutSubviews(iOS 5.0+) dapat digunakan untuk tujuan ini. Mereka dipanggil lebih awal dari viewDidAppear.

Jonny
sumber
3
Tetap mereka digunakan juga dalam kesempatan lain jadi saya pikir mereka mungkin dipanggil beberapa kali dalam "seumur hidup" pandangan itu.
Jonny
Ini juga bukan untuk apa metode - seperti namanya. viewDidAppear benar. Membaca siklus hidup pandangan adalah ide yang bagus.
tooluser
Ini solusi terbaik. Dalam kasus saya, penyajian di viewDidAppear menyebabkan tampilan sepersekian detik dari pengontrol tampilan sebelum modal dimuat, yang tidak dapat diterima.
TMilligan
Jawaban ini bekerja paling baik untuk saya ketika mencoba menampilkan peringatan. Lansiran tidak akan muncul ketika saya memasukkannya ke dalam viewDidLoad dan viewWillAppear.
uplearnedu.com
26

Untuk Menampilkan subview apa pun ke tampilan utama, Silakan gunakan kode berikut

UIViewController *yourCurrentViewController = [UIApplication sharedApplication].keyWindow.rootViewController;

while (yourCurrentViewController.presentedViewController) 
{
   yourCurrentViewController = yourCurrentViewController.presentedViewController;
}

[yourCurrentViewController presentViewController:composeViewController animated:YES completion:nil];

Untuk Abaikan subview apa pun dari tampilan utama, Silakan gunakan kode berikut

UIViewController *yourCurrentViewController = [UIApplication sharedApplication].keyWindow.rootViewController;

while (yourCurrentViewController.presentedViewController) 
{
   yourCurrentViewController = yourCurrentViewController.presentedViewController;
}

[yourCurrentViewController dismissViewControllerAnimated:YES completion:nil];
abdul sathar
sumber
Bekerja untuk saya juga
Aziz Javed
17

Saya juga mengalami masalah ini ketika saya mencoba untuk menyajikan UIViewControllerdalam viewDidLoad. Jawaban James Bedford berhasil, tetapi aplikasi saya menunjukkan latar belakang pertama selama 1 atau 2 detik.

Setelah beberapa penelitian, saya telah menemukan cara untuk menyelesaikan ini dengan menggunakan addChildViewController.

- (void)viewDidLoad
{
    ...
    [self.view addSubview: navigationViewController.view];
    [self addChildViewController: navigationViewController];
    ...
}
sunkehappy
sumber
9
Saya pikir Anda tidak ada [navigationViewController didMoveToParentViewController: self]
foFox
2
Saya mencoba kode Anda, bersama dengan saran foFox, dan ketika saya pergi untuk menghapusnya dari orang tuanya, itu tidak akan hilang. Lololol. Masih macet tanpa perbaikan.
Logicsaurus Rex
Bekerja di Swift3.1
Kang Byul
@sunkehappy di atas dua baris yang akan digunakan sebelum presentviewcontroller, tetapi mengapa crash?
Iyyappan Ravi
14

Mungkin, seperti saya, Anda salah paham viewController

Saya ingin menampilkan ViewControllerdalam non-UIViewControllerkonteks,

Jadi saya tidak bisa menggunakan kode seperti itu:

[self presentViewController:]

Jadi, saya mendapatkan UIViewController:

[[[[UIApplication sharedApplication] delegate] window] rootViewController]

Untuk beberapa alasan (bug logis), itu rootViewControlleradalah sesuatu yang tidak diharapkan (normal UIViewController). Lalu saya memperbaiki bug, mengganti rootViewControllerdengan UINavigationController, dan masalahnya hilang.

Sanbrother
sumber
8

TL; DR Anda hanya dapat memiliki 1 rootViewController dan yang terbaru disajikan. Jadi jangan coba-coba membuat viewcontroller menyajikan viewcontroller lain ketika sudah disajikan yang belum diberhentikan.

Setelah melakukan beberapa pengujian saya sendiri saya sampai pada kesimpulan.

Jika Anda memiliki rootViewController yang ingin Anda sajikan semuanya maka Anda dapat mengalami masalah ini.

Berikut ini adalah kode rootController saya (terbuka adalah jalan pintas saya untuk menghadirkan viewcontroller dari root).

func open(controller:UIViewController)
{
    if (Context.ROOTWINDOW.rootViewController == nil)
    {
        Context.ROOTWINDOW.rootViewController = ROOT_VIEW_CONTROLLER
        Context.ROOTWINDOW.makeKeyAndVisible()
    }

    ROOT_VIEW_CONTROLLER.presentViewController(controller, animated: true, completion: {})
}

Jika saya memanggil terbuka dua kali berturut-turut (terlepas dari waktu yang berlalu), ini akan berfungsi dengan baik pada pembukaan pertama, tetapi BUKAN pada pembukaan kedua. Upaya terbuka kedua akan menghasilkan kesalahan di atas.

Namun jika saya menutup tampilan yang paling baru disajikan kemudian memanggil terbuka, itu berfungsi dengan baik ketika saya memanggil terbuka lagi (pada viewcontroller lain).

func close(controller:UIViewController)
{
    ROOT_VIEW_CONTROLLER.dismissViewControllerAnimated(true, completion: nil)
}

Apa yang saya simpulkan adalah bahwa rootViewController hanya MOST-RECENT-CALL ada pada tampilan Hierarchy (bahkan jika Anda tidak mengabaikannya atau menghapus tampilan). Saya mencoba bermain dengan semua panggilan loader (viewDidLoad, viewDidAppear, dan melakukan panggilan pengiriman tertunda) dan saya telah menemukan bahwa satu-satunya cara saya bisa membuatnya bekerja adalah HANYA memanggil hadir dari pengendali tampilan paling atas.

Agresor
sumber
Ini sepertinya masalah yang jauh lebih umum bahwa banyak jawaban yang memilih Anda. Sayangnya, ini sangat membantu
rayepps
ya semua baik dan bagus tapi apa solusinya ... saya memiliki latar belakang pekerja thread pergi ke server dan menampilkan storyboard kiri kanan dan tengah dan seluruh metodologi adalah palsu .. itu mengerikan .. apa yang seharusnya menjadi angin sama sekali sebuah lelucon karena saya ingin melakukan int dia latar belakang adalah: wait wait decide push screen to frontdan itu TIDAK MUNGKIN adalah IOS ????
Tuan Heelis
5

Masalah saya adalah saya tampil Shalawat di UIApplicationDelegate's didFinishLaunchingWithOptionsmetode sebelum aku menelepon makeKeyAndVisible()di jendela.

Adam Johns
sumber
bagaimana? bisakah kamu menguraikan? Saya menghadapi masalah yang sama. ini adalah kode saya biarkan initialViewControlleripad: UIViewController = mainStoryboardIpad.instantiateViewController (withIdentifier: "SplashController") sebagai UIViewController self.window .rootViewController = initialViewControlleripad self.window .makeKeyAndVisible ()??
shahtaj khalid
4

Dalam situasi saya, saya tidak dapat menempatkan kelas saya di kelas. Jadi, inilah yang saya dapat:

let viewController = self // I had viewController passed in as a function,
                          // but otherwise you can do this


// Present the view controller
let currentViewController = UIApplication.shared.keyWindow?.rootViewController
currentViewController?.dismiss(animated: true, completion: nil)

if viewController.presentedViewController == nil {
    currentViewController?.present(alert, animated: true, completion: nil)
} else {
    viewController.present(alert, animated: true, completion: nil)
}
George_E
sumber
3

Saya memiliki masalah yang sama. Saya harus menanamkan pengontrol navigasi dan menyajikan pengontrol melaluinya. Di bawah ini adalah kode sampel.

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    UIImagePickerController *cameraView = [[UIImagePickerController alloc]init];
    [cameraView setSourceType:UIImagePickerControllerSourceTypeCamera];
    [cameraView setShowsCameraControls:NO];

    UIView *cameraOverlay = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 768, 1024)];
    UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"someImage"]];
    [imageView setFrame:CGRectMake(0, 0, 768, 1024)];
    [cameraOverlay addSubview:imageView];

    [cameraView setCameraOverlayView:imageView];

    [self.navigationController presentViewController:cameraView animated:NO completion:nil];
//    [self presentViewController:cameraView animated:NO completion:nil]; //this will cause view is not in the window hierarchy error

}
beristirahat
sumber
3

Jika Anda memiliki objek AVPlayer dengan video yang diputar, Anda harus menjeda video terlebih dahulu.

Vlad
sumber
Maksud saya video harus dihentikan / dihentikan dulu.
Vlad
sebenarnya ini membantu saya, itu membawa saya setelah ini stackoverflow.com/questions/20746413/...
Omar N Shamali
3

Saya memiliki masalah yang sama. Masalahnya adalah, performSegueWithIdentifier dipicu oleh pemberitahuan, segera setelah saya meletakkan pemberitahuan di utas utama pesan peringatan itu hilang.

Merah
sumber
3

Ini bekerja dengan baik, coba ini. Tautan

UIViewController *top = [UIApplication sharedApplication].keyWindow.rootViewController;
[top presentViewController:secondView animated:YES completion: nil];
vijay
sumber
3

Jika itu membantu siapa pun, masalah saya sangat konyol. Tentu saja ini salahku. Pemberitahuan memicu metode yang memanggil modal. Tetapi saya tidak menghapus notifikasi dengan benar, jadi pada beberapa titik, saya akan memiliki lebih dari satu notifikasi, sehingga modalnya akan dipanggil beberapa kali. Tentu saja, setelah Anda memanggil modal sekali, viewcontroller yang menyebutnya tidak lagi dalam hierarki tampilan, itu sebabnya kami melihat masalah ini. Situasi saya menyebabkan banyak masalah lain juga, seperti yang Anda harapkan.

Jadi untuk meringkas, apa pun yang Anda lakukan pastikan modal tidak dipanggil lebih dari sekali .

HotFudgeSunday
sumber
3

Saya telah berakhir dengan kode yang akhirnya bekerja untuk saya (Swift), mengingat Anda ingin menampilkan beberapa viewControllerdari hampir di mana saja. Kode ini jelas akan macet ketika tidak ada rootViewController yang tersedia, itulah akhir yang terbuka. Ini juga tidak termasuk biasanya diperlukan beralih ke menggunakan UI thread

dispatch_sync(dispatch_get_main_queue(), {
    guard !NSBundle.mainBundle().bundlePath.hasSuffix(".appex") else {
       return; // skip operation when embedded to App Extension
    }

    if let delegate = UIApplication.sharedApplication().delegate {
        delegate.window!!.rootViewController?.presentViewController(viewController, animated: true, completion: { () -> Void in
            // optional completion code
        })
    }
}
igraczech
sumber
BTW untuk memahami DI MANA saya memanggil metode ini dari ... itu adalah perpustakaan SDK UI-kurang, yang menampilkan UI sendiri atas aplikasi Anda dalam kasus tertentu (tidak diungkapkan).
igraczech
Anda AKAN lumpuh dan terbakar jika ada yang memutuskan untuk menanamkan Anda sdk di aplikasi yang memiliki ekstensi. Lewati UIViewController untuk menyalahgunakan metode SDK Anda [s].
Anton Tropashko
Kamu benar Anton. Kode ini ditulis ketika ekstensi tidak ada dan SDK belum digunakan di salah satu dari mereka. Saya telah menambahkan klausa penjaga untuk melewati casing tepi ini.
igraczech
3

Semacam ini peringatan bisa berarti bahwa Anda sedang berusaha untuk baru hadir View Controllermelalui Navigation Controllersementara ini Navigation Controllersaat menyajikan lain View Controller. Untuk memperbaikinya Anda harus mengabaikan saat ini disajikan View Controllerpada awalnya dan pada saat selesai menyajikan yang baru. Penyebab lain dari peringatan tersebut adalah mencoba menampilkan View Controllerdi utas selain main.

saltwat5r
sumber
3

Saya memiliki masalah serupa pada Swift 4.2 tetapi pandangan saya tidak disajikan dari siklus tampilan. Saya menemukan bahwa saya memiliki beberapa segmen untuk disajikan pada waktu yang bersamaan. Jadi saya menggunakan dispatchAsyncAfter.

func updateView() {

 DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in

// for programmatically presenting view controller 
// present(viewController, animated: true, completion: nil)

//For Story board segue. you will also have to setup prepare segue for this to work. 
 self?.performSegue(withIdentifier: "Identifier", sender: nil)
  }
}
Ashim Dahal
sumber
2

Saya memperbaikinya dengan memindahkan start()fungsi di dalam dismissblok penyelesaian:

self.tabBarController.dismiss(animated: false) {
  self.start()
}

Mulai berisi dua panggilan ke self.present()satu untuk UINavigationController dan satu lagi untuk a UIImagePickerController.

Itu memperbaikinya bagi saya.

Alper
sumber
1

Anda juga bisa mendapatkan peringatan ini saat melakukan segue dari view controller yang tertanam dalam sebuah wadah. Solusi yang benar adalah dengan menggunakan segue dari induk wadah, bukan dari pengontrol tampilan wadah.

Borzh
sumber
1

Harus menulis di bawah garis.

self.searchController.definesPresentationContext = true

dari pada

self.definesPresentationContext = true

dalam UIViewController

Coder_A_D
sumber
1

Dengan Swift 3 ...

Kemungkinan penyebab lain untuk ini, yang terjadi pada saya, adalah memiliki segue dari tableViewCell ke ViewController lain di Storyboard. Saya juga menggunakan override func prepare(for segue: UIStoryboardSegue, sender: Any?) {}ketika sel diklik.

Saya memperbaiki masalah ini dengan membuat segue dari ViewController ke ViewController.

Devbot10
sumber
1

Saya mengalami masalah ini, dan akar penyebabnya berlangganan penangan klik tombol (TouchUpInside) beberapa kali.

Itu berlangganan di ViewWillAppear, yang dipanggil beberapa kali karena kami telah menambahkan navigasi untuk pergi ke pengontrol lain, dan kemudian bersantai kembali ke sana.

Wes
sumber
1

Itu terjadi pada saya bahwa segue di storyboard semacam rusak . Menghapus segue (dan membuat segue yang sama persis lagi) menyelesaikan masalah.

vonox7
sumber
1

Dengan jendela utama Anda, kemungkinan akan selalu ada saat-saat dengan transisi yang tidak sesuai dengan menghadirkan peringatan. Untuk mengizinkan pemberitahuan saat kapan saja dalam siklus hidup aplikasi Anda, Anda harus memiliki jendela terpisah untuk melakukan pekerjaan itu.

/// independant window for alerts
@interface AlertWindow: UIWindow

+ (void)presentAlertWithTitle:(NSString *)title message:(NSString *)message;

@end

@implementation AlertWindow

+ (AlertWindow *)sharedInstance
{
    static AlertWindow *sharedInstance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[AlertWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
    });
    return sharedInstance;
}

+ (void)presentAlertWithTitle:(NSString *)title message:(NSString *)message
{
    // Using a separate window to solve "Warning: Attempt to present <UIAlertController> on <UIViewController> whose view is not in the window hierarchy!"
    UIWindow *shared = AlertWindow.sharedInstance;
    shared.userInteractionEnabled = YES;
    UIViewController *root = shared.rootViewController;
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
    alert.modalInPopover = true;
    [alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
        shared.userInteractionEnabled = NO;
        [root dismissViewControllerAnimated:YES completion:nil];
    }]];
    [root presentViewController:alert animated:YES completion:nil];
}

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];

    self.userInteractionEnabled = NO;
    self.windowLevel = CGFLOAT_MAX;
    self.backgroundColor = UIColor.clearColor;
    self.hidden = NO;
    self.rootViewController = UIViewController.new;

    [NSNotificationCenter.defaultCenter addObserver:self
                                           selector:@selector(bringWindowToTop:)
                                               name:UIWindowDidBecomeVisibleNotification
                                             object:nil];

    return self;
}

/// Bring AlertWindow to top when another window is being shown.
- (void)bringWindowToTop:(NSNotification *)notification {
    if (![notification.object isKindOfClass:[AlertWindow class]]) {
        self.hidden = YES;
        self.hidden = NO;
    }
}

@end

Penggunaan dasar yang, menurut desain, akan selalu berhasil:

[AlertWindow presentAlertWithTitle:@"My title" message:@"My message"];
Cur
sumber
1

Sayangnya, solusi yang diterima tidak bekerja untuk kasus saya. Saya mencoba menavigasi ke Pengontrol Tampilan baru setelah melepas dari Pengontrol Tampilan lainnya.

Saya menemukan solusi dengan menggunakan bendera untuk menunjukkan yang mana segue santai dipanggil.

@IBAction func unwindFromAuthenticationWithSegue(segue: UIStoryboardSegue) {
    self.shouldSegueToMainTabBar = true
}

@IBAction func unwindFromForgetPasswordWithSegue(segue: UIStoryboardSegue) {
    self.shouldSegueToLogin = true
}

Kemudian berikan VC yang diinginkan dengan present(_ viewControllerToPresent: UIViewController)

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    if self.shouldSegueToMainTabBar {
        let mainTabBarController = storyboard.instantiateViewController(withIdentifier: "mainTabBarVC") as! MainTabBarController
        self.present(mainTabBarController, animated: true)
        self.shouldSegueToMainTabBar = false
    }
    if self.shouldSegueToLogin {
        let loginController = storyboard.instantiateViewController(withIdentifier: "loginVC") as! LogInViewController
        self.present(loginController, animated: true)
        self.shouldSegueToLogin = false
    }
}

Pada dasarnya, kode di atas akan membuat saya menangkap pelepasan dari login / Mendaftar VC dan menavigasi ke dasbor, atau menangkap tindakan pelepasan dari lupa kata sandi VC dan menavigasi ke halaman login.

Fan Jin
sumber
1

Saya memperbaiki kesalahan ini dengan menyimpan viewcontroller paling atas ke dalam konstanta yang ditemukan di dalam sementara siklus di rootViewController:

if var topController = UIApplication.shared.keyWindow?.rootViewController {
    while let presentedViewController = topController.presentedViewController {
        topController = presentedViewController
    }
    topController.present(controller, animated: false, completion: nil)
    // topController should now be your topmost view controller
}
Marek Baláž
sumber
1

Saya menemukan bug ini tiba setelah memperbarui Xcode, saya percaya ke Swift 5 . Masalahnya terjadi ketika saya secara sistematis meluncurkan segue langsung setelah membuka gulungan pengontrol tampilan.

Solusinya tiba saat memperbaiki bug terkait, yaitu bahwa pengguna sekarang dapat melepas segues dengan menggesekkan halaman. Ini mematahkan logika program saya.

Itu diperbaiki dengan mengubah mode Presentasi pada semua pengontrol tampilan dari Otomatis ke Layar Penuh .

Anda bisa melakukannya di panel atribut di pembuat antarmuka. Atau lihat jawaban ini untuk cara melakukannya secara terprogram.

Tim MB
sumber
0

Saya hanya punya masalah ini juga, tetapi tidak ada hubungannya dengan waktu. Saya menggunakan singleton untuk menangani adegan, dan saya menetapkannya sebagai presenter. Dengan kata lain "Diri" tidak terhubung dengan apa pun. Saya baru saja membuat "adegan" batinnya sebagai presenter dan voila baru, itu berhasil. (Voila kehilangan sentuhannya setelah Anda mempelajari artinya, heh).

Jadi ya, ini bukan tentang "secara ajaib menemukan jalan yang benar", ini tentang memahami di mana kode Anda berdiri dan apa yang dilakukannya. Saya senang Apple memberikan pesan peringatan sederhana-bahasa Inggris, bahkan dengan emosi untuk itu. Kudos kepada dev apel yang melakukan itu !!

Stephen J
sumber
0

Jika solusi lain tidak terlihat bagus untuk beberapa alasan, Anda masih dapat menggunakan workaroundpresentasi tua dengan penundaan 0 ini, seperti ini:

dispatch_after(0, dispatch_get_main_queue(), ^{
    finishViewController *finished = [self.storyboard instantiateViewControllerWithIdentifier:@"finishViewController"];
    [self presentViewController:finished animated:NO completion:NULL];    
});

Meskipun saya telah melihat tidak ada jaminan yang terdokumentasi bahwa VC Anda akan berada pada hierarki tampilan pada blok pengiriman dijadwalkan untuk dieksekusi, saya telah mengamati itu akan berfungsi dengan baik.

Menggunakan penundaan misalnya 0,2 detik juga merupakan pilihan. Dan hal terbaik - dengan cara ini Anda tidak perlu dipusingkan dengan variabel booleanviewDidAppear:

Dannie P
sumber
2
Meskipun ini mungkin bekerja sekarang, tidak ada jaminan bahwa Apple akan mengubah perilaku dan menghancurkan ini pada Anda di masa depan. Kemudian ketika Anda kembali untuk melihat kode Anda untuk mencoba dan memperbaiki lagi, Anda akan bertanya-tanya mengapa Anda melakukan pengiriman yang tampaknya tidak perlu ini.
Cruinh
Pengiriman dengan 0 waktu telah menyelamatkan saya cukup banyak kali - kadang-kadang hal-hal yang seharusnya hanya bekerja secara logis biasanya tidak berfungsi tanpa itu. Jadi buat komentar untuk diri sendiri dan orang lain tentang mengapa Anda melakukan hal-hal yang tidak jelas (tidak hanya pengiriman seperti itu) dan Anda harus baik-baik saja.
Dannie P
2
Anda hanya meretas masalah dan tidak menyelesaikannya.
Michael Peterson
0

Ini berfungsi untuk menampilkan pengontrol tampilan, jika Anda memiliki pengontrol navigasi. self.navigationController? .present (MyViewController, animated: true, completion: nil) Juga, saya dapat menampilkan peringatan dan pengontrol email juga.

Gurpreet Singh
sumber