简体   繁体   中英

Touch area after CALayer animation on UIButton subclass

I have a UIButton I'm subclassing. Trying to build a class that replicates the AppStore "buy now" buttons. I create the style of the button with 3 CALayers.

When resizing the button I use:

[CATransaction begin];
[CATransaction setAnimationDuration:0.25];

CGSize size = [self.titleLabel.text sizeWithFont:[UIFont boldSystemFontOfSize:18]];
size.width = size.width + kPadding;

for(CALayer *la in self.layer.sublayers){       
    CGRect boundsRect = la.frame;
    float inset = boundsRect.size.width - size.width;       
    boundsRect.origin.x = boundsRect.origin.x+inset;
    boundsRect.size.width = size.width;
    la.frame = boundsRect;  
    [la layoutIfNeeded];
}

[CATransaction commit];

This behave perfectly and looks great, but the touch area of the button stays the same as the original size of the button. Any attempt to modify the frame\\bounds of the button or the main CALayer results in weird behavior, and the touch area still seems incorrect.

I'm also animating a color change with a CABasicAnimation. Is using CALayer the wrong choice? What am I missing here?

Fairly simple solution. Since you are offsetting the layers in order to make the animation go in a specific direction, the button's frame doesn't match up with the layers anymore.

To solve the problem, after the CALayer animation, I resize and offset the UIButton frame and then offset the CALayer frames back to where they belong within the UIButton frame. This was achieved by using setCompletionBlock on the CATransaction .

[CATransaction setCompletionBlock:^{
    //Readjust button frame for touch area

    CGRect frameRect = self.frame;
    frameRect.origin.x = frameRect.origin.x - offset;
    frameRect.size.width = frameRect.size.width + offset;
    self.frame = frameRect;

    [CATransaction setDisableActions:YES];
    for(CALayer *layer in self.layer.sublayers){
        CGRect rect = layer.frame;
        rect.origin.x = rect.origin.x+offset;
        layer.frame = rect;
    }
    [CATransaction commit];

}];

Note that CALayers have implicit animations, so you have to disable CALayer actions in a nested CATransaction.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM