Unicode non-breaking space is removed end of label - ios

I'm using tableview and i use one cell to create many columns.My column number is not fixed so i had to create columns using for loop inside cellForRowAt function.I want to give some spaces between my labels inside my cell.This piece of code succesfully inserts non-breaking spaces to head of the label but it removes end of the label.Thanks for your help.
let spaces = String(repeating:"\u{00A0}",count : columnSpaceCount)
if globalSubviewHeaderStructArray[i].type == "numeric"{
if globalSubviewHeaderStructArray[i].digitsAfterComma != "0" {
var dataNumber = applyComma(comma : globalSubviewHeaderStructArray[i].digitsAfterComma , data : globalSubviewDataArray[indexPath.row][i])
var newString = "\(spaces)\(checkCurrency(option: globalSubviewHeaderStructArray[i].currency, data: dataNumber))\(spaces)"
newLabel.text = newString
}else{
var newString = "\(spaces)\(checkCurrency(option: globalSubviewHeaderStructArray[i].currency, data: globalSubviewDataArray[indexPath.row][i]))\(spaces)"
newLabel.text = newString
}
}else{
var newString = "\(spaces)\(checkCurrency(option: globalSubviewHeaderStructArray[i].currency, data: globalSubviewDataArray[indexPath.row][i]))\(spaces)"
newLabel.lineBreakMode = .byTruncatingMiddle
newLabel.text = newString
}

I want to give some spaces between my labels inside my cell
Don't do this by messing with the content of the label. Do it by messing with the position / size of the labels themselves. Insert actual space (that is, empty pixels) between the labels.

To insert space in between UILabels within a UITableViewCell, set up Autolayout Contraints, either in Storyboard or in code. Depending on the target iOS version, embedding the UILabels in a StackView is probably the easiest way, but it's available in iOS >= 8 only.
Select the labels:
Choose Embed in -> Stack View:
Set spacing:
Also set the contraints for the StackView to your needs:

Related

Get truncated text from UILabel in Swift [duplicate]

I have a single line UILabel. It has width = screen width and the content now is (the content of UILabel can change)
You have 30 seconds to make an impression during an interview
Currently, my UILabel is truncated tail and the word "duration" is not complete
self.nameLabel.lineBreakMode = NSLineBreakByTruncatingTail;
What I want is I want my UILabel still truncating tail and only display complete word.
Like the image below
Any help or suggestion would be great appreciated.
You can do something like this:
let labelWidth = CGRectGetWidth(label.bounds)
let str = "You will have 30 seconds till you give us a good impression" as NSString
let words = str.componentsSeparatedByString(" ")
var newStr = "" as NSString
for word in words{
let statement = "\(newStr) \(word) ..." as NSString
let size = statement.sizeWithAttributes([NSFontAttributeName:label.font])
if size.width < labelWidth {
newStr = "\(newStr) \(word)"
}
else{
break
}
}
newStr = newStr.stringByAppendingString(" ...")
self.label.text = newStr as String
Idea is: we split words and try check the width while appending from the beginning + the string "..." till we found the a word that will exceed the size, in the case we stop and use this new string
Ideally this is not possible,with default UILabel, when you set lineBreakMode to TruncatingTail, depending on the space required by the letter/word the OS will truncate it, one solution to fix the issue you can use following properties depending on your match.
Minimum Font Scale -- Use this property to specify the smallest multiplier for the current font size that yields an acceptable font size to use when displaying the label’s text. If you specify a value of 0 for this property, the current font size is used as the smallest font size.
Minimum Font Size -- When drawing text that might not fit within the bounding rectangle of the label, you can use this property to prevent the receiver from reducing the font size to the point where it is no longer legible.
i am not sure but try it:
nameLabel.adjustsFontSizeToFitWidth = NO;
nameLabel.lineBreakMode = NSLineBreakByWordWrapping;
OR
If you are using storyboard follow these steps i tried this and it working fine
Open Attribute Inspector
Change Line Breaks to Truncate Tail then
Change AutoShrink to Minimum Font Size
here are my screenshots of label after and before applying these properties
new output

creating spaces in placeholder fields

