iOS: Modal ViewController ที่มีพื้นหลังโปร่งใส


180

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

- (IBAction)pushModalViewControllerButtonPressed:(id)sender
{
    ModalViewController *modalVC = [[ModalViewController alloc] init];
    [self presentViewController:modalVC animated:YES completion:nil];
}

ฉันรู้ว่าฉันสามารถเพิ่มมุมมองเป็นมุมมองย่อยได้ แต่ฉันต้องการหลีกเลี่ยงวิธีนี้ด้วยเหตุผลบางอย่าง ฉันจะแก้ไขได้อย่างไร


4
@TheKing ฟังดูเหมือนว่า Michael เหมือนกับฉันต้องการให้ modal view เป็นแบบโปร่งแสงเพื่อให้ปรากฏเป็นเลเยอร์เจลที่ลอยอยู่เหนือมุมมอง primary (การนำเสนอ) สร้างความรู้สึกของผู้ใช้ที่อยู่ในบริบทปัจจุบันในขณะที่ทำการตั้งค่าอย่างรวดเร็วเมื่อเทียบกับการทำงานหลักอื่น ๆ (ในมุมมองที่แยกต่างหาก)
Basil Bourque

stackoverflow.com/q/27598846/1603234นี้ทำให้ฉันยิ้มตอนนี้ถึงตาคุณแล้ว :)
Hemang

ดูคำตอบของฉันได้ที่นี่stackoverflow.com/a/29794201/1606125สำหรับ iOS 8
Pankaj Wadhwa

รุ่น swift ที่นี่stackoverflow.com/a/34578402/3380878
Mojtabye

1
สำหรับ iOS 10 ทำงาน UIModalPresentationOverFullScreen ตาม inigo333 ที่กล่าวถึงด้านล่าง
Josef Rysanek

คำตอบ:


97

รหัสต่อไปนี้ใช้งานได้บน iPad เท่านั้น

self.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:modalVC animated:YES];

ฉันจะไปกับการเพิ่มมุมมองย่อย

นี่คือการสนทนาที่ดีมาก ดูความคิดเห็นเฉพาะ ไม่เพียงคำตอบ

ดู Modal

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

แก้ไข:

ตามที่กล่าวไว้โดย Paul Linsay ตั้งแต่ iOS 8 สิ่งที่จำเป็นต้องมีUIModalPresentationOverFullScreenสำหรับ modalPresentationStyle ของ ViewController ที่นำเสนอ นี่จะครอบคลุมปุ่มนำทางบาร์และแท็บบาร์ด้วย


18
มันไม่ทำงานบน iOS 7 และบน iPhone, สิ่งที่คุณจะต้องระบุmodalPresentationStyle = UIModalPresentationCurrentContextในพรีเซนเตอร์ควบคุมดูและไม่ได้อยู่ในที่นำเสนอหนึ่ง
redent84

6
ใช่มันใช้งานได้ แต่เฉพาะเมื่อคุณตั้งค่านี้ในลำดับชั้นการดูที่สูงขึ้น ViewController(เช่น. NavigationControllerหรืออินสแตนซ์ของตัวควบคุมมุมมองเมนูสไลด์ของคุณเป็นต้น)
iGranDav

4
ในกรณีของฉันมันใช้งานได้หลังจากตั้งค่าสไตล์โมดอลเป็นUIModalPresentationCustomเท่านั้นและถ้าตั้งค่าไว้ก่อนหน้าpresentViewControllerแทนที่จะเข้าviewDidLoadมา
mojuba

5
ตั้งแต่ iOS 8 สิ่งที่จำเป็นต้องมีคือ UIModalPresentationOverFullScreen สำหรับ modalPresentationStyle ของ ViewController
Paul Linsay

1
หลังจากที่ประมาณ 1000 ครั้งฉันตระหนักคุณจะต้องตั้งก่อนmodalPresentationStyle viewDidLoadฉันทำมันในตัวสร้างและมันทำงานได้
bendytree

186

สำหรับผู้ที่พยายามที่จะได้รับการทำงานใน iOS 8, "แอปเปิ้ลได้รับการอนุมัติ" วิธีที่จะแสดงตัวควบคุมมุมมองกิริยาโปร่งใสโดยการตั้งค่าmodalPresentationStyle ในปัจจุบันเอ็ดควบคุมUIModalPresentationOverCurrentContextการ

