Can I set offset position on Storyboard? - swift

Can I write like the code below on Storyboard?
let button = UIButton()
button.titleLabel.center = CGPoint(x:button.titleLabel.center.x, y:button.titleLabel.center.y + 30)

Look into UIEdgeInsets and the UIButton property titleEdgeInsets.
button.titleLabelInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 30)
Depending on your exact needs and code, this should do what you need. (FYI - there is a imageEdgeInsets also.)

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.

How to get rid of the padding between UIButton image and the borders of the UIButton?

I would like to get rid of the spacing between the top of the UIButton image and the top border of the UIButton as well as the bottom of the UIButton image and the bottom border of the UIButton (refer to attached image).
I tried to use the below code however with no avail:
newFileButton.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
newFileButton.titleEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
newFileButton.contentEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
Any suggestions are much appreciated.
Regards,
Shadi.
The insets are at zero by default. To get rid of space on the inside, add negative insets.
newFileButton.imageEdgeInsets = UIEdgeInsets(top: -4, left: 0, bottom: -4, right: 0)

How to set spacing between collectionview cells in Swift 3?

currently i am using swift 3 and storyboard, googled everything and looked over all stackoverflow similar questions, got nothing so far.
On my example Porject,
my Collection view looks like this
Simulator Screenshot
which is not what i want, i want a grid layout with no spacing at all, i edited the storyboard values ddin't got anything there, so for that i used this code
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
let width = UIScreen.main.bounds.width
layout.sectionInset = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
layout.itemSize = CGSize(width: width / 2, height: width / 2)
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 0
collectionView!.collectionViewLayout = layout
didn't work either :(
'if let layout = self.collectionView.collectionViewLayout as? UICollectionViewFlowLayout{
let width = UIScreen.main.bounds.width
layout.sectionInset = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
layout.itemSize = CGSize(width: width / 2, height: width / 2)
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 0
}'

Padding around UIImageView. Swift 3

I have a UIImageView, where I don't want the image to 'touch' the edge of the view, rather have some 'padding' around it. However, I have tried the following, and for some reason it doesnt change:
#IBOutlet weak var pictureOutletOne: UIImageView!
//set the image
pictureOutletOne.image = UIImage(named: itemOne)
//set the padding
pictureOutletOne.layoutMargins = UIEdgeInsetsMake(10, 10, 10, 10);
I have also tried:
pictureOutletOne.translatesAutoresizingMaskIntoConstraints = false
pictureOutletOne.layoutMargins = UIEdgeInsets(top: 10, left: 100, bottom: 10, right: 0)
I have read alot about this, but these are the solutions I have found, but they aren't working. Using Swift 3.
Thanks so much.
Swift 4.2 & 5
let imageView = UIImageView()
imageView.image = UIImage(named:
"image")?.withAlignmentRectInsets(UIEdgeInsets(top: -5, left: -5, bottom: -5,
right: -5))
Insets should be given in negative value
You can insert the imageView into a view and set constraints to sides, guaranteed approach :)
Override the alignmentRectInsets property in a new class:
class PaddedImageView: UIImageView {
override var alignmentRectInsets: UIEdgeInsets {
return UIEdgeInsets(top: -10, left: -10, bottom: -10, right: -10)
}
}
Swift 5.4 & Xcode 13
Here is a little helper extension I build:
extension UIImage {
func addPadding(_ padding: CGFloat) -> UIImage {
let alignmentInset = UIEdgeInsets(top: -padding, left: -padding,
bottom: -padding, right: -padding)
return withAlignmentRectInsets(alignmentInset)
}
}
let padding: CGFloat = 10
myImageView.contentMode = .scaleAspectFill
myImageView.image = UIImage(named: "myImage.png").resizableImage(withCapInsets: UIEdgeInsets(top: padding, left: padding, bottom: padding, right: padding), resizingMode: .stretch)
Swift 5
Adds padding to right and left of an image place in an image view.
let image = UIImage(systemName: "circle.fill")
let insets = UIEdgeInsets(top: 0, left: -15, bottom: 0, right: -15)
let imageView = UIImageView(image: image.withAlignmentRectInsets(insets))
Note: UIStackView honors alignment insets as contributors to an image view's intrinsic content size.
Use case example:
In my application, I have a vertical stack comprised of a small center-aligned UILabel stacked above a UIImageView in a UITableViewCell. Label width varies from cell to cell, varying respective vertical stack widths and shifting images' respective horizontal alignments. I.e. the images don't line up in the table.... By padding images with horizontal alignment insets, it forces vertical stack to have a consistent width greater than max expected label width, keeping images center-aligned vertically in the table.

