6

I am displaying a disclaimer UIAlertView in my iOS app, but the default AlertView size in iOS is very small. How can I make it bigger?

It seems like something that should be simple, but from what info I have searched for there does not seem to be a way to do it?

Code,

UIAlertView* alert = [[UIAlertView alloc] initWithTitle: @"Disclaimer" message: nil delegate: self cancelButtonTitle: @"Accept" otherButtonTitles: nil];

UIWebView* webView = [[UIWebView alloc] init];
[webView setFrame:CGRectMake(0, 0, 280, 140)];
[webView loadHTMLString: html baseURL: nil];
UIView* view = [[UIView alloc] initWithFrame: CGRectMake(0, 0, 280, 140)];
[view addSubview: webView];
[alert setValue: view forKey: @"accessoryView"];
[alert show];
mmd1080
  • 1,812
  • 2
  • 17
  • 29
James
  • 17,965
  • 11
  • 91
  • 146

7 Answers7

6

First, create a view controller with your web view, let's call it MyWebViewController.

Then you can present it either as a full screen controller:

MyWebViewController* alertController = [[MyWebViewController alloc] init];
alertController.view.backgroundColor = [UIColor.lightGrayColor colorWithAlphaComponent:0.2];
alertController.modalPresentationStyle = UIModalPresentationOverFullScreen;

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

This is a full screen controller though. You will have to create a view in the center for your content, add a border for that view and keep everything around semitransparent.

You can also use a popover:

UIView *sourceView = self.view;

MyWebViewController* alertController = [[MyWebViewController alloc] init];
alertController.modalPresentationStyle = UIModalPresentationPopover;

alertController.preferredContentSize = CGRectInset(self.view.bounds, 20, 100).size;
alertController.popoverPresentationController.canOverlapSourceViewRect = YES;
alertController.popoverPresentationController.sourceView = sourceView;
alertController.popoverPresentationController.sourceRect = CGRectMake(CGRectGetMidX(sourceView.bounds), CGRectGetMidY(sourceView.bounds), 0, 0);
alertController.popoverPresentationController.permittedArrowDirections = 0;
alertController.popoverPresentationController.delegate = self;

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

The delegate also has to implement:

- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection {
    return UIModalPresentationNone;
}

The source view is usually the button which opens the popover but I am using the parent view to ensure the popover is centered.

You will also have to add the buttons which are added automatically by UIAlertView but that should be trivial.

Sulthan
  • 128,090
  • 22
  • 218
  • 270
5

You'll need to create a new class to accomplish this:

WebAlertView.h

#import <UIKit/UIKit.h>

@interface WebAlertView : UIView

- (id)initWithTitle:(NSString *)title webView:(UIWebView *)webView delegate:(id)delegate cancelButtonTitle:(NSString *)cancelButtonTitle;

- (void)show;

@end

@protocol WebAlertViewDelegate <NSObject>
@optional

- (void)webAlertViewCancel:(WebAlertView *)alertView;

@end

WebAlertView.m

#import "WebAlertView.h"

@interface WebAlertView()

@property (weak, nonatomic) UIWebView *webView;
@property (weak, nonatomic) NSString *title;
@property (weak, nonatomic) NSString *cancelButtonTitle;
@property (weak, nonatomic) id delegate;

@property (strong, nonatomic) UIView *curtainView;

@end

@implementation WebAlertView

- (id)initWithTitle:(NSString *)title webView:(UIWebView *)webView delegate:(id)delegate cancelButtonTitle:(NSString *)cancelButtonTitle {
    CGFloat titleViewHeight = 64.0;
    CGFloat cancelButtonHeight = 44.0;

    if ((self = [super initWithFrame:CGRectMake(0, 0, webView.frame.size.width, webView.frame.size.height+titleViewHeight+cancelButtonHeight)])) {

        self.backgroundColor = [UIColor groupTableViewBackgroundColor];

        _webView = webView;
        _title = title;
        _cancelButtonTitle = cancelButtonTitle;
        _delegate = delegate;

        CGRect titleViewFrame = self.frame;
        titleViewFrame.size.height = titleViewHeight;
        UILabel *label = [[UILabel alloc] initWithFrame:titleViewFrame];
        label.text = title;
        label.font = [UIFont boldSystemFontOfSize:16.0];
        label.textAlignment = NSTextAlignmentCenter;

        [self addSubview:label];

        CGRect webViewFrame = _webView.frame;
        webViewFrame.origin.y = titleViewHeight;
        _webView.frame = webViewFrame;

        [self addSubview:_webView];

        CGRect cancelButtonFrame = self.frame;
        cancelButtonFrame.size.height = cancelButtonHeight;
        cancelButtonFrame.origin.y = self.frame.size.height - cancelButtonHeight;
        UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
        button.frame = cancelButtonFrame;
        [button setTitle:cancelButtonTitle forState:UIControlStateNormal];
        button.titleLabel.font = [UIFont boldSystemFontOfSize:16.0];

        [button addTarget:self action:@selector(buttonTouchUpInside) forControlEvents:UIControlEventTouchUpInside];

        [self addSubview:button];
    }
    return self;
}

