Как создать гибкую рамку для фото в iPhone? - PullRequest
4 голосов
/ 26 октября 2011

Я пытаюсь создать гибкую рамку для моего приложения для iPhone с небольшими картинками. CustomView наследует UIView и переопределяет его setFrame: метод. В setFrame: я пытаюсь вызвать [self setNeedsDisplay]; Каждый раз, когда я масштабирую фотографию, этот кадр действительно отображается и изменяется, но что-то работает не очень хорошо. Код и эффект ниже:

This is the image that I used to draw the frame, in code for self.patternImage


Effect of my code


Effect of my code


// повернуть, чтобы получить зеркальное отображение originImage, а isHorization означает направление вращения - (UIImage *) fetchMirrorImage: (UIImage *) originImage Направление: (BOOL) isHorization { CGSize imageSize = originImage.size; UIGraphicsBeginImageContext (IMAGESIZE); CGContextRef context = UIGraphicsGetCurrentContext (); CGAffineTransform transform = CGAffineTransformIdentity;

    if (isHorization) {
        transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
        transform = CGAffineTransformScale(transform, -1.0, 1.0);
    }else {
        transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
        transform = CGAffineTransformScale(transform, 1.0, -1.0);
    }

    CGContextScaleCTM(context, 1, -1);
    CGContextTranslateCTM(context, 0, -imageSize.height);
    CGContextConcatCTM(context, transform);

    CGContextDrawImage(context, CGRectMake(0, 0, imageSize.width, imageSize.height), originImage.CGImage);
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

- (UIImage*)fetchPattern:(PatternType)pattern{
    if (!self.patternImage) {
        return nil; 
    }

    UIImage *tmpPattern = nil;
    CGRect fetchRect = CGRectZero;
    CGSize imageSize = self.patternImage.size;
    switch (pattern) {
        case kTopPattern:
            fetchRect = CGRectMake(self.insetSize.width, 0, imageSize.width-self.insetSize.width, self.insetSize.height);
            tmpPattern = [UIImage imageWithCGImage:CGImageCreateWithImageInRect(self.patternImage.CGImage, fetchRect)];
            break;
        case kTopRightPattern:
            fetchRect = CGRectMake(0, 0, self.insetSize.width, self.insetSize.height);
            tmpPattern = [UIImage imageWithCGImage:CGImageCreateWithImageInRect(self.patternImage.CGImage, fetchRect)];

            break;
        case kRightPattern:

            break;
        case kRightBottomPattern:

            break;
        case kBottomPattern:

            break;
        case kLeftBottomPattern:

            break;
        case kLeftPattern:
            fetchRect = CGRectMake(0, self.insetSize.height, self.insetSize.width, imageSize.height-self.insetSize.height);
            tmpPattern = [UIImage imageWithCGImage:CGImageCreateWithImageInRect(self.patternImage.CGImage, fetchRect)];
            break;
        case kLeftTopPattern:
            fetchRect = CGRectMake(0, 0, self.insetSize.width, self.insetSize.height);
            tmpPattern = [UIImage imageWithCGImage:CGImageCreateWithImageInRect(self.patternImage.CGImage, fetchRect)];
            break;
        default:
            break;
    }

    return tmpPattern;
}

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    if (self.patternImage == nil) {
        return;
    }

    // Drawing code.
    UIImage *conLeftImage = [self fetchPattern:kLeftTopPattern];
    [conLeftImage drawAtPoint:CGPointMake(0, 0)];

    UIImage *topImage = [self fetchPattern:kTopPattern];
    [topImage drawAsPatternInRect:CGRectMake(self.insetSize.width, 0, self.frame.size.width-self.insetSize.width*2, self.insetSize.height)];

    UIImage *leftImage = [self fetchPattern:kLeftPattern];
    [leftImage drawAsPatternInRect:CGRectMake(0, self.insetSize.height, self.insetSize.width, self.frame.size.height-self.insetSize.height*2)];

    UIImage *conRightImage = [self fetchMirrorImage:conLeftImage direction:YES];
    [conRightImage drawAtPoint:CGPointMake(self.frame.size.width-self.insetSize.width, 0)];

    UIImage *rightImage = [self fetchMirrorImage:leftImage direction:YES];
    CGRect rectRight = CGRectMake(self.frame.size.width-self.insetSize.width, self.insetSize.height, self.insetSize.width, self.frame.size.height-self.insetSize.height*2);
    [rightImage drawAsPatternInRect:rectRight];

    UIImage *botRightImage = [self fetchMirrorImage:conRightImage direction:NO];
    [botRightImage drawAtPoint:CGPointMake(self.frame.size.width-self.insetSize.width, self.frame.size.height-self.insetSize.height)];

    UIImage *bottomImage = [self fetchMirrorImage:topImage direction:NO];
    CGRect bottomRect = CGRectMake(self.insetSize.width, self.frame.size.height-self.insetSize.height, self.frame.size.width-self.insetSize.width*2, self.insetSize.height);
    [bottomImage drawAsPatternInRect:bottomRect];

    UIImage *botLeftImage = [self fetchMirrorImage:conLeftImage direction:NO];
    [botLeftImage drawAtPoint:CGPointMake(0, self.frame.size.height-self.insetSize.height)];

    [super drawRect:rect];
}

