Add top and bottom padding to UILabel using Swift - ios

How do you add padding to the top and bottom of the content within a UILabel?
I have tried to find the means of doing it via NSAttributedString text but cannot seem to find a way to apply margins to the top and bottom only.

Do this in swift :-
class Label: UILabel {
override func drawTextInRect(rect: CGRect) {
super.drawTextInRect(UIEdgeInsetsInsetRect(rect, UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10)))
}
}

Related

UITableViewController's tableView's Content insets

I want to make a padding for tableView's content. The result should be the following:
Result I want to achieve
If I use tableView.contentInset = UIEdgeInset(...) like this:
func setStandartDesign() {
...
tableView.contentInsetAdjustmentBehavior = .always
tableView.showsVerticalScrollIndicator = false
tableView.contentInset = UIEdgeInsets(top: 0, left: .bigOffset, bottom: 0, right: .bigOffset)
...
}
To be clear .bigOffset is merely a constant value that is equal to 12
And then use it in viewDidLoad:
override func viewDidLoad() {
setStandartDesign()
}
I have insets only on the left side of a tableView:
No inset on the right side
Alternatively I can use .insetGrouped style of the tableView. However, I do not know how to change a padding size. Is there any possible way to fix this problem?

How to set space between tableView Cells?

Implemented Programmatically Custom Cell
I am trying to set space between cells but this code is not working for me
override func layoutSubviews() {
super.layoutSubviews()
let padding = UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
bounds = bounds.inset(by: padding)
}
Better approach is the most simple way that make your cells height a bit bigger(3pt from top and 7pt from the bottom) than that of your cell's Total height, and making the colour as [UIColor clearColor]. That would give the illusion that the cells have a 10 pt gap in between.
OR
Add UIView() of 10 height at the end and give it clear color it show space between two cells

cannot set UILabel padding in tableViewcell

I have set my UILabel padding using StackOverflow's popular thread for resolving auto-layout issue.
This thread is basically a UILabel extension.
Part of the answer is:
class NRLabel : UILabel {
var textInsets = UIEdgeInsets.zero {
didSet { invalidateIntrinsicContentSize() }
}
override func textRect(forBounds bounds: CGRect, limitedToNumberOfLines numberOfLines: Int) -> CGRect {
let insetRect = UIEdgeInsetsInsetRect(bounds, textInsets)
let textRect = super.textRect(forBounds: insetRect, limitedToNumberOfLines: numberOfLines)
let invertedInsets = UIEdgeInsets(top: -textInsets.top,
left: -textInsets.left,
bottom: -textInsets.bottom,
right: -textInsets.right)
return UIEdgeInsetsInsetRect(textRect, invertedInsets)
}
override func drawText(in rect: CGRect) {
super.drawText(in: UIEdgeInsetsInsetRect(rect, textInsets))
}
}
Everything is working fine, padding has been added but i need to reload the tableViewcell to see the effect.
I have overridden my customCell's viewWillLayoutSubviews() function like this for padding
self.chatLabel.textInsets = UIEdgeInsets.init(top: 10, left: 10, bottom: 10, right: 10)
And the effect is like this.
You see, first label is getting it's padding after reloading the cell.
Pls suggest how to achieve UILabel padding by using the extension mentioned above so that this issue is resolved.
Add
this two function into your extention and remove all other:
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 var intrinsicContentSize : CGSize {
var intrinsicSuperViewContentSize = super.intrinsicContentSize
intrinsicSuperViewContentSize.height += topInset + bottomInset
intrinsicSuperViewContentSize.width += leftInset + rightInset
return intrinsicSuperViewContentSize
}
Using your NRLabel class, this works fine for me. The theLabel is added in Storyboard TableViewCell Prototype, with constraints set to allow auto-sizing rows.
class PaddedLabelCell : UITableViewCell {
#IBOutlet weak var theLabel: NRLabel!
override func awakeFromNib() {
super.awakeFromNib()
self.setupLabel()
}
func setupLabel() -> Void {
theLabel.layer.cornerRadius = 8.0
theLabel.layer.masksToBounds = true
theLabel.textInsets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
// any other setup stuff can go here....
}
}
You have nothing in NRLabel which tells it to redraw when the textInsets property is changed. You need to do something like this:
var textInsets = UIEdgeInsets.zero {
didSet {
invalidateIntrinsicContentSize()
setNeedsDisplay()
}
}
So now when the textInsets property is changed the NRLabel will be re-drawn with the new text insets.
After some long tiring hours i just found the solution which i never tried and i don't know why. :(
In cellForRowAtIndexPath i just wrote the line which was in customCell's file.
Just call this line before returning cell.
cell.chatLabel.textInsets = UIEdgeInsets.init(top: 10, left: 10, bottom: 10, right: 10)
The reason behind it may be, Cell is drawn with all the functionality but it didn't get much to refresh it's UI.
So calling the line just before showing the cell resolve the problem.

