web-dev-qa-db-ja.com

プログレスバーをUIAlertControllerに追加する方法

Swift iOS 8 UIAlertControllerにプログレスバーを追加したいのですが、これは可能ですか?UIAlertControllerをサブクラス化してプログラムバーを追加してデリゲート関数を接続する方法はありますか?

ありがとう

13
Nik

プログレスバーが必要な場合は、次のようにサブビューとして追加するだけです。

Swift 5:の更新

//  Just create your alert as usual:
let alertView = UIAlertController(title: "Please wait", message: "Need to download some files.", preferredStyle: .alert)
alertView.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))

//  Show it to your users
present(alertView, animated: true, completion: {
    //  Add your progressbar after alert is shown (and measured)
    let margin:CGFloat = 8.0
    let rect = CGRect(x: margin, y: 72.0, width: alertView.view.frame.width - margin * 2.0 , height: 2.0)
    self.progressView = UIProgressView(frame: rect)
    self.progressView!.progress = 0.5
    self.progressView!.tintColor = self.view.tintColor
    alertView.view.addSubview(self.progressView!)
})

Swift 2.0:

//  Just create your alert as usual:
let alertView = UIAlertController(title: "Please wait", message: "Need to download some files.", preferredStyle: .Alert)
alertView.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))

//  Show it to your users
presentViewController(alertView, animated: true, completion: {
    //  Add your progressbar after alert is shown (and measured)
    let margin:CGFloat = 8.0
    let rect = CGRectMake(margin, 72.0, alertView.view.frame.width - margin * 2.0 , 2.0)
    let progressView = UIProgressView(frame: rect)
    progressView.progress = 0.5
    progressView.tintColor = UIColor.blueColor()
    alertView.view.addSubview(progressView)
})

より大きなコンテンツのUIAlertControllerのサイズを変更することは非常に困難ですが、プログレスバーの場合はこれでうまくいくはずです。

21
coyer

このソリューションでObjective Cを使用したことをお詫び申し上げますが、Swiftをまだ使用していない他のユーザーを助けることができると思います。また、これを簡単にSwift。それは私が強調したかった方法論です。

Appleがこの解決策を拒否するかどうかもわかりませんが、とにかくここに行きます。

Appleは、iOS7以降、UIAlertViewをサブクラス化すべきではないと述べています。このクラスのビュー階層はプライベートであり、変更してはなりません:

https://developer.Apple.com/reference/uikit/uialertview?language=objc

言い換えると、UIViewをUIAlertViewに追加してもまったく効果がありません。

ただし、UIAlertViewの上にUIProgressViewを追加し、前者をアプリウィンドウに追加するというソリューションがあります。 UIViewsuperview.centerプロパティといくつかの微調整を使用すると、望ましい効果を得ることができます。

-(void)addProgressBar{
    float width = 232;
    float height = 5;
    self.progbar = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
    self.progbar.backgroundColor = [UIColor colorWithWhite:0.75f alpha:1.0f];
    [self.progbar setFrame:CGRectMake(0,0,width,height)];
    [self.progbar setTrackTintColor:[UIColor colorWithWhite:0.75f alpha:1.0f]];
    [self.progbar setProgressTintColor:[UIColor colorWithRed:21.0f/255.0f green:126.0f/255.0f blue:251.0f/255.0f alpha:1.0f]];
    self.progbar.alpha = 0.0;
    [[UIApplication sharedApplication].keyWindow addSubview:self.progbar];
    self.progbar.center = self.progbar.superview.center;
    [self.progbar setFrame:CGRectMake(self.progbar.frame.Origin.x,self.progbar.frame.Origin.y+10,self.progbar.frame.size.width,self.progbar.frame.size.height)];
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:2.0];
    [self.progbar setAlpha:1.0];
    [UIView commitAnimations];
}

最初にUIAlertViewが完全に表示されるように、フェードインを追加します。次に、他のデリゲート関数をいくつか追加して、適切なタイミングでUIProgressViewを閉じます。

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
    if(self.alert.cancelButtonIndex == buttonIndex){
        [self.progbar removeFromSuperview];
    }
}

- (void)alertViewCancel:(UIAlertView *)alertView{
    [self.progbar removeFromSuperview];
}

enter image description here

3
func downloadAlert() {
        let alertController = UIAlertController(title: "Title", message: "Loading...", preferredStyle: .Alert)

        let progressDownload : UIProgressView = UIProgressView(progressViewStyle: .Default)

        progressDownload.setProgress(5.0/10.0, animated: true)
        progressDownload.frame = CGRect(x: 10, y: 70, width: 250, height: 0)

    alertController.view.addSubview(progressDownload)
    presentViewController(alertController, animated: true, completion: nil)
}
2
Chea Sambath

自動レイアウトのソリューション:

    UIAlertController *alertCtr = [UIAlertController alertControllerWithTitle:@"Test" message:@"50%" preferredStyle:UIAlertControllerStyleAlert];
    [alertCtr addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        // Do things
    }]];

    UIView *alertView = alertCtr.view;

    UIProgressView *progressView = [[UIProgressView alloc] initWithFrame:CGRectZero];
    progressView.progress = 0.5;
    progressView.translatesAutoresizingMaskIntoConstraints = false;
    [alertView addSubview:progressView];


    NSLayoutConstraint *bottomConstraint = [progressView.bottomAnchor constraintEqualToAnchor:alertView.bottomAnchor];
    [bottomConstraint setActive:YES];
    bottomConstraint.constant = -45; // How to constraint to Cancel button?

    [[progressView.leftAnchor constraintEqualToAnchor:alertView.leftAnchor] setActive:YES];
    [[progressView.rightAnchor constraintEqualToAnchor:alertView.rightAnchor] setActive:YES];

    [self presentViewController:alertCtr animated:true completion:nil];

enter image description here

1
Dong Mai