Swift - Setting corner radius on image nested in UIButton - swift

I have a button which contains text and an image but I would like the image to have a corner radius on it. When I try to apply the corner radius to the button, it applies to the whole button which I guess is correct. How can I set the corner radius to the image instead?
Here's my code:
let titleButton = UIButton()
titleButton.frame = CGRect(x: 0, y: 0, width: 100, height: 40)
titleButton.setTitle("display name", for: .normal)
titleButton.setImage(#imageLiteral(resourceName: "imgName"), for: .normal)
titleButton.layer.masksToBounds = true
titleButton.layer.cornerRadius = titleButton.frame.width / 2
self.navigationItem.titleView = titleButton

An UIButton has an UIImageView on it. So to set corner, simply set radius to the layer of the image view
titleButton.imageView?.layer.cornerRadius = 5

if you want rounded then set height and width equal
titleButton.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
titleButton.layer.cornerRadius = titleButton.frame.size.width / 2.0
titleButton.layer.masksToBounds = true
And If you want corner rounded only then
titleButton.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
titleButton.layer.cornerRadius = 10
titleButton.layer.masksToBounds = true

If you want the cornerRadius to be on the button itself and not the image add the following line:
titleButton.clipsToBounds = true

Related

Swift textfield rightview custom UIButton image size issue (Secure field toggle)

I have a custom button which works as a secure text toggle button - the image size is fine on larger iPhones, but on smaller Iphone8, iPhone 7 etc. The image is too big, see below.
I have tried adding constraints and modifying the CGrect of the button but this strangely has no effect on the size of the image.
I have tried a smaller image size but the image is just too small. Do I need different images for different device sizes or is there a way around this in code ?
Thanks
let button = UIButton(type: .custom)
//let button = UIButton(frame: CGRect(x: 0, y: 0, width: 50, height: self.frame.height))
setPasswordToggleImage(button)
button.imageEdgeInsets = UIEdgeInsets(top: 0, left: -10, bottom: 0, right: 0)
// Debug
//button.backgroundColor = .blue
//button.frame = CGRect(x: CGFloat(self.frame.size.width - 25), y: CGFloat(5), width: CGFloat(25), height: CGFloat(25))
button.addTarget(self, action: #selector(self.togglePasswordView), for: .touchUpInside)
self.rightView = button
self.rightViewMode = .always
button.alpha = 0.4
Creating correct assets for x1 x2 and x3 fixed the issue.

UIImage in a UIcollectonView issue

I am trying to add a UIImage to the UICollectionViewController by using the following code:
let backgroundImage = UIImageView(frame: CGRect(x: 0, y: 0, width: 430, height: 550))
backgroundImage.image = UIImage(named: "fantasy_football_hero_tile_cropped.png")
backgroundImage.contentMode = UIView.ContentMode.scaleAspectFit
backgroundImage.clipsToBounds = true
self.view.insertSubview(backgroundImage, at: 0)
My issue is that the image is not at the bottom/lowest part of the screen which is what I am trying to achieve... how can I clip it to the bottom?! I am not using story board, can I programmatically anchor the image to the bottom as I could do in a storyboard?
This is especially true since the screen sizes for the phones are different, but the desire is still to have it anchored to the bottom.
you can add programatically. I think you add/insert some views to the self.view that will also affect simple scenario
let backgroundImageV = UIView(frame: CGRect(x: 0, y: 0, width: 430, height: 500))
backgroundImageV.backgroundColor = UIColor.blue
backgroundImageV.contentMode = UIView.ContentMode.scaleAspectFit
backgroundImageV.clipsToBounds = true
self.view.addSubview(backgroundImageV)
let backgroundImageV2 = UIView(frame: CGRect(x: 0, y: 0, width: 430, height: 510))
backgroundImageV2.backgroundColor = UIColor.green
backgroundImageV2.contentMode = UIView.ContentMode.scaleAspectFit
backgroundImageV2.clipsToBounds = true
self.view.insertSubview(backgroundImageV2, at: 0)
let backgroundImage = UIImageView(frame: CGRect(x: 0, y: 0, width: 430, height: 550))
backgroundImage.backgroundColor = UIColor.red
backgroundImage.contentMode = UIView.ContentMode.scaleAspectFit
backgroundImage.clipsToBounds = true
self.view.insertSubview(backgroundImage, at: 0)
Here Red will be bottom Green will be in 1. because you add that red colored view later. So It will work. Can you please show your full code. It will work
One problem here is that self.view for a UICollectionViewController is the UICollectionView. This is a scroll view, so no matter where you put this image view, it is going to move when the scroll view scrolls.
If that isn't what you want, there is a simple solution: set the image view as the collection view's backgroundView. That is a stationary view that forms the background to the collection view no matter how it is scrolled. If you set the image view's contentMode to bottom the image will be centered at the bottom, which seems to be what you are after.

How to change view for label

I have a UILabel and I want to change its background view. Somebody advised me to use bezier but I want a simple variant.
My label:
What it should look like:
Since these are not very complex shapes, I would suggest creating two white UIViews, rotating them 45 degrees and then adding them as subviews to the UILabel. The code would look something like this:
myLabel.clipsToBounds = true
// create the triangle on the left side of the label
let leftSquare = UIView(frame: CGRect(x: myLabel.frame.height / -2, y: 0, width: myLabel.frame.height, height: myLabel.frame.height))
leftSquare.translatesAutoresizingMaskIntoConstraints = true
leftSquare.isUserInteractionEnabled = false
leftSquare.backgroundColor = UIColor.white
leftSquare.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi / 4)) // 45 degree rotation
// create the triangle on the right side of the cell
let rightSquare = UIView(frame: CGRect(x: myLabel.bounds.width - (myLabel.frame.height / 2), y: 0, width: myLabel.frame.height, height: myLabel.frame.height))
rightSquare.translatesAutoresizingMaskIntoConstraints = true
rightSquare.isUserInteractionEnabled = false
rightSquare.backgroundColor = UIColor.white
rightSquare.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi / 4))
// add squares to label
myLabel.addSubview(leftSquare)
myLabel.addSubview(rightSquare)
myLabel.sendSubview(toBack: leftSquare)
myLabel.sendSubview(toBack: rightSquare)

