iOS Dim background when a view is shown

2019-02-01 08:37发布

In my main view, I do some gesture action causing some new view to be shown. At this time I want to dim the entire background (except this new view) as a good UI practice. In HTML, Javascript it looks like so - How do I get this same effect in iOS ?

enter image description here

4条回答
闹够了就滚
2楼-- · 2019-02-01 08:52

Lay a UIView over the background, set its background to [UIColor blackColor] and set its opacity to like 0.6. Then add that UIView to the parent view.

This'll dim out the background AND intercept any taps to background controls.

查看更多
爷、活的狠高调
3楼-- · 2019-02-01 09:09

While Dan's suggestion is on target, you cannot use a modal view controller in this case because a typical modal covers the entire screen, blocking the parent view controller, even if you have the background of your view as transparent (you'll see whatever you have in the application's UIWindow).

If you are doing this on the iPad there are 2 modal presentation styles (UIViewModalPresentationStylePageSheet and UIViewModalPresentationStyleFormSheet) that can do something similar, but those will not work on an iPhone or iPod Touch.

Add the "shadow" view, with the dark background and partial opacity and whatever view you want to be in the foreground, to the view controller's view directly. You can animate them in using standard UIView animation blocks, or CoreAnimation.

Another note, if you want to intercept touches to that shadow view you can either make it a giant button, subclass UIView to override one of the touch methods like touchesEnded: or change it to a UIControl which can receive touch events like a UIButton, but without the extra options for text, shadows, states etc.

查看更多
孤傲高冷的网名
4楼-- · 2019-02-01 09:10

The above two answers work if the new view has it's own 'background', i.e. has no transparency. The problem that led me here cannot be solved that way though, what I was trying to do is this: I'm running an AVCaptureSession on my screen with the usual AVCaptureVideoPreviewLayer to display video in real time. I want to select a part of the screen (to later do something with only this part), and when this part is selected want to dim the rest of the video preview. This is what it looks like:

This is how I solved this: A new view is created depending on where the screen is touched and added as a subview of the video preview view. Then, I create 4 additional, non-overlapping rectangular subviews with the before-mentioned background color and opacity to cover the rest of the screen. I explicitly need all these views not to be subviews of the main view, because I need the ability to touch the screen somewhere else and change the selected area.

I'm sure there are more elegant ways to solve this, so if someone knows how please comment...

查看更多
走好不送
5楼-- · 2019-02-01 09:11
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController<UIGestureRecognizerDelegate>
{
    UIView *mainView;
    UIView *dimBackgroundUIView;
    UIView *customView;

    UIButton *btn;
}

@end


#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    mainView = [[UIView alloc] init];
    mainView.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:mainView];
    [self addConstraintsForMainView];

    btn = [[UIButton alloc] initWithFrame:CGRectMake(200, 200, 100, 30)];
    [btn setTitle:@"Button" forState:UIControlStateNormal];
    [btn setBackgroundColor:[UIColor blueColor]];
    [btn addTarget:self action:@selector(showCustomView_Action:) forControlEvents:UIControlEventTouchUpInside];
    [mainView addSubview:btn];

    dimBackgroundUIView = [[UIView alloc] init];
    dimBackgroundUIView.backgroundColor = [UIColor blackColor];
    dimBackgroundUIView.alpha = 0.2;
}

-(void)removeCustomViewsFromSuperView {

    if(dimBackgroundUIView)
        [dimBackgroundUIView removeFromSuperview];

    if(customView)
        [customView removeFromSuperview];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)showCustomView_Action:(id)sender {

    customView = [[UIView alloc] initWithFrame:CGRectMake(100, 200, 80, 80)];
    customView.backgroundColor = [UIColor redColor];

    [self.view addSubview:dimBackgroundUIView];
    [self addConstraintsForDimView];

    [self.view addSubview:customView];

    UITapGestureRecognizer *tapped = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(removeCustomViewsFromSuperView)];
    tapped.delegate=self;
    tapped.numberOfTapsRequired = 1;
    [customView addGestureRecognizer:tapped];
}

-(void) addConstraintsForDimView {

    [dimBackgroundUIView setTranslatesAutoresizingMaskIntoConstraints:NO];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:dimBackgroundUIView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1 constant:0]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:dimBackgroundUIView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1 constant:0]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:dimBackgroundUIView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1 constant:0]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:dimBackgroundUIView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1 constant:0]];
}

-(void) addConstraintsForMainView {

    [mainView setTranslatesAutoresizingMaskIntoConstraints:NO];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:mainView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1 constant:0]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:mainView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1 constant:0]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:mainView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1 constant:0]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:mainView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1 constant:0]];
}

@end

note: you can optimise the code by using graphical interface on Xcode but i had to write code programmatically to be able to test it

so the idea is to:

  1. create UIView name it what you want (dimBackgroundUIView) than set the backgroundcolor as Black and set alfa to 0.1 or 0.2 or....
  2. add this 2 line of code when you need to dim the background:[self.view addSubview:dimBackgroundUIView]; [self addConstraintsForDimView];
  3. and add this 2 line of code when you want to remove the dimming background: if(dimBackgroundUIView) [dimBackgroundUIView removeFromSuperview];
查看更多
登录 后发表回答