Button with Image and Text vertically aligned using autolayout constraints

I m very new to IOS development and AutoLayout .
I am facing issues to align the Image and Text inside UIbutton using Storyboard. I had tried to achieve it with TitleEdgeinset and ImageEdge insets accordingly to place the Title ( text ) vertically centered below the Image. But the issue is I have 3 similar buttons which are Vertically stacked ( StackView) and the Text is dynamically set since we have localized strings ( includes Arabic rtl ) .
The image and text moves according to the text length. Is there any ways that I can achieve to make all the buttons with image and text vertically alligned.Also, different screen resolutions are not currently working if using edge insets. Appreciate your help . Thanks in advance.
Few days ago, I solved similar problem,try this
private func adjustImageAndTitleOffsetsForButton (button: UIButton) {
let spacing: CGFloat = 6.0
let imageSize = button.imageView!.frame.size
button.titleEdgeInsets = UIEdgeInsetsMake(0, -imageSize.width, -(imageSize.height + spacing), 0)
let titleSize = button.titleLabel!.frame.size
button.imageEdgeInsets = UIEdgeInsetsMake(-(titleSize.height + spacing), 0, 0, -titleSize.width)
}
call this method for each button, like
self.adjustImageAndTitleOffsetsForButton(yourButton)
Combining Ajay's and Matej's answer:
import Foundation
import UIKit
class VerticalButton: UIButton {
override func awakeFromNib() {
super.awakeFromNib()
self.contentHorizontalAlignment = .left
}
override func layoutSubviews() {
super.layoutSubviews()
centerButtonImageAndTitle()
}
private func centerButtonImageAndTitle() {
let titleSize = self.titleLabel?.frame.size ?? .zero
let imageSize = self.imageView?.frame.size ?? .zero
let spacing: CGFloat = 6.0
self.imageEdgeInsets = UIEdgeInsets(top: -(titleSize.height + spacing),left: 0, bottom: 0, right: -titleSize.width)
self.titleEdgeInsets = UIEdgeInsets(top: 0, left: -imageSize.width, bottom: -(imageSize.height + spacing), right: 0)
}
}
I've modified Ajay's answer because my images weren't centered:
func centerButtonImageAndTitle(button: UIButton) {
let spacing: CGFloat = 5
let titleSize = button.titleLabel!.frame.size
let imageSize = button.imageView!.frame.size
button.titleEdgeInsets = UIEdgeInsets(top: 0, left: -imageSize.width, bottom: -(imageSize.height + spacing), right: 0)
button.imageEdgeInsets = UIEdgeInsets(top: -(titleSize.height + spacing), left: -imageSize.width/2, bottom: 0, right: -titleSize.width)
}
This is a solution that worked for me. Just set the button class to HorizontallyCenteredButton in storyboard and set the title and image top and bottom insets according to your needs (to place the image higher than title) and the button will adjust horizontal insets automatically so that the image is centered above title.
class HorizontallyCenteredButton: LocalizedButton {
override func awakeFromNib() {
super.awakeFromNib()
self.contentHorizontalAlignment = .left
}
override func layoutSubviews() {
super.layoutSubviews()
self.centerButtonImageAndTitle()
}
func centerButtonImageAndTitle() {
let size = self.bounds.size
let titleSize = self.titleLabel!.frame.size
let imageSize = self.imageView!.frame.size
self.imageEdgeInsets = UIEdgeInsets(top: self.imageEdgeInsets.top, left: size.width/2 - imageSize.width/2, bottom: self.imageEdgeInsets.bottom, right: 0)
self.titleEdgeInsets = UIEdgeInsets(top: self.titleEdgeInsets.top, left: -imageSize.width + size.width/2 - titleSize.width/2, bottom: self.titleEdgeInsets.bottom, right: 0)
}
}
To align all the buttons vertically, first select the buttons, then click the button on the bottom-right of the storyboard titled "Align", and finally select "Vertical Centers" in the menu that appears. That should do the trick.
I created a view, then put a VStack with image and text, as well as button.
Make sure the VStack constraints are 0 on all 4 sides so it covers the button :)
this is an easy one, so apologies if you have already tried it!
you don't need to set anything for insets, just make sure that the 3 buttons are aligned with horizontal centres ...
select the controls you want to align, and click on the button highlighted below (bottom right on the xCode screen) and select the Vertical Centres option to align the three with each other, or select Horizontally in Container to put them in the middle of your view.

