Tampilkan clearColor UIViewController melalui UIViewController

150

Saya memiliki UIViewControllerpandangan sebagai subview / modal di atas UIViewControllerpandangan lain , seperti bahwa subview / modal harus transparan dan komponen apa pun yang ditambahkan ke subview harus terlihat. Masalahnya adalah yang saya miliki adalah subview menunjukkan latar belakang hitam sebagai gantinya memiliki clearColor. Saya mencoba menjadikan UIViewsebagai clearColor bukan latar belakang hitam. Adakah yang tahu apa yang salah dengannya? Setiap saran dihargai.

FirstViewController.m

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];

[vc setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentModalViewController:vc animated:NO];  

SecondViewController.m

- (void)viewDidLoad 
{
     [super viewDidLoad];
     self.view.opaque = YES;
     self.view.backgroundColor = [UIColor clearColor];
}

Diselesaikan : Saya memperbaiki masalah. Ini bekerja dengan baik untuk iPhone dan iPad. Pengendali Modal View tanpa latar belakang hitam hanya clearColor / transparan. Satu-satunya hal yang saya perlu perubahan adalah saya diganti UIModalPresentationFullScreenuntuk UIModalPresentationCurrentContext. Betapa sederhananya itu!

FirstViewController.m

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
vc.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:NO completion:nil];

PEMBERITAHUAN: Jika Anda menggunakan modalPresentationStyleproperti dari navigationController:

FirstViewController.m

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
vc.view.backgroundColor = [UIColor clearColor];
self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:NO completion:nil];

PEMBERITAHUAN: Berita buruknya adalah solusi di atas tidak berfungsi di iOS 7. Berita baiknya adalah saya memperbaiki masalah untuk iOS7! Saya meminta bantuan seseorang dan inilah yang dia katakan:

Saat menghadirkan pengontrol tampilan secara modial, iOS menghapus pengontrol tampilan di bawahnya dari hierarki tampilan selama durasi disajikan. Meskipun tampilan pengontrol tampilan yang disajikan secara transparan, tidak ada yang di bawahnya kecuali jendela aplikasi, yang berwarna hitam. iOS 7 memperkenalkan gaya presentasi modal baru UIModalPresentationCustom,, yang menyebabkan iOS tidak menghapus tampilan di bawah pengontrol tampilan yang disajikan. Namun, untuk menggunakan gaya presentasi modal ini, Anda harus menyediakan delegasi transisi Anda sendiri untuk menangani presentasi dan memberhentikan animasi. Ini diuraikan dalam pembicaraan 'Transisi Ubahsuaian Menggunakan Pengontrol Tampilan' dari WWDC 2013 https://developer.apple.com/wwdc/videos/?id=218 yang juga mencakup cara menerapkan delegasi transisi Anda sendiri.

Anda dapat melihat solusi saya untuk masalah di atas di iOS7: https://github.com/hightech/iOS-7-Custom-ModalViewController-Transitions

teknologi tinggi
sumber
1
pastikan Anda mengatur modalPresentationStyle dari rootViewController, jika tidak, tidak akan berfungsi
Thorsten
Silakan lihat komentar pada jawaban ini stackoverflow.com/a/25990081/1418457 , kerjanya
onmyway133
Stackoverflow.com/q/27598846/1603234 ini membuat saya tersenyum, sekarang giliran Anda :)
Hemang
Saya harus melakukan self.modalPresentationStyle = UIModalPresentationCurrentContext; dengan pengontrol tampilan yang disajikan untuk membuatnya bekerja, bukan dengan yang menyajikan.
Tulleb
1
Periksa jawaban Brody di bawah ini. modalViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext; akan memecahkan masalah ini,
GoodSp33d

Jawaban:

143

iOS8 +

Di iOS8 + Anda sekarang dapat menggunakan modalPresentationStyle baru UIModalPresentationOverCurrentContext untuk menyajikan pengontrol tampilan dengan latar belakang transparan:

