Subclassed UIAlertView not drawn correctly in iOS

2019-02-15 12:48发布

I've subclassed an UIAlertView as follow:

@interface NarrationAlertView : UIAlertView {
    UIImage * backgroundImage; //The image I want as custom background
    UILabel * textualNarrationView; //The test I wanna be displayed on the view        
}

And implemented it this way :

- (id)initNarrationViewWithImage:(UIImage *)image{

    if (self = [super init]){
        UILabel * alertTextLabel = [[UILabel alloc] initWithFrame:CGRectZero];
        self.textualNarrationView = alertTextLabel;
        [alertTextLabel release];
        [self addSubview:alertTextLabel];
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    /* Here I draw the image as background */
    CGSize imageSize = self.backgroundImage.size;
    [self.backgroundImage drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];
}

- (void)layoutSubviews {
    /* To fit the text */
    [textualNarrationView sizeToFit];

    CGRect textRect = textualNarrationView.frame;
    textRect.origin.x = (CGRectGetWidth(self.bounds) - CGRectGetWidth(textRect)) / 2;
    textRect.origin.y = (CGRectGetHeight(self.bounds) - CGRectGetHeight(textRect)) / 2;
    textRect.origin.y -= 70;
    textualNarrationView.frame = textRect;
}

- (void)show{
    /* Showing the view */
    [super show];
    CGSize imageSize = self.backgroundImage.size;
    self.bounds = CGRectMake(0, 0, imageSize.width, imageSize.height);
}

On the previous versions of iOS (I'm always testing on the simulator) the subclass run fine and when shown it displayed the custom background image drawn correctly and just text upon it, whereas in the 4.2 version it draws the UIAlertView classic background (the blue rounded corners rectangle) on top of my image.

What am I doing wrong? Any suggestion about UIAlertView programming and UIView too will be appreciated.

UPDATE Has anyone got some UIAlertView replacement class to share?

3条回答
Emotional °昔
2楼-- · 2019-02-15 13:19

Prior to iOS 4.2 UIAlertView's standard dark blue rounded rectangle was drawn in drawRect. the rounded rectangle could be removed by subclassing UIAlertView and implementing drawRect without calling super. however in 4.2 the rounded rectangle is a UIImageView subview. the quick, easy (not best) solution: If you are not adding any UIImageView instances to your UIAlertView subclass you can simply remove the default UIImageView that is loaded by observing subview additions:

- (void)didAddSubview:(UIView *)subview {
  if ([subview isMemberOfClass:[UIImageView class]]) {
    [subview removeFromSuperview];
  }
}
查看更多
虎瘦雄心在
3楼-- · 2019-02-15 13:22

I got burned by this too. I ended up writing a replacement class, which I'm sharing on github:

https://github.com/TomSwift/TSAlertView

查看更多
Deceive 欺骗
4楼-- · 2019-02-15 13:34

We had a similar problem with UIAlertView in iOS 4.2; we were customizing the layout, added text boxes and rearranging the buttons.

This won't be a popular answer, but due to the changes to UIAlertView, we had to abandon using it entirely for this purpose. We always knew it was a fragile implementation since customizing/subclassing UIAlertView isn't officially supported and makes assumptions about the internal structure of the view hierarchy, but the release of 4.2 really kicked us into gear.

In the end, we implemented our own UI element to replace the customized UIAlertView.

查看更多
登录 后发表回答