ซึ่งสามารถทำได้ในรหัสหรือโดยการตั้งค่าคุณสมบัติของ segue ในกระดานเรื่องราว

จากเอกสารประกอบ UIViewController:

UIModalPresentationOverCurrentContext

สไตล์การนำเสนอที่เนื้อหาจะแสดงบนเนื้อหาของตัวควบคุมมุมมองหลักเท่านั้น มุมมองด้านล่างเนื้อหาที่นำเสนอจะไม่ถูกลบออกจากลำดับชั้นการดูเมื่องานนำเสนอเสร็จสิ้น ดังนั้นหากตัวควบคุมมุมมองที่นำเสนอไม่เต็มหน้าจอที่มีเนื้อหาทึบแสงเนื้อหาพื้นฐานจะแสดงผ่าน

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

พร้อมใช้งานใน iOS 8.0 และใหม่กว่า

https://developer.apple.com/documentation/uikit/uiviewcontroller

วิดีโอ 'View Controller Advancements ใน iOS 8' จาก WWDC 2014 มีรายละเอียดดังนี้

บันทึก:

  • ตรวจสอบให้แน่ใจว่าได้ให้สีพื้นหลังของตัวควบคุมมุมมองที่นำเสนอของคุณชัดเจนว่าจริง ๆ แล้วไม่ได้ดูผ่าน!
  • คุณต้องตั้งค่านี้ก่อนที่จะนำเสนอเช่นการตั้งค่าพารามิเตอร์นี้ในviewDidLoadของ presentationViewController จะไม่มีผลกระทบใด ๆ

32
หมายเหตุ - ปรากฏเป้าหมายที่คุณต้องการตั้งค่าmodalPresentationStyleมีการเปลี่ยนแปลง ยกตัวอย่างเช่นใน iOS 7 จะได้รับนี้ไปทำงานผมจำเป็นต้องมีการตั้งค่าmodalPresentationStyleของดู Controller (s) ซึ่งเป็นความพยายามที่จะเปิดกิริยาเพื่อUIModalPresentationCurrentContext อย่างไรก็ตามเพื่อให้ได้รับการทำงานใน iOS8 ผมต้องตั้งค่าmodalPresentationStyleของมุมมองกิริยาซึ่งจะต้องแสดงให้UIModalPresentationOverCurrentContext
u2Fan

1
หากใช้งาน segues ในกระดานเรื่องราวของคุณคุณต้องกำหนดสไตล์การนำเสนอที่นั่น อย่างน้อยนี่คือสิ่งที่ได้ผลสำหรับฉัน
Julian B.

ฉันเพิ่มสามบรรทัดเหล่านี้ในวิธีการเริ่มต้นในตัวควบคุมมุมมองที่นำเสนอและทำงานเหมือนมีเสน่ห์: self.providesPresentationContextTransitionStyle = YES; self.definesPresentationContext = YES; [ตนเอง setModalPresentationSStyle: UIModalPresentationOverCurrentContext];
inigo333

2
ใน iOS 8+ ฉันต้องนำเสนอ modal จาก UINavigationController ดังนั้นการนำเสนอจากเด็กจึงไม่ได้ให้สิ่งที่ฉันต้องการ แต่เป็นsourceVC self.navigationControllerนอกจากนี้หลังจากตั้งค่าสไตล์การนำเสนอเป้าหมายเป็นกำหนดเองฉันสามารถดูได้ [sourceVC setModalPresentationStyle:UIModalPresentationCurrentContext];, [targetVC setModalPresentationStyle:UIModalPresentationCustom];หวังว่ามันจะช่วยให้คน
devdc

หมายเหตุ - โทรpresentedVC.modalPresentationStyle = UIModalPresentationOverCurrentContextในการนำเสนอ VC ไม่ทำงานในการนำเสนอVC เชื่อใจฉันฉันพยายาม
smileham

104

ใน iOS 8.0 ขึ้นไปสามารถทำได้โดยการตั้งค่าคุณสมบัติmodalPresentationStyleเป็นUIModalPresentationOverCurrentContext

