“Please wait” dialog in iOS8

后端 未结 8 1983
离开以前
离开以前 2020-12-13 08:14

I used to have a \"Please wait\" dialog in my app for long time. It was quite simple thing using UIActivityIndicatorView and adding it to

8条回答
  •  -上瘾入骨i
    2020-12-13 08:32

    If you only want to display title and activity indicator and you feel adventurous, you can hack AlertController's view hierarchy. The code below works on 8.2. However this normally should not be in production.

    As it's been noted in comments below, using this code in your app may get you rejected, here is the excerpt from documentation:

    The UIAlertController 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.

    @implementation AlertControllerWithActivityIndicator
    
    - (void)viewDidLayoutSubviews {
        [super viewDidLayoutSubviews];
    
        UIView *scrollView = [self findViewByClassPrefix:@"_UIAlertControllerShadowedScrollView" inView:self.view];
        UIView *containerView = [scrollView.subviews firstObject];
        UILabel *titleLabel = containerView.subviews.firstObject;
    
        if(!titleLabel) {
            return;
        }
    
        if(!self.indicatorView) {
            self.indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
            self.indicatorView.translatesAutoresizingMaskIntoConstraints = NO;
            [containerView addSubview:self.indicatorView];
            NSDictionary *views = @{ @"text": titleLabel, @"indicator": self.indicatorView };
    
            NSArray *constraints = [scrollView constraintsAffectingLayoutForAxis:UILayoutConstraintAxisVertical];
            for(NSLayoutConstraint *constraint in constraints) {
                if(constraint.firstItem == containerView && constraint.secondItem == titleLabel && constraint.firstAttribute == NSLayoutAttributeBottom) {
                    constraint.active = NO;
                }
            }
    
            [containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[text]-[indicator]-24-|" options:0 metrics:nil views:views]];
            [containerView addConstraint:[NSLayoutConstraint constraintWithItem:self.indicatorView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:containerView attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0]];
    
            [self.indicatorView startAnimating];
        }
    }
    
    - (UIView *)findViewByClassPrefix:(NSString *)prefix inView:(UIView *)view {
        for(UIView *subview in view.subviews) {
            if([NSStringFromClass(subview.class) hasPrefix:prefix]) {
                return subview;
            }
    
            UIView *child = [self findViewByClassPrefix:prefix inView:subview];
            if(child) {
                return child;
            }
        }
        return nil;
    }
    
    @end
    

    Produces something like that:

    UIAlertController with activity indicator

提交回复
热议问题