how to give padding to a label text in collectionviewcell in swift? - ios

I have UICollectionViewCell and inside cell their is one label without set width constraints that text automatically set ,but I need left and right spacing from the text in the label in swift

You should have custom UILabel class and in that class override drawTextInRect :
override func drawTextInRect(rect: CGRect) {
var insets: UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 10.0, bottom: 0.0, right: 10.0)
super.drawTextInRect(UIEdgeInsetsInsetRect(rect, insets))
}
If your label has more than one line it's better to use UITextView and change textContainerInset property:
let textView = UITextView()
textView.textContainerInset = UIEdgeInsets(top: 0.0, left: 10.0, bottom: 0.0, right: 10.0)

Related

UIcollectionViewCell disappear when UICollectionView.contentInset set

My problem is..
when I set contentInset like below
membershipCollectionView.contentInset = UIEdgeInsets(top: 1, left: 0, bottom: 1, right: 0)
UICollectionViewCell disappear. If I change the parameter value of top, bottom to 0 it appears. Is there anyone who explain this disappearing situation?
On contentInset = UIEdgeInsets(top: 1, left: 0, bottom: 1, right: 0)
On contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
Here is my UICollectionView and UICollectionViewCell
UICollectionView
height = 50
also I set estimatedItemSize to automaticSize
#IBOutlet weak var collectionLayout: UICollectionViewFlowLayout! {
didSet {
collectionLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
}
}
UICollectionViewCell
height = 40
this is label inside UICollectionViewCell. Height is 40

Set insets on UILabel

I'm trying to set some insets in a UILabel. It worked perfectly, but now UIEdgeInsetsInsetRect has been replaced with CGRect.inset(by:) and I can't find out how to solve this.
When I'm trying to use CGRect.inset(by:) with my insets, then I'm getting the message that UIEdgeInsets isn't convertible to CGRect.
My code
class TagLabel: UILabel {
override func draw(_ rect: CGRect) {
let inset = UIEdgeInsets(top: -2, left: 2, bottom: -2, right: 2)
super.drawText(in: CGRect.insetBy(inset))
// super.drawText(in: UIEdgeInsetsInsetRect(rect, inset)) // Old code
}
}
Anyone knows how to set the insets to the UILabel?
Imho you also have to update the intrinsicContentSize:
class InsetLabel: UILabel {
let inset = UIEdgeInsets(top: -2, left: 2, bottom: -2, right: 2)
override func drawText(in rect: CGRect) {
super.drawText(in: rect.inset(by: inset))
}
override var intrinsicContentSize: CGSize {
var intrinsicContentSize = super.intrinsicContentSize
intrinsicContentSize.width += inset.left + inset.right
intrinsicContentSize.height += inset.top + inset.bottom
return intrinsicContentSize
}
}
Please update your code as below
class TagLabel: UILabel {
override func draw(_ rect: CGRect) {
let inset = UIEdgeInsets(top: -2, left: 2, bottom: -2, right: 2)
super.drawText(in: rect.insetBy(inset))
}
}
this code differs from the accepted answer because the accepted answer uses insetBy(inset) and this answer uses inset(by: inset). When I added this answer in iOS 10.1 and Swift 4.2.1 autocomplete DID NOT give you rect.inset(by: ) and I had to manually type it in. Maybe it does in Swift 5, I'm not sure
For iOS 10.1 and Swift 4.2.1 use rect.inset(by:)
this:
override func draw(_ rect: CGRect) {
let inset = UIEdgeInsets(top: -2, left: 2, bottom: -2, right: 2)
super.drawText(in: rect.inset(by: inset))
}
Swift 5
replace method drawText(...) with draw(...)
extension UILabel {
open override func draw(_ rect: CGRect) {
let inset = UIEdgeInsets(top: -2, left: 2, bottom: -2, right: 2)
super.draw(rect.inset(by: inset))
}}

How can I modify my UILabel subclass so that it can accept custom values?