//Set property **definesPresentationContext** YES to avoid presenting over presenting-viewController's navigation bar

self.definesPresentationContext = YES; //self is presenting view controller
presentedController.view.backgroundColor = [YOUR_COLOR with alpha OR clearColor]
presentedController.modalPresentationStyle = UIModalPresentationOverCurrentContext;

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

ดูรูปภาพที่แนบมา


5
นี่เป็นทางออกเดียวที่ฉันสามารถทำงานได้ ง่ายมากเช่นกัน เพียงเพิ่มส่วนนี้ลงใน VC ที่นำเสนอของคุณก่อนที่จะทำคำกริยา
Siriss

1
Xcoe 9.2 / iOS 11.2 รวดเร็ว.customและ.overFullScreenทำงานได้
William Hu

และดูเหมือนว่าถ้าคุณตั้งค่า.overFullScreenตัวควบคุมมุมมองปัจจุบันviewWillAppearจะไม่ถูกเรียก
William Hu

สิ่งหนึ่งที่มากขึ้นpresentedController.view.backgroundColor = #color#ควรจะเขียนในpresentedController's viewDidLoadหรืออื่น ๆ ที่presentedControllerชีวิตถูกขัดจังหวะ
DawnSong

44

รหัสนี้ใช้งานได้ดีบน iPhone ภายใต้ iOS6 และ iOS7:

presentedVC.view.backgroundColor = YOUR_COLOR; // can be with 'alpha'
presentingVC.modalPresentationStyle = UIModalPresentationCurrentContext;
[presentingVC presentViewController:presentedVC animated:YES completion:NULL];

ในกรณีนี้คุณพลาดการเคลื่อนไหวแบบสไลด์บน เพื่อรักษาภาพเคลื่อนไหวคุณยังสามารถใช้ส่วนขยาย "ไม่หรูหรา" ต่อไปนี้:

[presentingVC presentViewController:presentedVC animated:YES completion:^{
    [presentedVC dismissViewControllerAnimated:NO completion:^{
        presentingVC.modalPresentationStyle = UIModalPresentationCurrentContext;
        [presentingVC presentViewController:presentedVC animated:NO completion:NULL];
    }];
}];

หาก presentingV ของเราตั้งอยู่ภายใน UINavigationController หรือ UITabbarController คุณจำเป็นต้องใช้งานร่วมกับคอนโทรลเลอร์ดังกล่าวเพื่อนำเสนอ VC

นอกจากนี้ใน iOS7 คุณสามารถใช้แอนิเมชั่นการเปลี่ยนผ่านที่กำหนดเองโดยใช้UIViewControllerTransitioningDelegateโปรโตคอล แน่นอนในกรณีนี้คุณจะได้พื้นหลังโปร่งใส

@interface ModalViewController : UIViewController <UIViewControllerTransitioningDelegate>

ก่อนอื่นคุณต้องตั้งค่า modalPresentationStyle

modalViewController.modalPresentationStyle = UIModalPresentationCustom;

จากนั้นคุณต้องใช้วิธีการโปรโตคอลสองวิธี

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
{
    CustomAnimatedTransitioning *transitioning = [CustomAnimatedTransitioning new];
    transitioning.presenting = YES;
    return transitioning;
}

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
    CustomAnimatedTransitioning * transitioning = [CustomAnimatedTransitioning new];
    transitioning.presenting = NO;
    return transitioning;
}

สิ่งสุดท้ายคือการกำหนดการเปลี่ยนแปลงที่กำหนดเองของคุณในCustomAnimatedTransitioningชั้นเรียน

@interface CustomAnimatedTransitioning : NSObject <UIViewControllerAnimatedTransitioning>
@property (nonatomic) BOOL presenting;
@end

@implementation CurrentContextTransitionAnimator

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

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext 
{
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

    if (self.presenting) {
        // custom presenting animation
    }
    else {
        // custom dismissing animation
    }
}

7
ยืนยันงานนี้ โปรดทราบว่าถ้า viewController ของคุณอยู่ใน navigationController ให้แน่ใจว่าmodalPresentationStyleได้ตั้งค่าแล้ว!
mxcl

ฉันคิดว่าในกรณีทั่วไปมันเป็นความคิดที่ดีที่จะปฏิบัติต่อตัวควบคุมการนำทางของคุณเหมือนการนำเสนอ VC
malex

