Customize UIAlertButton through layoutSubviews => UIAlertButton class not found

倖福魔咒の 提交于 2020-01-15 11:41:34

问题


i'm trying to implement custom alert view using this tutorial. All in this tut work well, but it doesn't speak about customizing UIAlertButton. Then, i'm trying to customize it through layoutSubviews method:

- (void)layoutSubviews
{
    for (UIView *subview in self.subviews){ //Fast Enumeration
        if ([subview isMemberOfClass:[UIImageView class]]) {
            subview.hidden = YES; //Hide UIImageView Containing Blue Background
        }
        if ([subview isMemberOfClass:[UILabel class]]) { //Point to UILabels To Change Text
            UILabel *label = (UILabel*)subview; //Cast From UIView to UILabel
            label.textColor = [UIColor colorWithRed:210.0f/255.0f green:210.0f/255.0f blue:210.0f/255.0f alpha:1.0f];
            label.shadowColor = [UIColor blackColor];
            label.shadowOffset = CGSizeMake(0.0f, 1.0f);
        }
        if ([subview isMemberOfClass:[UIAlertButton class]]) {
            // do blablabla
        }
    }
}

especially what i added is :

if ([subview isMemberOfClass:[UIAlertButton class]]) {
     // do blablabla
}

But it can't found UIAlertButton class, why? Thanks

EDIT : Here is my final working code, thanks to nsguliver.

CustomAlertView.h

#import <UIKit/UIKit.h>

@interface CustomAlertView: UIAlertView {
    NSMutableArray *fakeButtonIndexList;
    NSMutableArray *buttonList;
}

-(void)addCustomButton:(NSString*)title;

@end

CustomAlertView.m

#import "CustomAlertView.h"

@implementation CustomAlertView


-(id) initWithTitle:(NSString *)title message:(NSString *)message delegate:(id)delegate cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ... {
    self = [super initWithTitle:title message:message delegate:delegate cancelButtonTitle:cancelButtonTitle otherButtonTitles:otherButtonTitles, nil];

    if (self) {
        buttonList = [NSMutableArray array];
        fakeButtonIndexList = [NSMutableArray array];
    }

    return self;
}


-(void)layoutSubviews {
    for (UIView *subview in self.subviews){ //Fast Enumeration

        // Image de fond
        if ([subview isMemberOfClass:[UIImageView class]]) {
            subview.hidden = YES; //Hide UIImageView Containing Blue Background
        }
        // Label
        if ([subview isMemberOfClass:[UILabel class]]) { //Point to UILabels To Change Text
            UILabel *label = (UILabel*)subview; //Cast From UIView to UILabel
            label.shadowColor = [UIColor blackColor];
            label.shadowOffset = CGSizeMake(0.0f, 1.0f);
        }
    }
}

-(void)drawRect:(CGRect)rect {
    //////////////GET REFERENCE TO CURRENT GRAPHICS CONTEXT
    CGContextRef context = UIGraphicsGetCurrentContext();

    //////////////CREATE BASE SHAPE WITH ROUNDED CORNERS FROM BOUNDS
    CGRect activeBounds = self.bounds;
    CGFloat cornerRadius = 10.0f;
    CGFloat inset = 6.5f;
    CGFloat originX = activeBounds.origin.x + inset;
    CGFloat originY = activeBounds.origin.y + inset;
    CGFloat width = activeBounds.size.width - (inset*2.0f);
    CGFloat height = activeBounds.size.height - (inset*2.0f);

    CGRect bPathFrame = CGRectMake(originX, originY, width, height);
    CGPathRef path = [UIBezierPath bezierPathWithRoundedRect:bPathFrame cornerRadius:cornerRadius].CGPath;

    //////////////CREATE BASE SHAPE WITH FILL AND SHADOW
    CGContextAddPath(context, path);
    CGContextSetFillColorWithColor(context, [UIColor colorWithRed:40.0f/255.0f green:40.0f/255.0f blue:40.0f/255.0f alpha:1.0f].CGColor);
    CGContextDrawPath(context, kCGPathFill);

    //////////////CLIP STATE
    CGContextSaveGState(context); //Save Context State Before Clipping To "path"
    CGContextAddPath(context, path);
    CGContextClip(context);

}

-(void)show {
    [super show];

    // On redéfinit les frames des boutons
    NSInteger indexCustomButton = 0;
    for (NSString *indexStr in fakeButtonIndexList) {

        UIButton *customButton = (UIButton*)[buttonList objectAtIndex:indexCustomButton];
        UIButton *fakeButton = (UIButton*)[self.subviews objectAtIndex:[indexStr integerValue]];
        [customButton setFrame:fakeButton.frame];

        indexCustomButton++;
    }
}

-(void)addCustomButton:(NSString *)title {
    [self addButtonWithTitle:title];
    UIButton *fakeButton = [self.subviews lastObject];
    [fakeButton setHidden:YES];
    [fakeButtonIndexList addObject:[NSString stringWithFormat:@"%d",[self.subviews count]]];

    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button setFrame:fakeButton.frame];
    [button setTitle:title forState:nil];
    [button setBackgroundColor:[Templates getColor:@"color"]];
    [button.layer setCornerRadius:5.0f];

    [buttonList addObject:button];
    [self addSubview:button];
}

@end

回答1:


One way you could customize the buttons over the UIAlertView by first keeping the both button titles to nil and then add custom button as subview to your CustomAlertView see the below code tested myself.

CustomAlertVIew *alert =[[CustomAlertVIew alloc]initWithTitle:@"title" message:@"message" delegate:nil cancelButtonTitle:nil otherButtonTitles:nil, nil];

// add the custom button
UIImage *buttonImage = [UIImage imageNamed:@"image.png"];

//create the button and assign the image
UIButton *alertButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.alertButton setFrame:CGRectMake(x,y,buttonImage.size.width,buttonImage.size.height)];

[alertButton setBackgroundImage:buttonImage forState:UIControlStateNormal];
alertButton.titleLabel.font = [UIFont boldSystemFontOfSize:12];
[alertButton setTitle:@"Done" forState:UIControlStateNormal];
[alertButton addTarget:self action:@selector(backMethod)  forControlEvents:UIControlEventTouchUpInside];

[alert addSubview:alertButton];
[alert show];



回答2:


Your question is already well answered, but my solution is maybe shorter and cleaner. First, I created a variable which tracks the button indexes in the subviews-array. I assume that the AlertViewButtons are the last subviews:

int buttonIndexInSubviews = (self.subviews.count - self.numberOfButtons);

Then I iterated through the subviews as shown, whereas the if-statement is formed different. The trick is to cast the AlertViewButton to the superclass.

if (subview == [self.subviews objectAtIndex:buttonIndexInSubviews]) {
        UIButton *button = (UIButton*)subview;

        //Here you can change the button appearance via the variable
        //E.g. button.titleLabel.shadowOffset = CGSizeMake(0.0f, 0.0f);

        buttonIndexInSubviews++;
    }

By the way, this workaround was approved by Apple.




回答3:


Or you can test for the UIAlertButton class like this:

if ([subview isMemberOfClass:NSClassFromString(@"UIAlertButton")]) {
    // do your customizing here...
}


来源:https://stackoverflow.com/questions/15228088/customize-uialertbutton-through-layoutsubviews-uialertbutton-class-not-found

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!