MyModalViewController *modalViewController = [[MyModalViewController alloc] init];
modalViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;           
[self presentViewController:modalViewController animated:YES completion:nil];    
Brody Robertson
sumber
5
Seharusnya jawaban yang diterima. Jawaban yang diterima sebelumnya masih valid karena alasan warisan, tetapi ini adalah metode yang direkomendasikan.
Tomasz Bąk
3
Jika Anda hanya mengembangkan untuk ios 8, ikuti jawaban ini! Ia bekerja
Mário Carvalho
2
Ini bagus, tetapi bukankah seharusnya baris terakhir [self presentViewController:modalViewController animated:YES completion:nil];? (bukan targetController)?
SuperDuperTango
3
Untuk mengerjakan ini untuk saya, saya menambahkan modalViewController.view.backgroundColor = UIColor.clearColor () terima kasih atas solusinya
Pramod
adakah yang bisa memberikan saya kode untuk pushviewcontroller juga (maksud saya untuk pengontrol navigasi).
Alok
140

Diselesaikan : Saya memperbaiki masalah. Ini bekerja dengan baik untuk iPhone dan iPad. Pengendali Modal View tanpa latar belakang hitam hanya clearColor / transparan. Satu-satunya hal yang perlu saya ubah adalah saya mengganti UIModalPresentationFullScreen ke UIModalPresentationCurrentContext. Betapa sederhananya itu!

FirstViewController.m

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
    vc.view.backgroundColor = [UIColor clearColor];
    self.modalPresentationStyle = UIModalPresentationCurrentContext;
    [self presentViewController:vc animated:NO completion:nil];

PEMBERITAHUAN: Jika Anda menggunakan properti modalPresentationStyle dari navigationController:

FirstViewController.m

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
    vc.view.backgroundColor = [UIColor clearColor];
    self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
    [self presentViewController:vc animated:NO completion:nil];

PEMBERITAHUAN: Berita buruknya adalah solusi di atas tidak berfungsi di iOS 7. Berita baiknya adalah saya memperbaiki masalah untuk iOS7! Saya meminta bantuan seseorang dan inilah yang dia katakan:

Saat menghadirkan pengontrol tampilan secara modial, iOS menghapus pengontrol tampilan di bawahnya dari hierarki tampilan selama durasi disajikan. Meskipun tampilan pengontrol tampilan yang disajikan secara transparan, tidak ada yang di bawahnya kecuali jendela aplikasi, yang berwarna hitam. iOS 7 memperkenalkan gaya presentasi modal baru, UIModalPresentationCustom, yang menyebabkan iOS tidak menghapus tampilan di bawah pengontrol tampilan yang disajikan. Namun, untuk menggunakan gaya presentasi modal ini, Anda harus menyediakan delegasi transisi Anda sendiri untuk menangani presentasi dan memberhentikan animasi. Ini diuraikan dalam pembicaraan 'Transisi Ubahsuaian Menggunakan Pengontrol Tampilan' dari WWDC 2013 https://developer.apple.com/wwdc/videos/?id=218 yang juga mencakup cara menerapkan delegasi transisi Anda sendiri.

Anda dapat melihat solusi saya untuk masalah di atas di iOS7: https://github.com/hightech/iOS-7-Custom-ModalViewController-Transitions

teknologi tinggi
sumber
1
self.modalPresentationStyle = UIModalPresentationCurrentContext;melakukannya.
Adriano Lucas
4
btw .. Saya telah mengamati bahwa karena self.modalPresentationStyle = UIModalPresentationCurrentContext; itu tidak menghadirkan modalViewController dengan animasi .. ada ide?
Devarshi
1
@Miraaj Kemudian mengatur modalPresentationStyle kembali ke UIModalPresentationFullScreen sebelum menampilkan UIViewController seharusnya berfungsiself.modalPresentationStyle = UIModalPresentationFullScreen; [self performSegueWithIdentifier:@"CustomSegue" sender:self];
hightech
1
Menjalankan ini di iOS 6 dan 7, pengendali tampilan baru jelas saat menjiwai presentasi, tetapi begitu sudah di tempat latar belakang menjadi hitam. Menjadi jelas kembali saat menjiwai pemecatan. Adakah orang lain yang mengalami masalah ini?
Drew C
3
@ pkamb Saya memperbarui solusi untuk iOS 7. stackoverflow.com/a/11252969/1344459 Saya harap ini membantu Anda.
Hightech
114