ใช่ใช้ modalPresentationSStyle เป็นไปไม่ได้ที่จะนำเสนอแอนิเมชั่น ((
malex

2
@alex ใช่ทำงานขออภัย: ข้อผิดพลาดของฉันคือการตั้ง modalPresentationStyle เป็น UIModalPresentationCurrentContext สำหรับ presentationVC แทนที่จะเป็น prenstingVC
tiguero

5
@mxcl และถ้า navigationController ของ viewController ของคุณอยู่ใน tabBarController แล้วให้แน่ใจว่า modalPresentationStyle มีการตั้งค่าเป็นเช่นนั้นด้วย)
Thomas CG de Vilhena

21

ฉันต่อสู้เล็กน้อยด้วย Interface Builder ของ XCode 7 เพื่อกำหนดรูปแบบการนำเสนอตามที่ @VenuGopalTewari แนะนำ ในรุ่นนี้ดูเหมือนจะไม่มีOver Current ContextหรือOver Full Screenโหมดการนำเสนอสำหรับการแยก ดังนั้นเพื่อให้มันทำงานได้ฉันจะตั้งโหมดเป็นDefault:

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

นอกจากนี้ฉันตั้งโหมดการนำเสนอของตัวควบคุมมุมมองที่นำเสนอ modally เป็นOver Full Screen:

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


สิ่งนี้ใช้ได้สำหรับฉันไม่จำเป็นต้องใช้รหัส ฉันใช้ Xcode 7.2, swift และเป้าหมายคือ iOS 8.0
LightMan

มันก็ใช้ได้กับฉันเช่นกัน +1 สำหรับคำตอบที่ถูกต้อง ขอบคุณ :)
Augustine PA

คำตอบที่ดีที่สุดที่นี่!
ShinyuX

1
ไม่มีรหัส = คำตอบที่ดีที่สุด บาสเตียนชนะเกมนี้ กรุณา +1 ทั้งหมดนี้คำตอบ
GeneCode

คำตอบนี้ใช้ได้ .. ใช้เวลามากกว่าหนึ่งชั่วโมงในการนี้
user578386

18

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

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


3
ฉันชื่นชมนักโต้คลื่น 100% มันได้ผล! กุญแจสำคัญคือการใช้มันใน segue ขอบคุณมาก
Badr

ถ้าคุณไม่ได้ทำต่อของคุณติดยาเสพติดให้กับปุ่มและคุณเรียกมันว่าโปรแกรมแล้วให้แน่ใจว่าการตั้งค่าตัวระบุและเพื่อเรียกร้อง performSegueWithIdentifier แทน presentViewController
user3344977

1
ฉันลองคำตอบอื่น ๆ ทั้งหมด แต่นี่เป็นคำตอบเดียวที่ใช้ได้กับฉันใน iOS9
endavid

14

PresentViewController ที่มีพื้นหลังโปร่งใส - ใน iOS 8 และ iOS 9

MYViewController *myVC = [self.storyboard   instantiateViewControllerWithIdentifier:@"MYViewController"];
    myVC.providesPresentationContextTransitionStyle = YES;
    myVC.definesPresentationContext = YES;
    [myVC setModalPresentationStyle:UIModalPresentationOverCurrentContext];
    [self.navigationController presentViewController:myVC animated:YES completion:nil];

และใน MYViewController ตั้งค่าสีพื้นหลังเป็นสีดำและลดความทึบ


12

เป็นวิธีที่แฮ็กเล็กน้อย แต่สำหรับฉันรหัสนี้ใช้งานได้ (iOS 6):

AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

[self presentViewController:self.signInViewController animated:YES completion:^{
    [self.signInViewController dismissViewControllerAnimated:NO completion:^{
        appDelegate.window.rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
        [self presentViewController:self.signInViewController animated:NO completion:nil];
        appDelegate.window.rootViewController.modalPresentationStyle = UIModalPresentationFullScreen;

    }];
}];

รหัสนี้ใช้ได้กับ iPhone


ขอบคุณ - นี่คือสิ่งที่ฉันต้องการ - แสดงหน้าจอ "เริ่มต้น" ที่ด้านบนของหน้าหลัก สวย!
Matt H

