UITableView blank space not working? - ios

so I was trying to align the text in UITableView using.
cell.textLabel?.text = sometext
I have two part in sometext first part is words, second part is number, such as "apple 45" "pear 23", "banana 34"so when they are showing in tableview cell, I want the left side of the words align with each other and the left side the number align with each other. and I can not post a picture here.
so according to the first part word length I added some blank space in the string by appending
let appStr = String(count: 22-cnt, repeatedValue: ( " " as Character))
print("append string is" + appStr + "end")
nameHere = name + appStr + number
I printed out to console in the program and it works fine, but when showing in the simulator it is not aligned.

Don't attempt to align numbers using spaces. Set the label's attributedText, not its text, and use the fact that an NSAttributedString can have tab stops to perform the alignment.

Related

How to make multi-line UILabel text fit within predefined width without wrapping mid-word

I have a UILabel carefully laid out in Interface Builder with proper height and width constraints. The number of lines is set to 4. The wrapping is set to word wrap. The text is "CHECKED". The font size is very large and thus it only fits "CHECKE" and the "D" is on the second line. Writing "Checked" instead of "CHECKED" lets the font shrink (as intended) so that the whole word fits. But (the text is user given and it can be expected that the user writes fully uppercase words) having uppercase words the label does not break it/shrink the font as expected.
Do you have a suggestion as to what I might have missed? Capitalising the words (thusly only having the first letter uppercase) does work, but is not what the client wants.
Updated question
The problem seems to be unrelated to having uppercase or lowercase text. My problem could be solved by an answer to the following question:
How to make (ideally with the help of only Interface Builder) the UILabel text shrink trying to fit full words within all available lines without wrapping the text mid-word?
If the text "CHECKED" is too wide for a label (with more than 1 line available) it should shrink the font size instead of breaking the "D" and wrapping the single letter to the next line.
If the text is "one CHECKED two" and the single word "CHECKED" is already too wide for a label (with more than 1 line available) it should break between all words and shrinking the font size so that "CHECKED" still fits the middle line.
Avoiding:
one
CHECKE
D two
Thank you very much!
Here is a UILabel subclass that will find the largest word in the labels text, use the boundingRect function of NSString to see how large that one word will be with the current font, and drop the font size until it fits the width.
class AutosizingMultilineLabel: UILabel {
override func layoutSubviews() {
super.layoutSubviews()
self.adjustFontToFitWidth()
}
func adjustFontToFitWidth() {
guard let currentFont = self.font else { return }
let minimumFontSize: CGFloat = floor(self.minimumScaleFactor * currentFont.pointSize)
var newFontSize = currentFont.pointSize
var theNewFont = currentFont
if let text = self.text, let longestWord = text.components(separatedBy: " ").max(by: {$1.count > $0.count})?.replacingOccurrences(of: "\n", with: "") {
let nsString = longestWord as NSString
while newFontSize > minimumFontSize {
theNewFont = currentFont.withSize(newFontSize)
let boundingRect = nsString.boundingRect(with: CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude),
options: NSStringDrawingOptions.usesLineFragmentOrigin,
attributes: [.font: theNewFont],
context: nil)
if ceil(boundingRect.size.width) <= self.bounds.size.width {
break
}
newFontSize -= 1
}
self.font = theNewFont
}
}
}
When the word is bigger than the line, word wrap doesn't work. If it doesn't fit on this line, it won't fit on the next line. (same word, same size, same line size). To make it fit, the label will start putting letters on the next line.
If you allow multiple lines on your label, the OS will try to fill the lines before adjusting the font size.
I think you're just running into a limitation on Autoshrink.
In Interface Builder:
add a new UILabel with Width: 230 and Height: 280
set the Font to System 44.0
set Line Break: Truncate Tail
set Autoshrink: Minimum Font Scale at 0.15
set the text of the label to test CHECKED lines
Now, drag the handle on the right edge of the label left and right... when it gets too narrow, the word CHECKED will break onto the next line.
Change CHECKED to checked and do the same thing. You should see the same behavior.
Now, try dragging the Bottom edge up and down. With either CHECKED or checked, you should see the Font Size auto shrink.
So... to do what you're trying to do, you might have to skip Autoshrink and instead do some code calculations.
Edit: further visual of what goes on...
Start with above values, but set the Height of the label to 170 - gives it just a little vertical padding.
Now, drag the left edge to make it narrower.
When you reach the end of the word CHECKED, and keep going, you will see the font shrink until it gets small enough that there is space for it to wrap to a 4th line.
I think you're going to need some code to get exactly what you need.

UINavigationItem title truncation

