Как создать гибкую рамку для фото в iPhone?

#iphone #frame #photo #setneedsdisplay

#iPhone #рамка #фото #setneedsdisplay

Вопрос:

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

Это изображение, которое я использовал для рисования рамки, в коде для self.patternImage


Влияние моего кода


Влияние моего кода


//повернуть, чтобы получить зеркальное отображение исходного изображения, а isHorization означает направление поворота — (UIImage*)fetchMirrorImage:(UIImage*)Направление исходного изображения:(BOOL)isHorization{ CGSize ImageSize = originImage.size; UIGraphicsBeginImageContext(ImageSize); CGContextRef context = UIGraphicsGetCurrentContext(); CGAffineTransform преобразование = 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];
}
 

Ответ №1:

Да, я делаю это!!!конечный эффект Единственное, что мне нужно сделать, это установить фазу текущего контекста.

 CGContextSetPatternPhase(context, CGSizeMake(x, y));
 

x, y — это начальная точка, в которой я хочу нарисовать узор.

Я просто допустил ошибку, используя шаблон. Если я не задам фазу текущего контекста, он начнет заполнять шаблон с левой верхней части контекста (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));
 

Ответ №2:

Во-первых, я скажу так:
у меня сейчас нет реального ответа. Но у меня есть подсказка.. Я думаю, это будет полезно.

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

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

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

self.contentMode = UIViewContentModeRedraw;

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

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

Комментарии:

1. спасибо за ваш ответ. Я только что попробовал contentMode, но он все еще не работает.

2. Да, я поместил код выше. Я просто переопределяю drawRect, и изображения — это результат, который я получил.