Central align subView

I'm trying to centre a UIView in another view (so like a pop up view), but whatever I do, I just cannot align it centrally!
func loadPopUpView() {
let customView = CGRect(x: view.center.x, y: view.center.y, width: 100, height: 100)
popUpView = UIView(frame: customView)
popUpView.backgroundColor = UIColor.black
view.addSubview(popUpView)
popUpView.isHidden = false
}
I've changed the background colour to black just so I know when it appears.
I cannot do this with storyboard because it's going on a tableView, so I'm trying to do it programmatically. Result Image
You also need to minus half value of your custom view height and width from x and y like below:
let customView = CGRect(x: view.center.x - 50, y: view.center.y - 50, width: 100, height: 100)
You are telling it to put top left corner in the center, hence you need to let it get half size in position.
let customView = CGRect(x: view.center.x-50, y: view.center.y-50, width: 100, height: 100)
Another solution is the use anchorpoints.
customView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
customView.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
customView.heightAnchor.constraint(equalToConstant: 100).isActive = true
customView.widthAnchor.constraint(equalToConstant: 100).isActive = true
On CGRect(x:, y:, width:, height:), the point (x,y) is the origin. In iOS, that's the top left point.
On the CGRect doc:
In the default Core Graphics coordinate space, the origin is located
in the lower-left corner of the rectangle and the rectangle extends
towards the upper-right corner. If the context has a
flipped-coordinate space—often the case on iOS—the origin is in the
upper-left corner and the rectangle extends towards the lower-right
corner.
So to fix this:
let width = 100.0
let height = 100.0
let customViewFrame = CGRect(x: view.center.x - width/2.0, y: view.center.y - height/2.0, width: width, height: height)
Another solution would be to apply the center once the frame (especially the width/size) have been set.
let customViewFrame = CGRect(x: 0, y: 0, width: 100, height: 100)
customViewFrame = view.center

LottieAnimationView size won't change/is too small (iOS/Swift)

Whether the view I'm creating is a LOTAnimatedSwitch or View, the image of the animation always appears very small. The lottie animation doesn't take up the size of the view that I create. Is this an issue with downloading the animation from LottieFiles? The dimensions of the file are 600x600 pixels. I'm using Lottie version 2.5.0 and Swift 4. For example:
let animatedSwitch = LOTAnimatedSwitch(named: "toggle_switch")
animatedSwitch.frame.origin = CGPoint(x: 8, y: separatorLineView.frame.height + separatorLineView.frame.origin.y + 8)
animatedSwitch.frame.size = CGSize(width: dialogViewWidth - 16, height: 40)
animatedSwitch.setProgressRangeForOnState(fromProgress: 0.5, toProgress: 1)
animatedSwitch.setProgressRangeForOffState(fromProgress: 0, toProgress: 0.5)
animatedSwitch.contentMode = .scaleAspectFill
animatedSwitch.clipsToBounds = true
animatedSwitch.backgroundColor = .purple
The problem was with the file I downloaded from LottieFiles. To fix the animation/icon from being small, I scaled the composition size in adobe after effects to fit the preview frame. I exported the .aeb file to .json using the bodymovin plugin.
Hardik's answer was also helpful. The problem was simply that the file I downloaded had a lot of empty space around the actual icon until I scaled the picture up.
Try this code i am not sure this will help in your case
let animatedSwitch = LOTAnimatedSwitch(named: "toggle_switch")
animatedSwitch.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
animatedSwitch.center = self.view.center
animatedSwitch.setProgressRangeForOnState(fromProgress: 0.5, toProgress: 1)
animatedSwitch.setProgressRangeForOffState(fromProgress: 0, toProgress: 0.5)
animatedSwitch.contentMode = .scaleAspectFit
self.view.addSubview(animatedSwitch)
self.view.backgroundColor = UIColor.lightGray
animationView = .init(name: "lf30_editor_fip4qqkq")
animationView!.frame = CGRect(x: 0, y: 0, width: 150, height: 150)
animationView!.center = self.view.center
animationView!.contentMode = .scaleAspectFit
animationView!.loopMode = .loop
animationView!.animationSpeed = 1.0
view.addSubview(animationView!)
animationView!.play()
I had this issue too. I modified the animation view's width and height to my desired size and changed the content mode to scale aspect fill. If you wanted to make the animation larger, just update your width and height. Here's example code.
animationView.animation = Animation.named("loading")
animationView.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
animationView.contentMode = .scaleAspectFill
animationView.loopMode = .loop
animationView.play()