Change a UIButton's text (padding) programmatically in Swift

Still learning Swift and don't know Objective-C. I saw that in order to changing a button's text programmatically requires the use of titleEdgeInsets but I am not really sure how to use it.
I would like to change the text in the button (padding) in the bottom and both the left and the right.
Thanks for any responses and/or examples!
Still valid for:
iOS 12/Xcode 10/Swift 4.2/OSX 10.13.2
iOS 9.1/Xcode 7.1/Swift 2.1/OSX 10.10.5:
The method titleEdgeInsets didn't work for me. My button's frame tightly hugs the text (I didn't specify a frame size), and the frame has a red background color. After doing:
myButton.titleEdgeInsets = UIEdgeInsetsMake(10,10,10,10)
the red background shrunk inwards by 10 pixels on each side, which meant that now some of the text was outside the red background. Using negative values had no effect on the original frame size.
I was able to get padding around the text, effectively making the frame bigger, by doing:
myButton.contentEdgeInsets = UIEdgeInsetsMake(5,5,5,5)
iOS 10 and Swift 3 example
Tested and works on IOS 11 and Swift 4.
refineButton.contentEdgeInsets = UIEdgeInsets(top: 5, left: 0, bottom: 0, right: 0)
You can add padding from top, left, right and bottom by doing these lines of code.
button.titleEdgeInsets.left = 10; // add left padding.
button.titleEdgeInsets.right = 10; // add right padding.
button.titleEdgeInsets.top = 10; // add top padding.
button.titleEdgeInsets.bottom = 10; // add bottom padding.
You can also do this in the storyboard:
For iOS 9.1/Xcode 7.1/Swift 2.1
#IBOutlet weak var ratingButton: UIButton!
override func viewDidLoad() {
ratingButton.contentEdgeInsets = UIEdgeInsets(top:15,right:10,bottom:15,left:10)
super.viewDidLoad()
}
Or you can use a custom class if you don't want to define the properties everytime you create a button;
class UIPaddedButton: UIButton {
let padding = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10)
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override init(frame: CGRect) {
super.init(frame: frame)
}
override func titleRect(forContentRect contentRect: CGRect) -> CGRect {
return contentRect.inset(by: padding)
}
}
And when initializing;
let btn = UIPaddedButton()
For xcode 13.4 and iOS 12
Tested and working
To make space to both sides of a button
ButtonName.contentEdgeInsets = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)

Resources