Jadi untuk pemikir visual murni dan penggemar storyboard, Anda dapat melakukan:

1. Menyajikan View Controller

Definisikan konteks

2. Pengontrol Tampilan yang Disajikan

Presentasi: Lebih Dari Konteks Saat Ini

pasevin
sumber
Ini harus menjadi jawaban yang diterima. Ini semua yang harus Anda lakukan agar ini berfungsi, kemudian atur warna latar belakang tampilan pada pengontrol modal agar dihapus.
Jesse
Setuju, opsi storyboard menimpa kode dalam kasus ini.
C0D3
17
Jawaban ini sangat manis, sekarang saya menderita diabetes.
GeneCode
25

Solusi Swift 3 & iOS10:

//create view controller
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "RoadTripPreviewViewController")
//remove black screen in background
vc.modalPresentationStyle = .overCurrentContext
//add clear color background
vc.view.backgroundColor = UIColor.clear
//present modal
self.present(vc, animated: true, completion: nil)
Kevin ABRIOUX
sumber
16

Ini dari xCode 7 beta 4 menggunakan kontrol drag segue. Cukup setel latar belakang tujuan Anda untuk menghapus, dan atur properti segue di IB karena ini (nb. Presentasi juga bisa "Di Atas Layar Penuh"):

masukkan deskripsi gambar di sini

smileBot
sumber
2
TERIMA KASIH. saya melakukan segue Anda memperbaiki + jawaban ViewControllers oleh @pasevin dan berhasil !!
CSawy
1
Ini menjawab pertanyaan saya. Terima kasih banyak. Berikan suara: D
Nate4436271
8

Saya menemukan cara termudah untuk membuatnya berfungsi di iOS7 dan iOS8 adalah dengan menambahkan set presentasentyle ke UIModalPresentationOverCurrentContext pada modallyPresentedVC (ViewController yang ingin Anda presentasikan secara digital) karena iOS8:

[modallyPresentedVC setModalPresentationStyle:UIModalPresentationOverCurrentContext];
[modallyPresentedVC.navigationController setModalPresentationStyle:UIModalPresentationOverCurrentContext];

dan UIModalPresentationCurrentContext pada presentingVC (controller yang menyajikan modallyPresented) karena iOS7:

[presentingVC setModalPresentationStyle:UIModalPresentationCurrentContext];
[presentingVC.navigationController setModalPresentationStyle:UIModalPresentationCurrentContext];

Karena semuanya ditangani secara berbeda pada iOS7 dan iOS8. Tentu saja Anda tidak perlu mengatur properti navigationController jika Anda tidak menggunakannya. Semoga itu bisa membantu.

3vangelos
sumber
menyelamatkan dagingku! Terima kasih
Bebek
5

Versi Swift2:

let vc = self.storyboard!.instantiateViewControllerWithIdentifier("YourViewController") as! YourViewController
vc.view.backgroundColor = UIColor.clearColor()
vc.modalPresentationStyle = UIModalPresentationStyle.OverFullScreen // orOverCurrentContext to place under navigation
self.presentViewController(vc, animated: true, completion: nil)
Mojtabye
sumber
4

Cara lain (tidak perlu membuat transisi khusus dan berfungsi di iOS 7)

Menggunakan Storyboard:

Buat Pengendali Tampilan Anak dengan ukuran kebebasan, atur lebar tampilan menjadi 500x500 (misalnya) dan tambahkan metode selanjutnya:

- (void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];
    self.view.superview.bounds = CGRectMake(0, 0, 500, 500);
    self.view.superview.backgroundColor = [UIColor clearColor];
}

Kemudian buat Segue Modal dengan Lembar Formulir dan mengujinya.

