Search code examples
iosuibuttonuiimageblurryscalable

Creating a scalable Image button in iOS. Without a blurry image.


What am I trying to do:

I want to make a button that scales up or down depending on it's current state which is determined by it either being big or small.

When button is big and I press it, it becomes small. When the button is small and I press it, it becomes big.

The button must contain a image of a QR code and subsequently be scannable by a QR reader.

My problem:

Is that the image is blurry when big. This isn't the case if I put the image inside a ImageView instead of a button.

The effect is best described here: https://i.sstatic.net/4aN5I.jpg

The Code:

Button/Image Declaration

UIImage* image = [QREncoder encode:user];
// declare image - QREncoder can be found on github
UIImage *strechedBackground = [image stretchableImageWithLeftCapWidth:220 topCapHeight:220];
UIImageView* imageView = [[UIImageView alloc] initWithImage:image];
CGFloat qrSize = self.view.bounds.size.width - kPadding * 2;
CGRect largeFrame = CGRectMake(kPadding, (self.view.bounds.size.height - qrSize) / 2,
                          qrSize, qrSize);
imageView.frame = largeFrame;
[imageView layer].magnificationFilter = kCAFilterNearest;

//[self.view addSubview:imageView];

// add qr button to the view
self.qrButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.qrButton.frame = largeFrame;
[self.qrButton setBackgroundImage:image forState:UIControlStateNormal];
[self.qrButton addTarget:self
           action:@selector(aMethod)
 forControlEvents:UIControlEventTouchDown];
self.qrButton.contentMode = UIViewContentModeCenter;    


[self.view addSubview:self.qrButton];

Button/Image Scale Function

- (void)aMethod{
// some variables concerned with button sizes and dimensions
CGFloat qrSize = self.view.bounds.size.width - kPadding * 2;
CGRect largeFrame = CGRectMake(kPadding, (self.view.bounds.size.height - qrSize) / 2,
                               qrSize, qrSize);

CGFloat smallButtonWidth = 33.0;
CGFloat smallButtonHeight = 33.0;

CGFloat largeButtonWidth = 264.0;
CGFloat largeButtonHeight = 264.0;

CGRect smallFrame = CGRectMake(self.view.frame.size.width - smallButtonWidth - kPadding/2, self.view.frame.size.height - smallButtonHeight - kPadding/2, smallButtonWidth, smallButtonHeight);
// a boolean ivar indicates the size of the button
if (!self.qrButtonIsBig){

    NSLog(@"Button was Big");


    // animate the view...
    [UIView animateWithDuration:0.5
                          delay:0.0
                        options:UIViewAnimationOptionCurveEaseOut
                     animations:^{
                         //self.qrButton.transform = CGAffineTransformMakeScale(3, 3);
                         // resting positon after animation
                         self.qrButton.frame = smallFrame;
                     }
                     completion:nil];

    NSLog(@"Button is now Small");


}else{

    NSLog(@"Button was Small");

    // animate the view...
    [UIView animateWithDuration:0.5
                          delay:0.0
                        options:UIViewAnimationOptionCurveEaseOut
                     animations:^{
                         self.qrButton.transform = CGAffineTransformIdentity;
                         // resting positon after animation, bottom left with 20 px margin
                         self.qrButton.frame = largeFrame;
                     }
                     completion:nil];

    NSLog(@"Button is now Big");

}
self.qrButtonIsBig = !self.qrButtonIsBig;

}


Solution

  • Since the ImageView was sharp and ButtonImage blurry. It makes sense to scale the imageview with an invisible button on top as a practical work around rather than trying to get the image to be sharp in the button.