Swift 3 | Button Label under Image AND resize Image - ios

I'm displaying an image on top of a button, everything is OK on iPhone 7 e.g. :
I set button background color to blue to see the button frame.
Since I set an aspect ratio on my button's parent view, the button size change on small device, and on iPhone 4S, I have :
The button's images are not resized.
This is my code :
public extension UIButton {
func setButtonWithTextBehindImage () {
let spacing = CGFloat(0.0)
let imageSize = self.imageView?.frame.size
self.titleEdgeInsets = UIEdgeInsetsMake(0.0, -(imageSize?.width)!, -((imageSize?.height)! + spacing), 0.0)
let titleSize = self.titleLabel?.frame.size
self.imageEdgeInsets = UIEdgeInsetsMake(-((titleSize?.height)!), 0.0, 0.0, -(titleSize?.width)!)
}
}
I tried to set contentMode .scaleAspectFit on button and on button imageView but everytime my imageSize is (30, 30) (the size of my #1x image) and it doesn't resize to button size.
How can I do ? TY

Could you provide a bit more context on how you're using the code snippet you provided (maybe some code that we could try running)?
Documentation from https://developer.apple.com/reference/uikit/uibutton/1624010-titleedgeinsets mention insets being applied after the rectangle has been sized to fit. The time at which you're calling your function in the extension might have an effect on the expected resize not happening - as in, are you calling this when the view is loaded, after it appears, after subviews have been laid out.

Related

How can I make Custom UIButton with image and text?

As I did on Android under a layout arrange an ImageView and TextView and set ClickListener on Layout so same thing how can I do on swift (3.0) Xcode 8.
There is no markup like XML. It's difficult to do with drag and drop.
How can I make this view with responsive for all device screens.
My UI image is below:
Thanks in advance.
after using CollectionView it shows like this
You can use this code to set image and title to button
let imageSize: CGSize = button.imageView!.image!.size
button.titleEdgeInsets = UIEdgeInsetsMake(26 , -imageSize.width, 0.0, 0.0);
let labelString = NSString(string: button.titleLabel!.text!)
let titleSize = labelString.sizeWithAttributes([NSFontAttributeName: button.titleLabel!.font])
button.imageEdgeInsets = UIEdgeInsetsMake(-15, 0.0, 0.0, -titleSize.width);
You can set UIImage + UIText inside UIButton , for reference
https://developer.apple.com/documentation/uikit/uibutton

bounds of imageView are always 240

I have a probably simple mistake that drives me crazy.
I'm working with UIImageView within a UIScrollView. To fit the image in the view I want to get the width of the imageView to adjust the zoom scale.
But the code
imageView.bounds.width
always returns 240.0 no matter what size the actual image has.
In the Interface Builder the imageView is horizontally and verically centered in the view, clip subviews is true and Mode is aspect fit.
Any ideas?
The size of the UIImageView is not related to the size of the image it contains. The UIImageView is probably sized to 240.0 in the storyboard or wherever else you generate it. The image will scale down or up to fit the view based on the mode. To get the size of the actual image, try the following code:
let image = UIImage("my_image_file")
let imageHeight = image.size.height
let imageWidth = image.size.width
With the size of the image now know, you can set the size of the view appropriately.
I had the same problem. Now I check the bounds in the main_queue and everything works fine.
dispatch_async(dispatch_get_main_queue(), {
print(self.image.bounds.width)
})

iOS: Solid Border Outside UIView

A layer's borderWidth and borderColor properties draw a border inside the view. Remykits pointed this out here.
A layer's shadow... properties cannot be used to create a border that both appears on all four sides and is opaque for reasons I showed here.
What I failed to specify in that question (and the reason I've opened a new one) is that I want the border to be outside the view. Increasing the frame of the view to compensate for the space lost, as has been suggested, doesn't work; I'm using a UIImageView, so even if the frame is increased, the image is still cropped.
Another suggestion was to change the contentMode of the UIImageView to .Center, in combination with changing the size of the view, but this doesn't work as the view then isn't the proper size.
The solution I first thought of was to create another UIView "behind" this UIImageView, and give it a backgroundColor to mimic the effect of a border. I also thought of creating a custom subclass of UImageView. Both courses of action, however, involve making calculations based on the frame of the view. I've had many problems with the frame not being set by AutoLayout at the proper time, etc.
Other things that come to mind are digitally adding a border to the image or positioning the image in a specific part of the UIImageView. (My attempt at the latter was imageView.layer.contentsRect = CGRectInset(imageView.bounds, 4, 4), which resulted in a strangely pixellated image.)
To be clear, what I'm looking for is this:
It really feels like there should be a simpler way to do this than creating a new class or view. Any help appreciated.
Aha! Stitching together aykutt's comment about resizing the image and changing the conentMode, Paul Lynch's answer about resizing images, and rene's (life-saving) answer about what to do your subviews actually aren't laid out in viewDidLayoutSubviews:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.myContainer.setNeedsLayout()
self.myContainer.layoutIfNeeded()
var width: CGFloat = 4 //the same width used for the border of the imageView
var rect = CGRectInset(imageView.bounds, width, width)
var size = CGSizeMake(rect.width, rect.height)
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
image.drawInRect(CGRectMake(0, 0, size.width, size.height))
var new = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
self.imageView.contentMode = .Center
self.imageView.image = new
}

Separate image's position from title's length on UIButton

UIButton image position is dependent of the current title length for the same image.
The first UIButton image is centered if there is no title set.
And the second one is shifted to the left when there is one ("like").
How can I always keep my UIButton image at the center of my button? Even if the title appears on the top of it?
I already tried with imageInset and it's the same problem. I'd also like not to use a different UIImageView other than the default UIButton's one.
You can use below code...
// the space between the image and text
CGFloat spacing = 6.0;
// lower the text and push it left so it appears centered
// below the image
CGSize imageSize = button.imageView.frame.size;
button.titleEdgeInsets = UIEdgeInsetsMake(
0.0, - imageSize.width, - (imageSize.height + spacing), 0.0);
// raise the image and push it right so it appears centered
// above the text
CGSize titleSize = button.titleLabel.frame.size;
button.imageEdgeInsets = UIEdgeInsetsMake(
- (titleSize.height + spacing), 0.0, 0.0, - titleSize.width);
Source: UIButton: how to center an image and a text using imageEdgeInsets and titleEdgeInsets?
You can try for alternate solutions using below link
UIButton Image + Text IOS
Hope it helps you...

How to make UIImageView automatically resize to the size of the image loaded

I have put an UIImageView control on my view with IB.
The size of the control is just something I decided upon, pretty random size really
What I want to do is the control to resize automatically whenever I set the image property to a new image. I want it to actually resize to the size of the image.
Can it be done automatically ? without any code intervention ?
If not - what will the best approach be in this case ?
What happens today is strange. I load images into the ImageView and I see the images getting displayed properly even though the size of the ImageView is not changed. This interferes with my intention of grabbing users touches over the ImageView. The user touches the actual image, but since some parts of the image are outside ( and this is the strange part ) of the ImageView - point mapping goes crazy
Can someone think of any explanation to this ?
thanks
The size of an image has no bearing on how large the UIImageView actually is, rather the size of the UIImageView solely depends on the size given to it in Interface Builder (or that you assigned to it). Else the images would be all whacky when you use the #2x images for Retina displays for example.
If you want to fix this, you must change the frame when setting the image as well. If you're doing this now:
[imageView setImage:[UIImage imageNamed:#"myImage.jpg"]];
change it to:
UIImage img = [UIImage imageNamed:#"myImage.jpg"];
[imageView setImage:img];
imageView.frame = CGRectMake(imageView.frame.origin.x, imageView.frame.origin.y,
img.size.width, img.size.height);
This will however not change the layout of view it is contained within, you can make it change the sizes of the other views automatically under iOS 6 using Layout Constraints. If you are an Apple Developer you can watch the WWDC instruction videos, they explain how that system works quite well.
If you're fine with the view not growing, and the problem is just how the image overflows it's bounds when you change it to one that does not match the dimension of the containing view, you can set the "Clip Subviews" checkbox in Interface Builder for the image view. This will make it so that the view will not draw anything outside it's own bounding box, if you also set the scaling mode to "Aspect Fill" or "Scale To Fill", the image will always fill up the entire bounds of the containing view.
Here is the code snippet I cut and paste often, using the same method as Hampus Nilsson above -
Example
func demo(x0:CGFloat, y0:CGFloat) {
let imgView = UIImageView(image: UIImage(named: "someImg.png"));
imgView.sizeToImage();
imgView.center = CGPoint(x:x0, y:y0);
}
UIImageView Extension
extension UIImageView {
/******************************************************************************/
/** #fcn sizeToImage()
* #brief size view to image
* ##assum (image!=nil)
*/
/******************************************************************************/
func sizeToImage() {
//Grab loc
let xC = self.center.x;
let yC = self.center.y;
//Size to fit
self.frame = CGRect (x: 0, y: 0, width: (self.image?.size.width)!/2, height: (self.image?.size.height)!/2);
//Move to loc
self.center = CGPoint(x:xC, y:yC);
return;
}
A wonderful cut & paste, use if needed!
let containerView = UIView(frame: CGRect(x:0,y:0,width:320,height:500))
let imageView = UIImageView()
if let image = UIImage(named: "Image_Name_Here") {
let ratio = image.size.width / image.size.height
if containerView.frame.width > containerView.frame.height {
let newHeight = containerView.frame.width / ratio
imageView.frame.size = CGSize(width: containerView.frame.width, height: newHeight)
}
else{
let newWidth = containerView.frame.height * ratio
imageView.frame.size = CGSize(width: newWidth, height: containerView.frame.height)
}
}

Resources