1
วันนี้ฉันใช้เวลาเกือบ 3 ชั่วโมงในการค้นหาและค้นหาโซลูชันที่ใช้งานได้ทั้ง iOS7 และ iOS8 พิจารณาข้อเท็จจริงที่ว่าคำตอบนี้มีอายุ 1.5 ปีและฉันใช้ ECSlidingViewController นี่เป็นทางออกเดียวที่ทำงานได้! ขอบคุณ @ Mak
Centurion

สมบูรณ์ นอกจากนี้ถ้าคุณไม่สนใจเกี่ยวกับอนิเมชั่น 3 เส้นที่อยู่ในความสมบูรณ์ด้านในนั้นจะทำงานได้อย่างสมบูรณ์แบบขอบคุณ!
RasTheDestroyer

หลังจาก 3 ชั่วโมงที่ใช้ไปโดยไม่ประสบความสำเร็จพบสิ่งนี้ไชโยหวังว่าฉันจะได้คะแนนมากขึ้น: D
alessioarsuffi

11

หมวดหมู่นี้ใช้งานได้สำหรับฉัน (iOS 7, 8 และ 9)

ไฟล์ H

@interface UIViewController (navigation)
- (void) presentTransparentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion;
@end

ไฟล์ M

@implementation UIViewController (navigation)
- (void)presentTransparentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion
{
    if(SYSTEM_VERSION_LESS_THAN(@"8.0")) {
        [self presentIOS7TransparentController:viewControllerToPresent withCompletion:completion];

    }else{
        viewControllerToPresent.modalPresentationStyle = UIModalPresentationOverCurrentContext;
         [self presentViewController:viewControllerToPresent animated:YES completion:completion];
    }
}
-(void)presentIOS7TransparentController:(UIViewController *)viewControllerToPresent withCompletion:(void(^)(void))completion
{
    UIViewController *presentingVC = self;
    UIViewController *root = self;
    while (root.parentViewController) {
        root = root.parentViewController;
    }
    UIModalPresentationStyle orginalStyle = root.modalPresentationStyle;
    root.modalPresentationStyle = UIModalPresentationCurrentContext;
    [presentingVC presentViewController:viewControllerToPresent animated:YES completion:^{
        root.modalPresentationStyle = orginalStyle;
    }];
}
@end

1
ฉันตรวจสอบคำตอบทั้งหมด .. แต่สำหรับฉันคำตอบของคุณคืองานที่สมบูรณ์แบบ .. "+1" สำหรับสิ่งนี้ @Ted
g212gs

1
ฉันคิดว่าฉันหาทางออกไม่ได้ ขอบคุณมาก!
CopperCash

10

ทางออกสำหรับคำตอบนี้โดยใช้ swift จะเป็นดังนี้

let vc = MyViewController()
vc.view.backgroundColor = UIColor.clear // or whatever color.
vc.modalPresentationStyle = .overCurrentContext
present(vc, animated: true, completion: nil)

9

หากคุณใช้ Storyboard คุณสามารถทำตามขั้นตอนนี้:

  1. เพิ่มตัวควบคุมมุมมอง (V2) ตั้งค่า UI ตามที่คุณต้องการ
  • เพิ่ม UIView - ตั้งค่าพื้นหลังเป็นสีดำและทึบถึง 0.5
  • เพิ่ม UIView อื่น (2) - ที่จะทำหน้าที่เป็นป๊อปอัพของคุณ (โปรดทราบว่า UIView และ UIView (2) จะต้องมีระดับ / ลำดับชั้นเดียวกันอย่าทำให้ภาพดูลูกของมุมมองมิฉะนั้นความทึบของ Uiview จะ ส่งผลกระทบต่อ UIView (2))
  1. ปัจจุบัน V2 Modally

  2. คลิกที่ทำต่อ ในการตรวจสอบคุณสมบัติชุดนำเสนอเป็นหน้าจอแบบเต็มกว่า ลบภาพเคลื่อนไหวหากคุณต้องการ

สตอรี่บอร์ด

  1. เลือก V2 ในการตรวจสอบคุณสมบัติชุดนำเสนอเป็นหน้าจอแบบเต็มกว่า ตรวจสอบกำหนดบริบทและให้บริบท

