Swift issue when set an image as background programmatically - ios

I'm trying to set an image as background to the whole controller so I've written the code which I enclosed below and works fine on iPhone 11 Pro Max.
But surprisingly that wouldn't work as expected on iPhone X and the image was cut off at the bottom of the screen so I tried to modify UIImageView contentMode but there was no result.
Please take a look at the screenshot to see the simulators:
Here is my code:
let img = UIImageView(frame: holderView.bounds)
img.image = UIImage(named: "step 2")
img.contentMode = .scaleToFill
holderView.addSubview(img)
The holderView was pinned in Interface Builder into the fourth edges of superview.
Any ideas to fix it but I don't want to use auto-layout here because this is a simple case to illustrate the issue and it would be a complex one.

You should set the contentMode to scaleToFill if you want to display the entire image irrespective of the displayed device. Also, constraint the UIImageView to it's superview UIView.
let img = UIImageView(frame: holderView.bounds)
img.contentMode = .scaleToFill
img.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
img.topAnchor.constraint(equalTo: view.topAnchor),
img.leadingAnchor.constraint(equalTo: view.leadingAnchor),
img.bottomAnchor.constraint(equalTo: view.bottomAnchor),
img.trailingAnchor.constraint(equalTo: view.trailingAnchor)
])

Related

UIImageView size relative to screen size

I have an UIImageView, with an image like so
imageView.image = UIImage(named: "imageName")
imageView.contentMode = .scaleAspectFit
imageView.translatesAutoresizingMaskIntoConstraints = false
On the iPhone X this image looks great with 140x140 dimensions
Maybe needless to say, this does not look great on the iPhone5s, since 140x140 would take up too much of screen space
How can I correctly scale my image for other screen dimensions, what would be the best practice for this?
As for now, I set the image height and width to
let size = UIScreen.main.bounds.height / 5.5
imageView.heightAnchor.constraint(equalToConstant: size),
imageView.widthAnchor.constraint(equalToConstant: size),
Since that will be pretty close to what I am after. But I can't shake the feeling that there are better alternatives than this
The question is a bit broad like "What do you think guys?", but still.
It's better to change your size accordingly to your parent view, not screen.
imageView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.2, constant: 0)
imageView.widthAnchor.constraint(equalTo: imageView.heightAnchor, multiplier: 1.0, constant: 0)

Circular UIImageView is square on some devices

I have a UIView that has a UIImageView in it.
I set the UIImageView to be circular and add a border to it like this:
self.profilePicImageView.layer.cornerRadius = self.profilePicImageView.frame.size.height / 2
self.profilePicImageView.layer.masksToBounds = true
self.profilePicImageView.layer.borderColor = UIColor.white.cgColor
self.profilePicImageView.layer.borderWidth = 3
It's being called after I initialize the view in my viewController and before I add it as a subview (function called setupUI()).
It works perfectly fine on most of the devices, but on the large screen devices (iPhone 6/6s/7 Plus and iPhone X) I get the border right but the image itself isn't circular.
Please see the examples:
Regular iPhones:
Large iPhones (iPhone 6/6s/7 Plus and iPhone X):
Any idea what the problem can be and how can I fix it?
Thanks!!
Just try this code it will help you.
imageView.layer.cornerRadius = imageHeight/2
imageView.layer.masksToBounds = true
imageView.contentMode = .scaleAspectFill

iOS - Layout UIImageView's subview on the scaleaspectfit UIImageView's image

I have UITableView, where is a UIStackView with same views(different content only) on each cell.(The tableView's cell is shown below)
The view consists of UIImageView and UILabel above. The UIImageView's content is set to .scaleAspectFit, because of keeping ratio. I have a problem with adding a new image layer (subview) to imageView, which has to perfectly overlap current image, but I can't fit on image properly with autolayout, because I know only UIImageView's anchor, not image's anchor (it doesn't exists).
PS: I have tried to use imageview.image.size.width, to set width and height, but it's also useless.
Current code of adding subview using autolayout:
func addStripe(){
let stripeLayer = UIImageView(image: #imageLiteral(resourceName: "book_new"))
imageView.addSubview(stripeLayer)
stripeLayer.contentMode = .scaleToFill
stripeLayer.translatesAutoresizingMaskIntoConstraints = false
stripeLayer.topAnchor.constraint(equalTo: imageView.topAnchor).isActive = true
stripeLayer.leadingAnchor.constraint(equalTo: imageView.centerXAnchor).isActive = true
stripeLayer.trailingAnchor.constraint(equalTo: imageView.trailingAnchor).isActive = true
Aaaand there is a result of addStripe function (the wrong one)
Thanks everyone for your time!
I think you should set frame of your stripeLayer equal to imageView. You can do this with init method of UIImageView like this:
let stripeLayer = UIImageView(frame: imageView.frame)
stripeLayer.image = #imageLiteral(resourceName: "book_new")
imageView.addSubview(stripeLayer.image)
I hope it help you
#ReinhardManner's comment helped me and it works. This single line fix my problem
let sizeInView = AVMakeRect(aspectRatio: imgViewFake.image.size, insideRect: imgViewFake.bounds).size

Swift 3 - Can not get label - creating in code - to match width when rotating to landscape mode

I created a UILabel in my Swift 3 code (I have some labels on storyboard and those resize just fine when rotating, it is just the ones I create in swift code that don't resize so clearly I am doing it wrong). I want the width to match the width of the view it is in. When I create it, it sizes correctly but when the view is rotated to landscape mode, it does not resize. I started by adding NSLayoutConstraint for the right of the label to match the right side of the view, but I kept having issues. After diving into the documentation, I found that it is safer and more appropriate to use NSLayoutAnchor to perform this task. The doc says it can catch more autolayout issues at compile time. I found that to be the case and it is a but easier to understand and use. But, it still does not work. When the view is rotated, the label stays the same width.
// Swim Title
newXPosition = 4
label = UILabel(frame: CGRect(x: newXPosition, y: newYPosition, width: labelParentView.frame.width - 4, height: SPLIT_HEIGHT))
label.textAlignment = .left
label.text = "Swim Splits"
label.backgroundColor = UIColor.lightGray
self.labelParentView.addSubview(label)
// Creating the same constraints using Layout Anchors
let margins = labelParentView.layoutMarginsGuide
label.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true
labelParentView.layoutIfNeeded()
Two ways to do this...
A. Tell the label to use an autoresizing mask:
self.labelParentView.addSubview(label)
// use autoresizing mask
label.autoresizingMask = [.flexibleWidth, .flexibleHeight]
// don't need anything else
//let margins = labelParentView.layoutMarginsGuide
//label.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true
//labelParentView.layoutIfNeeded()
or, B. Turn off autoresizing mask, and add constraints:
self.labelParentView.addSubview(label)
// turn off autoresizing mask
label.translatesAutoresizingMaskIntoConstraints = false
// add constraints
label.leftAnchor.constraint(equalTo: labelParentView.leftAnchor, constant: 4.0).isActive = true
label.topAnchor.constraint(equalTo: labelParentView.topAnchor, constant: 4.0).isActive = true
label.rightAnchor.constraint(equalTo: labelParentView.rightAnchor, constant: -8.0).isActive = true
label.heightAnchor.constraint(equalToConstant: SPLIT_HEIGHT).isActive = true

Swift 3 | Button Label under Image AND resize Image

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.

Resources