- (void)setFrame:(CGRect)frame{
    [super setFrame:frame];

    [self setNeedsDisplay];
}

Ответы [ 2 ]

4 голосов
/ 01 ноября 2011

Да, я делаю это!участвовать.

Я просто допустил ошибку при использовании шаблона.Если я не установил фазу текущего контекста, он начинает заполнять шаблон с левой верхней части контекста (0,0) каждый раз.

        CGColorRef color = NULL;
    UIImage *leftImage = [UIImage imageNamed:@"like_left.png"];
    color = [UIColor colorWithPatternImage:leftImage].CGColor;
    CGContextSetFillColorWithColor(context, color);
    CGContextFillRect(context, CGRectMake(0, 0, FRAME_WIDTH, rect.size.height));

    UIImage *topImage = [UIImage imageNamed:@"like_top.png"];
    color = [UIColor colorWithPatternImage:topImage].CGColor;
    CGContextSetFillColorWithColor(context, color);
    CGContextFillRect(context, CGRectMake(0, 0, rect.size.width,FRAME_WIDTH));

    UIImage *bottomImage = [UIImage imageNamed:@"like_bom.png"];
    CGContextSetPatternPhase(context, CGSizeMake(0, rect.size.height - FRAME_WIDTH));
    color = [UIColor colorWithPatternImage:bottomImage].CGColor;
    CGContextSetFillColorWithColor(context, color);
    CGContextFillRect(context, CGRectMake(0, rect.size.height - FRAME_WIDTH, rect.size.width, FRAME_WIDTH));

    UIImage *rightImage = [UIImage imageNamed:@"like_right.png"];
    CGContextSetPatternPhase(context, CGSizeMake(rect.size.width - FRAME_WIDTH, 0));
    color = [UIColor colorWithPatternImage:rightImage].CGColor;
    CGContextSetFillColorWithColor(context, color);
    CGContextFillRect(context, CGRectMake(rect.size.width - FRAME_WIDTH, 0, FRAME_WIDTH, rect.size.height));
0 голосов
/ 31 октября 2011

Сначала я скажу следующее:
У меня нет реального ответа прямо сейчас. Но у меня есть подсказка .. Думаю, это будет полезно.

Согласно учебному пособию , опубликованному Larmarche , вы можете легко настроить границы UIView, переопределив drawRect:. И, если вы прокрутите вниз до комментариев ниже (на веб-сайте учебника), вы увидите следующий комментарий:

Я обнаружил еще один глюк. Когда вы меняете границы RoundRect, оно не будет обновлено - поэтому углы иногда получают все винт (потому что они масштабируются автоматически).

Быстрое решение заключается в добавлении следующего к обоим методам инициализации:

self.contentMode = UIViewContentModeRedraw;

Установка для ContentMode значения Redraw избавит вас от необходимости звонить setNeedsDisplay. Вы можете легко изменить фрейм UIView, мгновенно или анимировать его, и UIView будет автоматически перерисован ..

Позже я попытаюсь лучше рассмотреть вашу проблему .. Я постараюсь на самом деле реализовать ее.

...