I have a
btn.imageView.contentMode = UIViewContentModeScaleAspectFill;
[btn setImage:image forState:UIControlStateNormal];
I have had this same issue. Try this:
[btn setContentHorizontalAlignment:UIControlContentHorizontalAlignmentFill]; [btn setContentVerticalAlignment:UIControlContentVerticalAlignmentFill];
From my understanding, when setting the image, the button's UIImageView's size/frame is set to that of the image, so when it is smaller, it isn't constrained by the UIButton's frame, and thus sits happily, unchanged, in the middle of the button.
To fix this, we need to force the UIImageView to take up the full size of the UIButton, and setting its alignment takes care of this.
See for more info (though it refers to this as an AutoLayout issue): http://stackoverflow.com/a/28205566/3692828