educaPix
sumber
Kamu luar biasa !!! ini benar-benar berfungsi !!! (pengaturan ukuran "kebebasan" dalam IB tidak mempengaruhi anithing karena itu adalah metrik yang disimulasikan, tapi bagaimanapun, itu berfungsi !!!) dan itu sangat sederhana !!!
Radu Simionescu
4

Solusi iOS 7 dengan segmen khusus:

CustomSegue.h
#import <UIKit/UIKit.h>

    @interface CustomSegue : UIStoryboardSegue <UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning>

    @end



CustomSegue.m
#import "CustomSegue.h"

@implementation CustomSegue

-(void)perform {

    UIViewController* destViewController = (UIViewController*)[self destinationViewController];
    destViewController.view.backgroundColor = [UIColor clearColor];
    [destViewController setTransitioningDelegate:self];
    destViewController.modalPresentationStyle = UIModalPresentationCustom;
    [[self sourceViewController] presentViewController:[self destinationViewController] animated:YES completion:nil];
}


//===================================================================
// - UIViewControllerAnimatedTransitioning
//===================================================================

- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext {
    return 0.25f;
}

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {

    UIView *inView = [transitionContext containerView];
    UIViewController* toVC = (UIViewController*)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIViewController* fromVC = (UIViewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

    [inView addSubview:toVC.view];

    CGRect screenRect = [[UIScreen mainScreen] bounds];
    [toVC.view setFrame:CGRectMake(0, screenRect.size.height, fromVC.view.frame.size.width, fromVC.view.frame.size.height)];

    [UIView animateWithDuration:0.25f
                     animations:^{

                         [toVC.view setFrame:CGRectMake(0, 0, fromVC.view.frame.size.width, fromVC.view.frame.size.height)];
                     }
                     completion:^(BOOL finished) {
                         [transitionContext completeTransition:YES];
                     }];
}


//===================================================================
// - UIViewControllerTransitioningDelegate
//===================================================================

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {

    return self;
}

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
    //I will fix it later.
    //    AnimatedTransitioning *controller = [[AnimatedTransitioning alloc]init];
    //    controller.isPresenting = NO;
    //    return controller;
    return nil;
}

- (id <UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id <UIViewControllerAnimatedTransitioning>)animator {
    return nil;
}

- (id <UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id <UIViewControllerAnimatedTransitioning>)animator {
    return nil;
}

@end

Solusi berdasarkan kode hightech.

Max Gribov
sumber
Ketika saya mengabaikannya oleh [self dismissViewControllerAnimated: YES completion: NULL]; Saya mendapat pengecualian ??
Asadullah Ali
Ya untuk kode ini. Atau Anda harus menerapkan metode animationControllerForDismissedController untuk memulai animasi.
Max Gribov
4

Bagi saya ini berfungsi:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main_iPhone" bundle:nil];
    UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"MMPushNotificationViewController"];

    vc.view.backgroundColor = [UIColor clearColor];
    self.modalPresentationStyle = UIModalPresentationCurrentContext;
#ifdef __IPHONE_8_0
    if(IS_OS_8_OR_LATER)
    {
        self.providesPresentationContextTransitionStyle = YES;
        self.definesPresentationContext = YES;
        [vc setModalPresentationStyle:UIModalPresentationOverCurrentContext];
    }
#endif


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

MMPushNotificationViewControlleradalah pengontrol Transparent View dan juga saya telah membuat MMPushNotificationViewControllerwarna tampilan sebagai clearcolor. Sekarang semua yang saya lakukan telah selesai dan membuat Transparentviewcontroller saya.

Manab Kumar Mal
sumber
2

Untuk iOS7

Sekarang ada cara untuk mencapai ini menggunakan transisi khusus iOS7, dengan cara ini:

MyController * controller = [MyController new];
[controller setTransitioningDelegate:self.transitionController];
controller.modalPresentationStyle = UIModalPresentationCustom;
[self controller animated:YES completion:nil];

Untuk membuat transisi khusus Anda, Anda perlu 2 hal:

  • Objek TransitionDelegate (menerapkan <UIViewControllerTransitionDelegate> )
  • Objek "AnimatedTransitioning" (menerapkan <UIViewControllerAnimatedTransitioning>)