สตอรี่บอร์ด

  1. เลือก MainView ของ V2 ของคุณ (กรุณาตรวจสอบภาพ) ตั้ง backgroundColor เป็นClear Color

สตอรี่บอร์ด


6

ฉันเพิ่มสามบรรทัดในเมธอด init ในตัวควบคุมมุมมองที่นำเสนอและใช้งานได้อย่างมีเสน่ห์:

self.providesPresentationContextTransitionStyle = YES;
self.definesPresentationContext = YES;
[self setModalPresentationStyle:UIModalPresentationOverCurrentContext];

แก้ไข (ทำงานบน iOS 9.3):

self.modalPresentationStyle = UIModalPresentationOverFullScreen;

ตามเอกสาร:

UIModalPresentationOverFullScreen สไตล์การนำเสนอมุมมองซึ่งมุมมองที่นำเสนอครอบคลุมหน้าจอ มุมมองด้านล่างเนื้อหาที่นำเสนอจะไม่ถูกลบออกจากลำดับชั้นการดูเมื่องานนำเสนอเสร็จสิ้น ดังนั้นหากตัวควบคุมมุมมองที่นำเสนอไม่เต็มหน้าจอที่มีเนื้อหาทึบแสงเนื้อหาพื้นฐานจะแสดงผ่าน

พร้อมใช้งานใน iOS 8.0 และใหม่กว่า


1
ทำงานบน iOS 10.2
Josef Rysanek

4

วิธีอื่นคือใช้ "มุมมองคอนเทนเนอร์" เพียงแค่ทำให้อัลฟาต่ำกว่า 1 และฝังด้วย seque XCode 5 เป้าหมาย iOS7 ทดสอบบน iPhone

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

ดูคอนเทนเนอร์จาก iOS6 เชื่อมโยงไปยังบล็อกโพสต์เกี่ยวกับเรื่องนั้น


3

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

มันมีวิธีการเดียวที่เรียบง่ายที่ทำสิ่งนี้:

- (void)presentViewController:(UIViewController *)presentedViewController
       fromViewController:(UIViewController *)presentingViewController
{
    presentedViewController.modalPresentationStyle = UIModalPresentationCustom;
    presentedViewController.transitioningDelegate = self;
    presentedViewController.modalPresentationCapturesStatusBarAppearance = YES;

    [presentedViewController setNeedsStatusBarAppearanceUpdate];

    [presentingViewController presentViewController:presentedViewController
                                       animated:YES
                                     completion:nil];
}

มันเป็นสิ่งสำคัญในการกำหนดmodalPresentationCapturesStatusBarAppearanceคุณสมบัติการและบังคับลักษณะแถบสถานะการอัปเดตถ้าควบคุมมุมมองการนำเสนอของคุณมีที่แตกต่างกันYESpreferredStatusBarStyle

วัตถุนี้ควรมี @property (assign, nonatommic) isPresenting

คุณต้องการให้วัตถุนี้ปฏิบัติตามUIViewControllerAnimatedTransitioningและUIViewControllerTransitioningDelegateโปรโตคอลและใช้วิธีการต่อไปนี้:

- (id)animationControllerForPresentedController:(UIViewController *)presented
                           presentingController:(UIViewController *)presenting
                               sourceController:(UIViewController *)source
{
    self.isPresenting = YES;

    return self;
}

- (id)animationControllerForDismissedController:(UIViewController *)dismissed
{
    self.isPresenting = NO;

    return self;
}

และ:

- (NSTimeInterval)transitionDuration:(id)transitionContext
{
    return 0.25;
}

- (void)animateTransition:(id)transitionContext
{
    UIViewController* firstVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController* secondVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIView* containerView = [transitionContext containerView];
    UIView* firstView = firstVC.view;
    UIView* secondView = secondVC.view;

    if (self.isPresenting) {
        [containerView addSubview:secondView];
        secondView.frame = (CGRect){
            containerView.frame.origin.x,
            containerView.frame.origin.y + containerView.frame.size.height,
            containerView.frame.size
        };

        firstView.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed;
        [UIView animateWithDuration:0.25 animations:^{
            secondView.frame = containerView.frame;
        } completion:^(BOOL finished) {
            [transitionContext completeTransition:YES];
        }];
        } else {
        [UIView animateWithDuration:0.25 animations:^{
            firstView.frame = (CGRect){
                containerView.frame.origin.x,
                containerView.frame.origin.y + containerView.frame.size.height,
                containerView.frame.size
        };

        } completion:^(BOOL finished) {
            [transitionContext completeTransition:YES];
        }];
    }
}