- (void)show {
    if ([_delegate isKindOfClass:[UIViewController class]]) {
        UIViewController *delegateViewController = (UIViewController *)_delegate;

        if (!_curtainView) {
            _curtainView = [[UIView alloc] initWithFrame:delegateViewController.view.bounds];
            _curtainView.backgroundColor = [UIColor blackColor];
            _curtainView.alpha = 0.5;
        }
        [delegateViewController.view addSubview:_curtainView];

        self.center = delegateViewController.view.center;

        [delegateViewController.view addSubview:self];
    }
}

- (void)drawRect:(CGRect)rect {

    self.layer.cornerRadius = 16.0;
    self.clipsToBounds = YES;
}

- (void)buttonTouchUpInside {

    [_curtainView removeFromSuperview];
    [self removeFromSuperview];

    if([_delegate respondsToSelector:@selector(webAlertViewCancel:)]) {
        [_delegate webAlertViewCancel:self];
    }
}

@end

How to use:

UIWebView* webView = [[UIWebView alloc] init];
[webView setFrame:CGRectMake(0, 0, 280, 140)];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.google.com"]];
[webView loadRequest:urlRequest];

WebAlertView *webAlertView = [[WebAlertView alloc] initWithTitle:@"Disclaimer" webView:webView delegate:self cancelButtonTitle:@"Accept"];
[webAlertView show];

Notes:

  • Only implemented cancel button- should give you an idea how to implement other buttons if you desire.
  • Nothing stops you from making the WebAlertView larger than its super view, so keep that in mind. There's also no accounting for length of title or cancelButton strings.
  • As others have mentioned, UIAlertView is deprecated.
  • Sulthan has given a good answer if you want to use a ViewController. My answer may be better if you really want something that works like UIAlertView.
mmd1080
  • 1,812
  • 2
  • 17
  • 29
0

According to Apple Documentation, the UIAlertView class is intended to be used as-is and does not support subclassing. The view hierarchy for this class is private and must not be modified.

To customise the size, please use JSSAlertView instead of UIAlertView

Anton Volkov
  • 109
  • 1
  • 10
0

UIAlertView is deprecated in iOS 9.0. You need to start using UIAlertController. To my knowledge we can increase the size of UIAlertController. I have tried all the ways.

Vamsy
  • 74
  • 7
0

you have to create Custom View by own third party: because In UIAlertView and UIAlertController frame adjustment does not work.

Ajjjjjjjj
  • 669
  • 4
  • 12
0

Use NSLayoutConstraint and make fixed-size of UIAlertController height and width.

Below is code for that:

UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"abcd" message:@"edfg" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *action = [UIAlertAction actionWithTitle:@"Done" style:UIAlertActionStyleDefault handler:nil];
[alert addAction:action];
NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:alert.view attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:self.view.frame.size.height * 0.8];
NSLayoutConstraint *width = [NSLayoutConstraint constraintWithItem:alert.view attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeWidth  multiplier:1 constant:self.view.frame.size.width * 0.5];
[alert.view addConstraint:width];
[alert.view addConstraint:height];
[alert.view setBackgroundColor:[UIColor blackColor]];
[self presentViewController:alert animated:YES completion:nil];

But width of UIAlertController is fixed. Using NSLayoutConstraint width of UIAlertController not changed.

Sakir Sherasiya
  • 1,562
  • 1
  • 17
  • 31
0

You are not supposed to do that but there is hack to scale the whole UIAlertView. UIAlertView is always displayed in new window, and trick is to scale the window.

[alert show]
alert.window.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.3, 1.3); // Must be called after [alert show]
Bilal
  • 18,478
  • 8
  • 57
  • 72