UIButton in Swift with two images

I'm trying to make a UIButton that has a UIImage on either side (left and right) of the button's title. Ideally, the images would be pinned to the left and right sides of the button, and the title would be centered, but I can live with the images being right next to the title label I suppose. I have been able to add one image, which appears right before the title, but how would I add a second?
I know this is an old question but since no code was provided and someone asked for it I figured I would share my solution for this.
What I did was create a new class which subclasses a UIButton. I made sure that you can see all the changes you do instantly in your interface builder as well. So you can just drag in a UIButton. Specify the class to your own class and it will allow you to set the images and see it being drawn instantly
Here is what I did to achieve this
import UIKit
#IBDesignable
class AddProfilePictureView: UIButton {
#IBInspectable var leftHandImage: UIImage? {
didSet {
leftHandImage = leftHandImage?.withRenderingMode(.alwaysOriginal)
setupImages()
}
}
#IBInspectable var rightHandImage: UIImage? {
didSet {
rightHandImage = rightHandImage?.withRenderingMode(.alwaysTemplate)
setupImages()
}
}
func setupImages() {
if let leftImage = leftHandImage {
self.setImage(leftImage, for: .normal)
self.imageView?.contentMode = .scaleAspectFill
self.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: self.frame.width - (self.imageView?.frame.width)!)
}
if let rightImage = rightHandImage {
let rightImageView = UIImageView(image: rightImage)
rightImageView.tintColor = COLOR_BLUE
let height = self.frame.height * 0.2
let width = height
let xPos = self.frame.width - width
let yPos = (self.frame.height - height) / 2
rightImageView.frame = CGRect(x: xPos, y: yPos, width: width, height: height)
self.addSubview(rightImageView)
}
}
}
I would break it into two buttons within a collection view- it's very flexible and can work great for something like this.
Add a UIImageView with an image to the button by addSubview and another to the button by setImage, it can be adjusted with titleEdgeInsets and imageEdgeInsets.
if you need a code sample – let me know.
Hope it helps!
Swift 5, XCode 11.6
Please use the below code in your extension or in a custom UIButton class. I have used the below code in my custom class. The function will set left or right image respectively and align the text.
/// Sets a left and right image for a button
/// - Parameters:
/// - right: right image
/// - left: left image
func setImages(right: UIImage? = nil, left: UIImage? = nil) {
if let leftImage = left, right == nil {
setImage(leftImage, for: .normal)
imageEdgeInsets = UIEdgeInsets(top: 5, left: (bounds.width - 35), bottom: 5, right: 5)
titleEdgeInsets = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: (imageView?.frame.width)!)
contentHorizontalAlignment = .left
}
if let rightImage = right, left == nil {
setImage(rightImage, for: .normal)
imageEdgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: (bounds.width - 35))
titleEdgeInsets = UIEdgeInsets(top: 0, left: (imageView?.frame.width)!, bottom: 0, right: 10)
contentHorizontalAlignment = .right
}
if let rightImage = right, let leftImage = left {
setImage(rightImage, for: .normal)
imageEdgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: (bounds.width - 35))
titleEdgeInsets = UIEdgeInsets(top: 0, left: (imageView?.frame.width)!, bottom: 0, right: 10)
contentHorizontalAlignment = .left
let leftImageView = UIImageView(frame: CGRect(x: bounds.maxX - 30,
y: (titleLabel?.bounds.midY)! - 5,
width: 20,
height: frame.height - 10))
leftImageView.image?.withRenderingMode(.alwaysOriginal)
leftImageView.image = leftImage
leftImageView.contentMode = .scaleAspectFit
leftImageView.layer.masksToBounds = true
addSubview(leftImageView)
}
}
Usage:
vegaButton.setImage(right: myImage) // for right image
vegaButton.setImage(left: myImage) // for left image
vegaButton.setImage(right: myImage, left: myImage) // for both images.