นี่เป็นภาพเคลื่อนไหวแบบสไลด์จากด้านล่างซึ่งเป็นการเลียนแบบภาพเคลื่อนไหวแบบเริ่มต้น แต่คุณสามารถสร้างมันได้ตามที่คุณต้องการ

สิ่งสำคัญคือมุมมองของตัวควบคุมมุมมองการนำเสนอจะยังคงอยู่ที่ด้านหลังทำให้คุณสร้างเอฟเฟกต์แบบโปร่งใสได้

วิธีนี้ใช้ได้กับ iOS 7+


ขอบคุณสำหรับคำตอบ.
Salman Khakwani

3

วิธีง่ายๆในการทำสิ่งนี้ ( Storyboardsตัวอย่างเช่นใช้) คือ:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"SomeStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SomeStoryboardViewController"];
// the key for what you're looking to do:
vc.modalPresentationStyle = UIModalPresentationOverCurrentContext;
vc.view.alpha = 0.50f;

[self presentViewController:vc animated:YES completion:^{
    // great success
}];

สิ่งนี้จะนำเสนอUIViewControllerในรูปแบบที่เป็นStoryboardพื้นๆ


3

ทำงานกับ iOS 7-10

if #available(iOS 8.0, *) {
    nextVC.modalPresentationStyle = .OverCurrentContext
    self.presentViewController(nextVC, animated: true, completion: nil)
} else {
    // Fallback on earlier version
    self.modalPresentationStyle = .Custom          
    nextVC.modalTransitionStyle = .CrossDissolve            
    self.presentViewController(nextVC, animated: false, completion: nil)
    }
}

2

ในการสรุปคำตอบและข้อคิดเห็นที่ดีทั้งหมดที่นี่และยังมีภาพเคลื่อนไหวในขณะที่ย้ายไปที่ใหม่ของคุณViewControllerนี่คือสิ่งที่ฉันทำ: (รองรับ iOS 6 ขึ้นไป)

หากคุณใช้ a UINavigationController\ UITabBarControllerนี่คือวิธีไป:

    SomeViewController *vcThatWillBeDisplayed = [self.storyboard instantiateViewControllerWithIdentifier:@"SomeVC"];

    vcThatWillBeDisplayed.view.backgroundColor = [UIColor colorWithRed: 255/255.0 green:255/255.0 blue:255/255.0 alpha:0.50];    

    self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
    [self presentViewController:presentedVC animated:YES completion:NULL];

หากคุณทำเช่นนั้นคุณจะสูญเสียการmodalTransitionStyleเคลื่อนไหว เพื่อแก้ปัญหาคุณสามารถเพิ่มSomeViewControllerชั้นเรียนของคุณได้อย่างง่ายดาย:

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [UIView animateWithDuration:0.4 animations:^() {self.view.alpha = 1;}
       completion:^(BOOL finished){}];
}
- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.alpha = 0;
}

2

แน่นอนคุณควรตั้ง UIModalPresentationCurrentContext แต่สถานที่ตั้ง clearColor มีความสำคัญเช่นกัน! คุณไม่สามารถตั้งค่าพื้นหลังในฟังก์ชั่น viewDidLoad ตั้งค่าก่อนที่มุมมองจะโหลดเหมือนในตัวควบคุมรูทมุมมองหรือในฟังก์ชั่น initของตัวควบคุมที่จะนำเสนอ!

actionController.view.backgroundColor = [UIColor clearColor];
[self presentViewController:actionController animated:YES completion:nil];

หรือ

- (instancetype)init {

    self = [super initWithNibName:nil bundle:nil];

    if(self) {
        self.modalPresentationStyle = UIModalPresentationOverCurrentContext;
        [self.view setBackgroundColor:[UIColor clearColor]];
    }

    return self;
}

