How do I scale a UIButton's imageView?

前端 未结 19 2924
刺人心
刺人心 2020-12-02 05:16

I created a UIButton instance named \"button\" with an image using [UIButton setImage:forState:]. The button.frame is larger than the image\'s size.

Now

相关标签:
19条回答
  • 2020-12-02 05:45

    I can't get a solution use by _imageView, but I can use a CGContextRef to solve it. It use the UIGraphicsGetCurrentContext to get the currentContextRef and draw a image in currentContextRef, and then scale or rotate the image and create a new image. But it's not perfect.

    the code:

    -(UIImage*) scaleAndRotateImage:(UIImage*)photoimage width:(CGFloat)bounds_width height:(CGFloat)bounds_height;
    {
        CGImageRef imgRef = photoimage.CGImage;
    
        CGFloat width = CGImageGetWidth(imgRef);
        CGFloat height = CGImageGetHeight(imgRef);
    
        CGAffineTransform transform = CGAffineTransformIdentity;
        CGRect bounds = CGRectMake(0, 0, width, height);
    
        bounds.size.width = bounds_width;
        bounds.size.height = bounds_height;
    
        CGFloat scaleRatio = bounds.size.width / width;
        CGFloat scaleRatioheight = bounds.size.height / height;
        CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
        CGFloat boundHeight;
        UIImageOrientation orient = photoimage.imageOrientation;
        switch(orient)
        {
            case UIImageOrientationUp: //EXIF = 1
                transform = CGAffineTransformIdentity;
                break;
    
            case UIImageOrientationUpMirrored: //EXIF = 2
                transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
                transform = CGAffineTransformScale(transform, -1.0, 1.0);
                break;
    
            case UIImageOrientationDown: //EXIF = 3
                transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
                transform = CGAffineTransformRotate(transform, M_PI);
                break;
    
            case UIImageOrientationDownMirrored: //EXIF = 4
                transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
                transform = CGAffineTransformScale(transform, 1.0, -1.0);
                break;
    
            case UIImageOrientationLeftMirrored: //EXIF = 5
                boundHeight = bounds.size.height;
                bounds.size.height = bounds.size.width;
                bounds.size.width = boundHeight;
                transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
                transform = CGAffineTransformScale(transform, -1.0, 1.0);
                transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
                break;
    
            case UIImageOrientationLeft: //EXIF = 6
                boundHeight = bounds.size.height;
                bounds.size.height = bounds.size.width;
                bounds.size.width = boundHeight;
                transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
                transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
                break;
    
            case UIImageOrientationRightMirrored: //EXIF = 7
                boundHeight = bounds.size.height;
                bounds.size.height = bounds.size.width;
                bounds.size.width = boundHeight;
                transform = CGAffineTransformMakeScale(-1.0, 1.0);
                transform = CGAffineTransformRotate(transform, M_PI / 2.0);
                break;
    
            case UIImageOrientationRight: //EXIF = 8
                boundHeight = bounds.size.height;
                bounds.size.height = bounds.size.width;
                bounds.size.width = boundHeight;
                transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
                transform = CGAffineTransformRotate(transform, M_PI / 2.0);
                break;
    
            default:
                [NSException raise:NSInternalInconsistencyException format:@"Invalid?image?orientation"];
                break;
        }
    
        UIGraphicsBeginImageContext(bounds.size);
    
        CGContextRef context = UIGraphicsGetCurrentContext();
    
        if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft)
        {
            CGContextScaleCTM(context, -scaleRatio, scaleRatioheight);
            CGContextTranslateCTM(context, -height, 0);
        }
        else
        {
            CGContextScaleCTM(context, scaleRatio, -scaleRatioheight);
            CGContextTranslateCTM(context, 0, -height);
        }
    
        CGContextConcatCTM(context, transform);
    
        CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
        UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return imageCopy;
    }
    
    0 讨论(0)
  • 2020-12-02 05:46

    use

    button.contentMode = UIViewContentModeScaleToFill;
    

    not

    button.imageView.contentMode = UIViewContentModeScaleAspectFit;
    

    Update:

    As @Chris commented,

    To get this to work for setImage:forState:, you need to do the following to scale horizontally: myButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;

    0 讨论(0)
  • 2020-12-02 05:46
    button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
    button.contentVerticalAlignment =  UIControlContentVerticalAlignmentFill;
    
    0 讨论(0)
  • 2020-12-02 05:48

    You can modify imageView by using custom class of UIButton. Please see my answer. https://stackoverflow.com/a/59874762/5693826

    0 讨论(0)
  • I found this solution.

    1) Subclass the following methods of UIButton

    + (id)buttonWithType:(UIButtonType)buttonType {
        MyButton *toReturn = [super buttonWithType:buttonType];
        toReturn.imageView.contentMode = UIViewContentModeScaleAspectFit;
        return toReturn;
    }
    
    - (CGRect)imageRectForContentRect:(CGRect)contentRect {
        return contentRect;
    }
    

    And it works well.

    0 讨论(0)
  • 2020-12-02 05:54

    This will also work, as the backgroundImage automatically scales

    [button setBackgroundImage:image forState:UIControlStateNormal];

    0 讨论(0)
提交回复
热议问题