Anda dapat menemukan lebih banyak informasi tentang transisi khusus dalam tutorial ini .

Kirualex
sumber
Adakah alasan khusus mengapa Anda telah menambahkan mainviewcontroller dan kelas pengontrol tampilan kedua di kelas animator? mengapa Anda tidak langsung menggunakan UIViewController * toVC = (UIViewController *) [transitionContext viewControllerForKey: UITransitionContextToViewControllerKey]; UIViewController * fromVC = (UIViewController *) [transisiContext viewControllerForKey: UITransitionContextFromViewControllerKey];
Satyam Raikar
Ini bukan tutorial saya jadi saya tidak tahu seluk beluk tentang ini. Poin Anda tampaknya valid.
Kirualex
2

Berfungsi Luar Biasa di iOS7 dan iOS8

UIViewController* vc=[[UIViewController alloc]initWithNibName:@"VC" bundle:nil];

vc.view.alpha=0.7;
[vc setModalPresentationStyle:UIModalPresentationOverCurrentContext];

self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;

[self presentViewController:vc animated:NO completion:nil];
hoppus
sumber
Duplikat dari jawaban terbaik kedua.
Tomasz Bąk
2

Anda juga dapat 'menambahkan kembali' jendela ke tampilan.

OneViewController *vc = [[OneViewController alloc] init];
if ([self respondsToSelector:@selector(presentViewController:animated:completion:)]) {
    [self presentViewController:vc animated:YES completion:nil];
} else {
    [self presentModalViewController:vc animated:YES];
}

[[[UIApplication sharedApplication] keyWindow] insertSubview:self.view atIndex:0];

Dan dengan cara ini, presentasi dapat dianimasikan.

Elf Sundae
sumber
1

Untuk iOS 7 dan hanya dengan menggunakan Interface Builder, hal itu dapat dicapai dengan mengatur Presentasi ke "Over Current Context" pada semua pengontrol tampilan yang terlibat dalam presentasi modal. Bahkan untuk pengontrol navigasi.

Misalnya, atur di semua pengontrol tampilan ini:

NavController -> RootViewController -> ModalViewController

masukkan deskripsi gambar di sini

David Hernandez
sumber
0

Saya belum pernah bermain-main dengan Storyboard / pembangun Antarmuka banyak, tapi apa yang muncul pada saya adalah bahwa Anda mengatakan tampilan berwarna jernih (mis. 100% alpha / tembus pandang) dan juga mengatakan itu buram ( 0% alpha - benar-benar solid). Kedua hal ini tampaknya tidak bertautan. Saya akan berkomentarself.view.opaque = YES; baris dan melihat apakah itu berfungsi;)

Ah, sesuatu yang lain yang baru saja saya pikirkan - sangat mungkin pengontrol tampilan Anda TIDAK memiliki latar belakang alfa, tetapi tentu saja alfa akan menunjukkan warna jendela dasar atau pengontrol tampilan akar program, yang oleh hitam standar. Lapisan paling dasar dari seluruh aplikasi Anda tidak dapat memiliki latar belakang transparan - transparan untuk apa? Apa yang ada di baliknya? Pasti ada sesuatu untuk MELALUI transparansi. Apakah itu masuk akal?

WendiKidd
sumber
Saya mencoba mengomentari self.view.opaque = YA; line dan tidak berfungsi. :-(
hightech
Apakah Anda membaca bagian kedua dari jawaban saya? Anda mungkin tidak dapat melakukan apa yang Anda inginkan, tergantung pada pengaturan Anda. Apa yang Anda tempatkan di belakang clearColor VC? Mungkin kita bisa menyelesaikan ini ^^
WendiKidd
-3

Cukup gunakan "self.modalPresentationStyle = UIModalPresentationCurrentContext;", dalam menyajikan tampilan

Akan bekerja dengan baik :)

Venkateswarlu.NP
sumber
1
Ini hanya mengulangi apa yang sudah ada jawaban yang sudah katakan.
Pang