นี่คือคำใบ้ที่ช่วยฉันในหมู่คนอื่น ๆ ทั้งหมด ขอบคุณสำหรับความช่วยเหลือของคุณ.
Tomasz Nazarenko

1

หากคุณใช้คำกริยาช่วยให้แน่ใจว่าได้ตั้งเป็นภาพนี้ (คุณสามารถปิดภาพเคลื่อนไหวถ้าคุณต้องการ)ป้อนคำอธิบายรูปภาพที่นี่


1

วิธีการที่สมบูรณ์แบบทดสอบบน iOS 7 และ iOS 8

@interface UIViewController (MBOverCurrentContextModalPresenting)

/// @warning Some method of viewControllerToPresent will called twice before iOS 8, e.g. viewWillAppear:.
- (void)MBOverCurrentContextPresentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion;

@end

@implementation UIViewController (MBOverCurrentContextModalPresenting)

- (void)MBOverCurrentContextPresentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
    UIViewController *presentingVC = self;

    // iOS 8 before
    if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) {
        UIViewController *root = presentingVC;
        while (root.parentViewController) {
            root = root.parentViewController;
        }

        [presentingVC presentViewController:viewControllerToPresent animated:YES completion:^{
            [viewControllerToPresent dismissViewControllerAnimated:NO completion:^{
                UIModalPresentationStyle orginalStyle = root.modalPresentationStyle;
                if (orginalStyle != UIModalPresentationCurrentContext) {
                    root.modalPresentationStyle = UIModalPresentationCurrentContext;
                }
                [presentingVC presentViewController:viewControllerToPresent animated:NO completion:completion];
                if (orginalStyle != UIModalPresentationCurrentContext) {
                    root.modalPresentationStyle = orginalStyle;
                }
            }];
        }];
        return;
    }

    UIModalPresentationStyle orginalStyle = viewControllerToPresent.modalPresentationStyle;
    if (orginalStyle != UIModalPresentationOverCurrentContext) {
        viewControllerToPresent.modalPresentationStyle = UIModalPresentationOverCurrentContext;
    }
    [presentingVC presentViewController:viewControllerToPresent animated:YES completion:completion];
    if (orginalStyle != UIModalPresentationOverCurrentContext) {
        viewControllerToPresent.modalPresentationStyle = orginalStyle;
    }
}

@end

1

สวิฟท์ 4.2

guard let someVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "someVC") as? someVC else {
    return
}
someVC.modalPresentationStyle = .overCurrentContext

present(someVC, animated: true, completion: nil)

0

ใน appdelegate:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [[_window rootViewController]setModalPresentationStyle:UIModalPresentationCurrentContext];
    return YES;
}

ในตัวคุณดูคอนโทรลเลอร์ก่อนจากที่คุณต้องโหลดมุมมองถัดไป:

  NextViewController *customvc = [[NextViewController alloc]init];
    [self presentViewController:customvc animated:YES completion:^{

    }];

ใน nextViewController ของคุณที่จะเพิ่มความโปร่งใส:

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor clearColor];
    UIView* backView = [[UIView alloc] initWithFrame:self.view.frame];
    backView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6];
    [self.view insertSubview:backView atIndex:0];
}

0

หน้าจอเข้าสู่ระบบเป็นแบบโมดัลซึ่งหมายความว่ามันอยู่ด้านบนของหน้าจอก่อนหน้า จนถึงตอนนี้เรามีฉากหลังเบลอ แต่มันก็ไม่ได้พร่ามัว มันเป็นเพียงพื้นหลังสีเทา

เราจำเป็นต้องตั้ง Modal ของเราอย่างถูกต้อง

เป้าหมายลิงค์รูปภาพ

  • ก่อนอื่นเราต้องเปลี่ยนมุมมองพื้นหลังของ View Controller เป็น Clear color มันก็หมายความว่ามันควรจะโปร่งใส ตามค่าเริ่มต้นมุมมองนั้นจะเป็นสีขาว

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

เป้าหมายลิงค์รูปภาพ


0

ชุดนำทางmodalPresentationStyleไปUIModalPresentationCustom

และตั้งค่าสีพื้นหลังของตัวควบคุมมุมมองการนำเสนอของคุณเป็นสีใส

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.