my problem is I want to put 2 placeholders for one textField. one of the place holders should be on the left and the other should be on the right.
my code:
func returnPlaceHolder(first: String, second: String, textField: UITextField){
let width: Int = Int(textField.bounds.width * 0.2)
let spaceValue = width - (first.count + second.count)
var temp = "\(first) "
let tempCount = spaceValue - (first.count + second.count)
var value = String()
for _ in 0..<tempCount {
temp.append(" ")
}
value = "\(temp) \(second)"
textField.placeholder = value
textField.setLeftPaddingPoints(10)
textField.setRightPaddingPoints(10)
}
I'm currently using this function to create spaces.. but my problem is the spaces won't be the same for more than one textField, and I want them to be aligned..
just like this picture: https://imgur.com/pZZMoNv
and this is the result I'm getting for my current code: https://imgur.com/a/5AN8EXl
don't mind the textFields format & text I can fix them later.. I just want to be able to align the textFields placeholders.
It would be really hard (if possible) to achieve what you are trying to do by injecting spaces into the text because each character in the font has a different width unless you use a monospaced font.
https://en.wikipedia.org/wiki/Monospaced_font
Instead, I would recommend a different approach. Override the text field, provide two UILabels and adjust their position using Autolayout.

How to center justify text in UITextView?

I have an Arabic (right to left) text in textView, when I set myTextView.alignment = .justify, the last line in text go to the left side. How can I set center justify for textView or how can move last line to the center?
just make it .center
i know what exactly you're looking for cause i've been there before, only you can make it .center
Interesting question, I would try to count the lines in the textView and cut the last one than I would try to put the cut text in a new label below the textView ... ;)
after asking how I would do this I added this:
print(self.testLabel.frame.width)
self.testLabel.text = "Hello World"
self.testLabel.sizeToFit()
print(self.testLabel.frame.width)
This is a starting point you can work with. Create a label and set the width to zero. Insert your text and set sizeToFit(). Now you are able to get the length of the label. Is it to long for your view it will have more lines... (The divider is your length - not tested, maybe an offset is needed too)
The idea is now to subtract as long as your lines are more than one and the lines are the same amount at the beginning of your calculation to get the last word and put it at the beginning of a temp string.
If this returns you get your substring for the last line.
I was interested and started with this one:
#IBOutlet weak var textBox: UITextView!
#IBOutlet weak var testLabel: UILabel!
override func viewWillAppear(_ animated: Bool) {
print(self.testLabel.frame.width)
self.testLabel.text = self.textBox.text
self.testLabel.sizeToFit()
print("total \(self.testLabel.frame.width)")
let basicAmount = Int(self.testLabel.frame.width / self.textBox.frame.width) + 1
print("lines \(basicAmount)")
var lastLine: String = ""
while basicAmount == Int(self.testLabel.frame.width / self.textBox.frame.width) + 1 {
var arr = self.textBox.text.components(separatedBy: " ")
lastLine = "\(arr.last) \(lastLine)"
arr.removeLast()
self.textBox.text = arr.joined(separator: " ")
self.testLabel.text = self.textBox.text
self.testLabel.sizeToFit()
print(lastLine)
}
}
the interesting output is:
total 1499.5
lines 7
Optional("civiuda.")
Of course you should spent more time in the calculation because of the free space at the end of a line...
use this
self.textView.textAlignment = .justified //set text alignment center and justified
self.textView.makeTextWritingDirectionRightToLeft(true)//if you want set writing direction right to left
self.textView.makeTextWritingDirectionLeftToRight(true)//if you want set writing direction left to right

Expand UILabel Text

I'm trying to make my app so that long text posts you don't have to scroll through but have an option to show all and show less (show less is default). I've been trying to do it but I'm not able to do it without changing all of the cells to "Show more" or "Show less". Here is how I make it initially show less by how many characters it has in it (Message = the post text, postCellObj = the object I use to call the cell class) this code is done in cellForRowAtIndexPath...
if messages.isEmpty == false {
var messageString = messages[indexPath.row] as String
var messageFinal = ""
if count(messageString) >= 200 {
var messageNs = messageString as NSString
var messageFinal = messageNs.substringWithRange(NSRange(location: 0, length: 200))
postCellObj.message.text = messageFinal as String + "..."
} else {
postCellObj.message.text = messages[indexPath.row]
}
}
If anyone knows how to do it, it would be much appreciated. Thanks for reading!
I will use two labels for this design. The first label is for your original text, and the other one will show "Show All" or "Show Less".
The only one thing you have to do is to set the frame of the first label (original text).
The frame height for "Show All" could be calculated by line height (firstLabel.font.lineHeight)* number_of_lines_you_want. Remember to set the label property "numberOfLines" and "lineBreakMode" to "ByTruncatingTail".
The frame height for "Show Less" could be calculated by "sizeThatFits", which is supported by UILabel. The parameter "size" could be set to (frame.size.width, MAXFLOAT);
I don't familiar with swift, so I just describe what I will do with this design. Hope this helps!

Space characters being removed from end of String - UILabel Swift

