Проблема поворота изображения UIButton - PullRequest
11 голосов
/ 29 августа 2011

У меня есть [UIButton buttonWithType:UIButtonTypeCustom] с изображением (или фоновым изображением - та же проблема), созданным [UIImage imageWithContentsOfFile:], указывающим на файл JPG, снятый камерой и сохраненный в папке документов приложением.

Если я определяю изображение только для UIControlStateNormal, то при касании кнопки изображение становится темнее, чем ожидалось, но оно также поворачивается на 90 или 180 градусов. Когда я убираю палец, он возвращается в нормальное состояние.

Этого не происходит, если я использую одно и то же изображение для UIControlStateHighlighted, но тогда я теряю сенсорную индикацию (более темное изображение).

Это происходит только с изображением, считанным из файла. Это не происходит с [UIImage ImageNamed:].

Я попытался сохранить файл в формате PNG, а не в формате JPG. В этом случае изображение отображается в неправильной ориентации и больше не поворачивается при прикосновении. В любом случае, это не очень хорошее решение, потому что PNG слишком большой и медленный для обработки.

Это ошибка или я что-то не так делаю?

Ответы [ 2 ]

4 голосов
/ 18 июля 2012

Я не смог найти правильное решение для этого, и мне нужно было быстро обойти. Ниже приведена функция, которая с учетом UIImage возвращает новое изображение, затемненное темной альфа-заливкой. Команды заливки контекста могут быть заменены другими процедурами рисования или заливки для обеспечения различных типов затемнения.

Это неоптимизировано и сделано с минимальным знанием графического API.

Вы можете использовать эту функцию для установки изображения состояния UIControlStateHighlighted так, чтобы оно по крайней мере было темнее.

+ (UIImage *)darkenedImageWithImage:(UIImage *)sourceImage
{
    UIImage * darkenedImage = nil;

    if (sourceImage)
    {
        // drawing prep
        CGImageRef source = sourceImage.CGImage;
        CGRect drawRect = CGRectMake(0.f,
                                     0.f,
                                     sourceImage.size.width, 
                                     sourceImage.size.height);
        CGContextRef context = CGBitmapContextCreate(NULL, 
                                                     drawRect.size.width, 
                                                     drawRect.size.height,
                                                     CGImageGetBitsPerComponent(source),
                                                     CGImageGetBytesPerRow(source),
                                                     CGImageGetColorSpace(source),
                                                     CGImageGetBitmapInfo(source)
                                                     );

        // draw given image and then darken fill it
        CGContextDrawImage(context, drawRect, source);
        CGContextSetBlendMode(context, kCGBlendModeOverlay);
        CGContextSetRGBFillColor(context, 0.f, 0.f, 0.f, 0.5f);
        CGContextFillRect(context, drawRect);

        // get context result
        CGImageRef darkened = CGBitmapContextCreateImage(context);
        CGContextRelease(context);

        // convert to UIImage and preserve original orientation
        darkenedImage = [UIImage imageWithCGImage:darkened
                                                      scale:1.f
                                                orientation:sourceImage.imageOrientation];
        CGImageRelease(darkened);
    }

    return darkenedImage;
}
2 голосов
/ 14 января 2016

Чтобы исправить это, вам нужна дополнительная функция нормализации, например:

public extension UIImage {

    func normalizedImage() -> UIImage! {

        if self.imageOrientation == .Up {
            return self
        }

        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
        self.drawInRect(CGRectMake(0, 0, self.size.width, self.size.height))
        let normalized = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return normalized
    }
}

тогда вы можете использовать это так:

self.photoButton.sd_setImageWithURL(avatarURL, 
forState: .Normal, 
placeholderImage: UIImage(named: "user_avatar_placeholder")) {

    [weak self] (image, error, cacheType, url) in

    guard let strongSelf = self else {

        return
    }

    strongSelf.photoButton.setImage(image.normalizedImage(), forState: .Normal
}
...