I have text that is built from two Strings:
A(B)
I want to use both strings as the title for the UINavigationItem but in case of truncation I want only A to be truncated and not B.
Example:
The title I want is "The quick brown fox jumps (over the lazy dog)".
The screen size is too small so the title truncates and it is now "The quick brown fox jumps (over...".
What I want it to be is: "The quick br... (over the lazy dog)"
How can I do that?
First check number of characters navigation bar allowing as title without truncating. Next, before setting title check whether the total string length is less than those number of characters or not. Now based on condition set either combined string or B only.
Since xcode won't be able to detect in which part of your title you want to stop and which part you want to start again, you need to do it yourself.
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.title = "Heal the world make it a better place for you and for me and the entire human race"
setNavTitle(title: self.navigationItem.title!)
}
func setNavTitle(title: String)
{
//get the last 10 characters of your title, change the number to your need
let last10 = title.substring(from:title.index(title.endIndex, offsetBy: -14))
//get the first 10 characters of your title, change the number to your need
let first10 = title.substring(to: title.index(title.startIndex, offsetBy: 14))
//concatenate the strings
let title = first10 + " ... " + last10
self.navigationItem.title = title
}

Align UILabel text to a specific character

I'm using a UILaber showing a second countdown in a very large font (size 240). The displayed string is formatted "xxx.xx", with x's being characters 0-9. I want to align the text to the dot-chatecter (.) in the string that showing in the label. I use textAlignment as .Center in the label, but some strings differ in actual displayed length, causing the dot-character to be shifted left and right when the string is updated. F.x. the textContainer for a "1" is smaller than an "8".
Is it possible to do this kind of character allignment?
Interesting Question mate:
Please find a solution below:
Basically what i've done here is:
Using Storyboard i've taken 3 Vertical Stack Views inside a Horizontal Stack View.
Just center align the second vertical stack view with static width and other stack views will adjust accordingly.
Rest you can follow the screenshot attached for constraints.
No constraints required for labels, just text align according to your need.
Cheers!
let attributedStringOne = NSAttributedString.init(string: "XXX", attributes: [NSAttributedStringKey.baselineOffset: 0])
let attributedStringTwo = NSAttributedString.init(string: ".", attributes: [NSAttributedStringKey.baselineOffset: label.frame.height / 4])
let attributedText = NSMutableAttributedString.init()
attributedText.append(attributedStringOne)
attributedText.append(attributedStringTwo)
label.attributedText = attributedText
baselineOffset is NSNumber type. So you can set how much you want from baseline.
attach three labels together..
label1|labelDot|label2 which will be matching your XX.XXX
right align your label1, fix your labelDot, left align your label2

UILabel with 2 lines, how to truncate each line independently?

I'm trying to display a UILabel with 2 lines with something like this:
"Here is the first line (a long one) and that's it"
"And this is the second line with random number of chars"
With Truncate Tail it displays this:
"Here is the first line (a long one) and that's ..."
My goal is to display:
"Here is the first line (a long .."
"And this is the second line wit.."
Is there a way to do this with UILabel set to 2 lines and without using 2 UILabel's ?
Split the string on \n to create two strings. Then create 2 UILabels set to numberOfLines = 1 and lineBreakMode = .ByTruncatingTail. Lay them out in the view, one on top of the other.
First, you need to set the numbers of lines to 0(infinite number of lines);
textLabel.numberOfLines = 0;
Next, you can break wherever you want by doing this:
textLabel.text = "str1 \n str2"

UITextView increment character to the left

I have a UITextView that has a fixed width and height. I pre-populate the entire textfield with blanks.
I would like to insert a character with the push of a button that will erase the last blank character, insert my string character and then place the cursor at the beginning of the newly inserted string. I am trying to achieve inserting special fonts right to left and bottom to top.
It is working with the first button push and on the second button push the new value is inserted in the correct position to the left, however, the cursor will not move to the left after the second button push, it remains to the right after the second string insert.
Here is my code...
-(IBAction)chartP:(id)sender {
NSRange currentRange = myChart.selectedRange;
if (currentRange.length == 0) {
currentRange.location--;
currentRange.length++;
}
myChart.text = [myChart.text stringByReplacingCharactersInRange:currentRange
withString:[NSString string]];
currentRange.length = 0;
myChart.selectedRange = currentRange;
myChart.text = [myChart.text stringByAppendingString:#"p"];
myChart.selectedRange = NSMakeRange(myChart.selectedRange.location -1, 0);
}
Can someone assist me with what I am missing here to continually increment to the left with my string inserts?
How about flipping the text area:
myChart.transform = CGAffineTransformMakeScale(-1,-1);
It sounds like you are trying to implement right-to-left text direction by faking it. Why not do the real thing?
Here's a question that covers the topic:
Change the UITextView Text Direction
If you need bottom-to-top entry, and you have the ability to use a custom font, perhaps you can apply a transformation to the UITextView and y-flip it. Look at the transform property of UIView. (Things like the text selection loupe may break, but it's worth a try.)

Resources