This is my current class.
class PaddedUILabel: UILabel {
var padding = UIEdgeInsets(top: 4, left: 8, bottom: 4, right: 8)
override func drawText(in rect: CGRect) {
super.drawText(in: UIEdgeInsetsInsetRect(rect, padding))
}
// Override -intrinsicContentSize: for Auto layout code
override var intrinsicContentSize : CGSize {
let superContentSize = super.intrinsicContentSize
let width = superContentSize.width + padding.left + padding.right
let heigth = superContentSize.height + padding.top + padding.bottom
return CGSize(width: width, height: heigth)
}
// Override -sizeThatFits: for Springs & Struts code
override func sizeThatFits(_ size: CGSize) -> CGSize {
let superSizeThatFits = super.sizeThatFits(size)
let width = superSizeThatFits.width + padding.left + padding.right
let heigth = superSizeThatFits.height + padding.top + padding.bottom
return CGSize(width: width, height: heigth)
}
}
Right now, the paddings are hardcoded. I'd like to be able to set custom values in StoryBoard UI (top, left, bottom, right).
What can I do to my code to modify this?
import Foundation
#IBDesignable class UILabelExtendedView: UILabel {
#IBInspectable var topInset: CGFloat = 4.0
#IBInspectable var bottomInset: CGFloat = 4.0
#IBInspectable var leftInset: CGFloat = 8.0
#IBInspectable var rightInset: CGFloat = 8.0
override func drawText(in rect: CGRect) {
let insets: UIEdgeInsets = UIEdgeInsets(top: topInset, left: leftInset, bottom: bottomInset, right: rightInset)
super.drawText(in: UIEdgeInsetsInsetRect(rect, insets))
}
override public var intrinsicContentSize: CGSize {
var contentSize = super.intrinsicContentSize
contentSize.height += topInset + bottomInset
contentSize.width += leftInset + rightInset
return contentSize
}
func setPadding(top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat) {
self.topInset = top
self.bottomInset = bottom
self.leftInset = left
self.rightInset = right
let insets: UIEdgeInsets = UIEdgeInsets(top: top, left: left, bottom: bottom, right: right)
super.drawText(in: UIEdgeInsetsInsetRect(self.frame, insets))
}}
Pass this class name to your label in storyboard and in attribute inspector set your padding.

UIButton's image and title edge insets programmatically in Swift

I am setting two UIButtons programmatically which look like this:
I am trying to set the image and text insets to be the same in buttons, but somehow left button's image is located differently than the right one.
I have this extension to UIButton class:
func setTextAndImageForButton(spacing: CGFloat) {
let insetAmount = spacing / 2
imageEdgeInsets = UIEdgeInsets(top: 8, left: 4, bottom: 8, right: insetAmount)
titleEdgeInsets = UIEdgeInsets(top: 0, left: 4, bottom: 0, right: -insetAmount)
contentEdgeInsets = UIEdgeInsets(top: insetAmount, left: 0, bottom: insetAmount, right: insetAmount*1.5)
}
As far as I understand when I set the insets for image, text and whole content, it should be located in the same place for both instances.
Are the insets override somehow after I set them in code?

UIButton not expanded with assigned text

I have a UIButton on the screen. There are no width constraints on the UIButton. I like my UIButton to be expanded to the assigned text. But here is the result:
Here is the implementation:
self.translatedPhraseButton.setTitle(self.selectedPhrase.translatedPhrase, for: .normal)
self.translatedPhraseButton.sizeToFit()
self.translatedPhraseButton.titleEdgeInsets = UIEdgeInsets(top: 0.0, left: 5.0, bottom: 0.0, right: 5.0)
self.translatedPhraseButton.layer.cornerRadius = 10.0
self.translatedPhraseButton.layer.masksToBounds = true
self.translatedPhraseButton.backgroundColor = UIColor(fromHexString: "2aace3")
So, I finally resolved my issue by using a single line of code:
self.translatedPhraseButton.contentEdgeInsets = UIEdgeInsets(top: 0.0, left: 15.0, bottom: 0.0, right: 15.0)
Try creating a temporary label, then setting the button's size to that label's.
let label = UILabel()
label.text = button.titleLabel?.text
label.font = button.titleLabel?.font
label.sizeToFit()
yourButton.frame.size = label.frame.size
Also, you can adjust the button's titleLabel to shrink the text to have it fit:
button.titleLabel?.adjustsFontSizeToFitWidth = true
button.titleLabel?.minimumScaleFactor = 0.5
Problem:
The reason why the text gets truncated is because of the following line:
self.translatedPhraseButton.titleEdgeInsets = UIEdgeInsets(top: 0.0, left: 5.0, bottom: 0.0, right: 5.0)
You have added 10.0 padding to the title label, which causes the text to truncate.
Solution:
I have used Swift 3 (It wouldn't be hard to change it to Swift 2 if you need)
Button:
class RoundedCornerButton : UIButton {
override func draw(_ rect: CGRect) {
let path = UIBezierPath(roundedRect: rect,
byRoundingCorners: [.topLeft, .topRight, .bottomLeft, .bottomRight],
cornerRadii: CGSize(width: 10, height: 10))
UIColor.red.setFill()
path.fill()
}
override var intrinsicContentSize: CGSize {
let originalSize = super.intrinsicContentSize
let size = CGSize(width: originalSize.width + 10, height: originalSize.height)
return size
}
}
Invoking:
let translatedPhraseButton = RoundedCornerButton()
translatedPhraseButton.setTitle("haskjhdjk", for: .normal)
view.addSubview(translatedPhraseButton)
translatedPhraseButton.translatesAutoresizingMaskIntoConstraints = false
translatedPhraseButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
translatedPhraseButton.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true

Resources