How do I prevent a button's background image from stretching?

后端 未结 10 1819
执笔经年
执笔经年 2021-01-30 16:22

I\'m allocating a UIButtonTypeCustom UIButton to a UIView with a background image that is smaller than the button\'s frame. Reason why the image is smaller is because I\'m tryin

相关标签:
10条回答
  • 2021-01-30 16:39

    The cleanest and easiest way it probably to use the title insets of the button.

    You set your image as the button image, and then you change the left title inset to match minus the width of your image:

    myButton.titleEdgeInsets = UIEdgeInsetsMake(0, -myImage.width, 0, 0)
    

    This will move the text back where it was before the image was added to its left. You can also use this value to add some padding to you button.

    0 讨论(0)
  • 2021-01-30 16:39

    I guess the easiest solution is to use UIImage's resizableImageWithCapInsets method. Use UIEdgeInsetsMake to configure the free spaces.

    0 讨论(0)
  • might help someone

    button.subviews.first?.contentMode = .scaleAspectFit
    
    0 讨论(0)
  • 2021-01-30 16:48

    It is simple as:

        ImageBn.imageView?.contentMode = .scaleAspectFit
        ImageBn.setImage(chosenImage, for: .normal)
    
    0 讨论(0)
  • 2021-01-30 16:49

    Answerbot answers the question with what is proper and correct to do. Don't fight the OS and use things as intended is always good advice. However, sometimes you need to break the rules.

    I was able to mask the enlarged background image (not prevent it) by overlaying it with a black CAlayer then overlaying again with a properly resized image CAlayer. This was all done by creating a subclass of UIButton and overwriting the setHighlighted method.

    NEED CODE?

    - (void)setHighlighted:(BOOL)highlighted
    {
    super.highlighted = highlighted;
    
    //
    //Whenever an image needs to be highlighted, create a dimmed new image that is correctly       sized. Below it is a englarged stretched image.
    //
    if (highlighted != _previousHighlightedSate)
    {
        _previousHighlightedSate = highlighted;
    
        if (highlighted)
        {
            //Create a black layer so image can dim
            _blackLayer = [CALayer layer];
            _blackLayer.bounds = self.bounds;
            CGRect rect = _blackLayer.bounds;
            rect.size.width = rect.size.width*2;
            rect.size.height = rect.size.height*2;
            _blackLayer.bounds = rect;
            _blackLayer.backgroundColor = [[UIColor blackColor] CGColor];
    
            //create image layer
            _nonStretchImageLayer = [CALayer layer];
            _nonStretchImageLayer.backgroundColor = [UIColor blackColor].CGColor;
            _nonStretchImageLayer.bounds = CGRectMake(0  , 0, self.bounds.size.width, self.bounds.size.height);
            _nonStretchImageLayer.frame = CGRectMake(0  , 0, self.bounds.size.width, self.bounds.size.height);
            _nonStretchImageLayer.contentsGravity = kCAGravityResizeAspect;//default is to resize
            _nonStretchImageLayer.contents = (id)self.imageView.image.CGImage;
            _nonStretchImageLayer.opacity = 0.5;
    
            //add layers to image view
            [self.imageView.layer addSublayer:_blackLayer];
            [self.imageView.layer addSublayer:_nonStretchImageLayer];
        }
        else
        {
            //remove from image view
            [_blackLayer removeFromSuperlayer];
            [_nonStretchImageLayer removeFromSuperlayer];
    
            //nil them out.
            _blackLayer = nil;
            _nonStretchImageLayer = nil;
        }
    }  
    

    Inspiration for this work around came from here

    0 讨论(0)
  • 2021-01-30 16:51

    You don't have access to the background imageView, but there is fully working workaround:

    EDIT: There is an even better workaround then what I posted originally. You can create a UIImage from any color, and call -setBackgroundImage:forState.

    See bradley's answer, here: https://stackoverflow.com/a/20303841/1147286


    Original answer:

    Instead of calling -setBackgroundImage:forState:, create a new UIImageView and add it as a subview of the button.

    UIImageView *bgImageView = [[UIImageView alloc] initWithImage:img];
    bgImageView.contentMode = UIViewContentModeScaleAspectFit;
    [bgImageView setFrame:CGRectMake(0, 0, videoButton.frame.size.width, videoButton.frame.size.height)];
    bgImageView.tag = 99;
    [yourButton addSubview:bgImageView];
    [yourButton bringSubviewToFront:yourButton.imageView];
    
    1. Create the imageview
    2. Set the content mode and frame
    3. I also set a recognizable tag, so that when the screen rotates I can easily find my custom imageView in the button's subviews and reset its frame
    4. Add it as a subview to the button
    5. Bring the frontal imageView of the button to the front so our custom imageView doesn't overlap it

    When the button needs to rotate just find the imageView by its tag and reset its frame:

    UIImageView *bgImageView = (UIImageView *)[button viewWithTag:99];
    [bgImageView setFrame:CGRectMake(0, 0, newWidth, newHeight)];
    
    0 讨论(0)
提交回复
热议问题