I have the following code for a Table View Cell in Swift
let rcap = cell.viewWithTag(613) as! UILabel
rcap.text = "Capacity: \(room.capacity) " // I added space at the end
The space characters at the end of the string, are removed when shown on screen.
If I add space characters at the beginning of the string there is no issue.
At the moment I am using this 'full stop' hack, but it is not good enough:
rcap.text = "Capacity: \(room.capacity) ."
Any ideas?
I also tried:
rcap.text = "Capacity: \(room.capacity) " + " "
Adding a constraint to the label seems like the better solution to me.
It allows you to define a well-defined distance between the label and
the margin of the table view cell.
The width of a space is dependent on the font and might even change if the text in the label is shrunk, causing non-aligned texts in the
table view.
Having said that, you can prevent the trailing space from being
removed by appending a "ZERO WIDTH NON-JOINER" character (U+200C):
rcap.text = "Capacity: \(room.capacity) \u{200c}"
But I consider that more as a "trick" than the proper solution to the
problem.
Update: It seems that this "trick" does not work any more in iOS 10,
so a layout constraint should be used instead, as initially suggested.
For 2020
This issue is critical when working with monospaced fonts and doing layout, such as, say, user codes which may have alignment spaces at the end in monospace.
\u{200c} does seem to work perfectly:
Please note that the solution of #MartinR does in fact work perfectly, today, 2020 A.D., iOS 13, Xcode 11.
.text = "FATTIE KODE " + reservation + reservation.neededTrailingSpaces + \u{200c}"
.text = "FATTIE KODE " + reservation + reservation.neededTrailingSpaces + \u{200c}"
.text = "FATTIE KODE " + reservation + reservation.neededTrailingSpaces + \u{200c}"
You can now absolutely normally set font sizes, etc etc. and it all works properly.
Bonus code sample!
Here's a simple UILabel that pads it out, so you need do nothing else:
class PaddyLabel: UILabel {
// pad always to 20 characters...
override var text: String? {
get {
return super.text
}
set {
if newValue == nil {
super.text = nil
return
}
var t = newValue!
while t.count < 20 { t += " " }
t += "\u{200c}"
super.text = t
}
}
So in the above three yellow examples, you would just do this
.text = "FATTIE KODE " + reservation
and not have to bother adding the needed spaces manually.
Note that even if you are not using monospace fonts, a typical real-world use case is when you want to "pile together" UILabels - imagine them being, say, one word each - and have the absolutely correct space between them regardless of font size etc, that is to say as if it's just the one sentence in the one UILabel.
The only way to actually do that is to have UILabel "actually include the space".
If it does not work in a future iOS...
Perhaps this will (again?) break in a future iOS.
The only other solution I know is this. To begin with, it's ridiculously hard to just add padding to a UILabel. It is explained here:
Adding padding manually to a UILabel?
How to actually reliably add damned padding to a UILabel
In fact, using a similar technique, it would be possible to force the extra width on one end using intrinsicContentSize , drawText and textRect. To know how much width to add, you would have to calculate that using a phantom example text, with the number of characters in question. Doing that calculation would call for the usual annoying techniques for calculating likely text rendering size. But because that sucks, fortunately we can use the amazing tip of #MartinR (as usual!)
I have created custom class for UILabel, take a look:
import UIKit
#IBDesignable class CustomLable: UILabel {
#IBInspectable var topInset: CGFloat = 5.0
#IBInspectable var bottomInset: CGFloat = 5.0
#IBInspectable var leftInset: CGFloat = 7.0
#IBInspectable var rightInset: CGFloat = 7.0
override func drawText(in rect: CGRect) {
let insets = UIEdgeInsets.init(top: topInset, left: leftInset, bottom: bottomInset, right: rightInset)
super.drawText(in: rect.inset(by: insets))
}
override var intrinsicContentSize: CGSize {
let size = super.intrinsicContentSize
return CGSize(width: size.width + leftInset + rightInset,
height: size.height + topInset + bottomInset)
}
}
You can than assign a class to UILabel from Storyboard and provide space you need.
Try putting zero-width space instead of the period. It can be written using left Alt and 0173 on numeric keyboard. Or you can copy it here and delete the quotes: "­"
So your code for setting the text will look like this (with the zero-width space at the end):
rcap.text = "Capacity: \(room.capacity) ­"
Non-breaking space (\u{00a0}) should work too and its usage is as \u{200c}'s in Martin's and Fattie's answer
rcap.text = String.localizedStringWithFormat("Capacity: %# ", rrom.capacity)
try above code it may works

Resources