effectThe requirement is to intercept the display of the string 3/2 of the screen width over the display...
Hope to get your help, thank you!
if (meetModel.title.length > 18) {
title = [NSString stringWithFormat:#"%#...", [meetModel.title substringToIndex:18]];
} else {
title = meetModel.title;
}
This method does not meet my needs. The page display is in Chinese.
I didn't clearly understand your question, but I think you need to add something like this (the example is in Swift 3.1). The idea is that you should set the width constraint, and if the text larger than this width, it should be automatically truncated.
yourLabel.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.66).isActive = true
// It's needed for adding three dots in the end, if the string is larger then it should be
yourLabel.adjustsFontSizeToFitWidth = false
yourLabel.lineBreakMode = .byTruncatingTail
Related
I am encountering a strange behaviour when using UITextView with a long text. In particular, when setting the maximumNumberOfLines of its textContainer to 0, the content disappears completely.
I have created a small test project to be sure there was nothing strange in my code that was causing it, and you can see it in the screenshots. In my project I have a UIViewController that contains a UIScrollView, that contains a vertical UIStackView. The stack view contains a UITextView (the red title in the screenshots), another stackview containing a label, text view, button, and then other text views.
When the button is clicked I am setting maximumNumberOfLines to 0 (before it was 2), and the content just disappears. I've tried with and without animation and I have the same result.
The disappearing seems to be related to the height of the final text, as if I use a smaller font, the content disappears only after setting much more text.
Any ideas why it could be happening?
For completeness, I am using Xamarin.iOS, and here
is my ViewController.
The Content disappears because your text is too large for a UIView object to show. According to this post we know that, actually UIView has a maximum height and width limited by the amount of memory they consume.
In my test if we don't set too much characters to the textView(remove some textView.Text += textView.Text;), the content will show. And I also tested that on UILabel, so does it. Because they all inherit from UIView.
If you do want to show so many strings, try to enable the textView's ScrollEnabled. Do not let the textView's Bounds exceed the maximum limit. You can try to add the Height and Width Constraints when you want to expand the textView:
var textViewContraints = new NSLayoutConstraint[]
{
NSLayoutConstraint.Create(textView, NSLayoutAttribute.Height, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1f, 700),
NSLayoutConstraint.Create(textView, NSLayoutAttribute.Width, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1f, 500)
};
UIView.AnimateNotify(1.2d, () =>
{
if (!buttonExpanded)
{
textView.ScrollEnabled = true;
textView.TextContainer.MaximumNumberOfLines = 0;
textView.TextContainer.LineBreakMode = UILineBreakMode.WordWrap;
textView.SizeToFit();
textView.AddConstraints(textViewContraints);
expandButton.Transform = CGAffineTransform.MakeRotation((nfloat)(Math.PI / 2.0f));
textView.Text = "r" + textStr;
textView.Text = textView.Text.Substring(1);
}
else
{
textView.ScrollEnabled = false;
foreach (NSLayoutConstraint constraint in textView.Constraints)
{
textView.RemoveConstraint(constraint);
}
textView.TextContainer.MaximumNumberOfLines = 3;
textView.TextContainer.LineBreakMode = UILineBreakMode.WordWrap;
expandButton.Transform = CGAffineTransform.MakeRotation(0f);
textView.Text = textStr;
}
scrollView.LayoutIfNeeded();
buttonExpanded = !buttonExpanded;
}, null);
I'm trying to simulate a kind of "Please wait..." UILabel. The label's text must be regularly updated. So far everything works as expected. However, I need to get the intrinsic content height of the label to be able to position its container view (UIView).
The label is the one with the red background, whereas the one with the white background is its container.
I've tried a few different approaches, unfortunately, all in vain. Any help would be greatly appreciated.
private func createBusyLabel(labelText: String) -> CGFloat {
self.busyViewContainer.addSubview(self.busyLabel)
self.busyLabel.backgroundColor = UIColor.red
self.busyLabel.numberOfLines = 0
self.busyLabel.lineBreakMode = NSLineBreakMode.byWordWrapping
self.busyLabel.sizeToFit()
//set the constraints, but skip height constraints
self.busyLabel.translatesAutoresizingMaskIntoConstraints = false
self.busyLabel.horizontalLeft(toItem: self.busyViewContainer, constant: 60)
self.busyLabel.horizontalRight(toItem: self.busyViewContainer, constant: -10)
self.busyLabel.topConstraints(toItem: self.busyViewContainer, constant: 10)
self.busyLabel.text = labelText
//calculate height with margin
let height: CGFloat = self.busyLabel.intrinsicContentSize.height + 20
return height
}
Also, the line counting function, from a previously asked and already answered question, delivers only 1
Here is what it look like after I set the bottom constraint:
A million Thanks to ozgur, who changed my approach. Ozgur, your code works perfect, but unfortunately not for me, as I faced problems with bottomLayoutGuide part. The reason for this is that the label and its container are created in an external class.
Previously I tried to set bottom constraint to the label, which did not return the expected result. However, inspired by ozgur's answer, this time I simply set the bottom constraint to its container and not the label, giving in expected result, like following:
self.busyViewContainer.bottomConstraints(toItem: self.busyLabel, constant: 10)
Thanks to all who put in their precious efforts.
private func createBusyLabel(labelText: String) -> Void {
self.busyLabel.text = labelText
self.busyLabel.font = UIFont.getGlobalFont(size: _textSizeSmall, type: "bold")
self.busyLabel.backgroundColor = UIColor.red
// handle multiline problem
self.busyLabel.numberOfLines = 0
self.busyLabel.lineBreakMode = NSLineBreakMode.byWordWrapping
self.busyLabel.sizeToFit()
self.busyViewContainer.addSubview(self.busyLabel)
self.busyLabel.translatesAutoresizingMaskIntoConstraints = false
self.busyLabel.horizontalLeft(toItem: self.busyViewContainer, constant: 60)
self.busyLabel.horizontalRight(toItem: self.busyViewContainer, constant: -10)
self.busyLabel.topConstraints(toItem: self.busyViewContainer, constant: 10)
// the following line made the difference
self.busyViewContainer.bottomConstraints(toItem: self.busyLabel, constant: 10)
}
The simple fix is adding the bottom constraint between 'self.busyViewContainer' and its superview.
Following your code and syntax it can be something like this:
self.busyLabel.bottomConstraints(toItem: self.busyViewContainer, constant: 10)
It is a common problem with 'Unsatisfiable Constraints'. The autolayout should ensure it satisfies horizontal axis layout so it needs to have both top and bottom constraints in this case.
Apple doc - Unsatisfiable Constraints
Apple doc - Logical Errors
UPD: In this case, the layout of the superview can define a height with intrinsicContentSize:
var intrinsicContentSize: CGSize { return ... }
Where the height of the parent view will be calculated based on the label one.
I have multiple uitextfields setup and they are all connected with IBOutlets. I have one textfield that is a password and I have the 'Secure text Entry' selected. when I have this check I get this
Any ideas why this happens? If i deselect the secured entry the textfield rises fine depending on the size of the password with no ellipsis dots.
It does not matter how long the password is. Same thing.
If i don't have the security text selected it works fine
Any idea why? It can be a width issue because it does autosize. But why does the 'secure text entry' cause the issue?
I have faced the same problem. I think it is a bug of UITextfield. It calculates size for the text but not for the secure text(dots). I have the problem when the text includes slim characters like 1, l etc...
As workaround I have subclassed the UITextfield class and overridden intrinsicContentSize function. You might need to adjust letter spacing. I couldn't find how to get it dynamically depending on font.
override var intrinsicContentSize: CGSize {
let size = super.intrinsicContentSize
if !self.isSecureTextEntry {
return size
}
var width = size.width
if let font = self.font,
let charCount = self.text?.count {
width = "•".size(withAttributes: [NSAttributedString.Key.font : font]).width * CGFloat(charCount)
width += (CGFloat(charCount)+1) * 4.5 // this magic number is for letter spacing
}
return CGSize(width: width, height: size.height)
}
I want to make sure the button text fits into a UIButton, while the UIButton has a fixed size.
Of course I can access the titleLabel of the UIButton.
In a label I would set autoshrink to minimum font scale which seems to correspond to
self.myButton.titleLabel.adjustsFontSizeToFitWidth = YES;
, but doesn't really behave the same, since it only makes the text fits horizontally into the bounds, not vertically, thereby not changing the font size.
How can i actually adjust the font size of a label programmatically to make the text fit into the label bounds (as shown in Goal in the picture below) ?
I already tried
self.myButton.titleLabel.numberOfLines = 0;
self.myButton.titleLabel.minimumScaleFactor = 0.5f;
without success, always ended up as in adjustsFontSizeToFitWidth on the left side of the pic above.
Edit: The solution also has to be ios7 compliant
self.mybutton.titleLabel.minimumScaleFactor = 0.5f;
self.mybutton.titleLabel.numberOfLines = 0; <-- Or to desired number of lines
self.mybutton.titleLabel.adjustsFontSizeToFitWidth = YES;
... did the trick, after layoutIfNeeded in viewDidLoad
As it turns out, all those must be set to actually adjust the font-size, not just making it fit into the frame.
Update for Swift 3:
mybutton.titleLabel?.minimumScaleFactor = 0.5
mybutton.titleLabel?.numberOfLines = 0 <-- Or to desired number of lines
mybutton.titleLabel?.adjustsFontSizeToFitWidth = true
Updated code for Swift 3.0:
yourButton.titleLabel?.minimumScaleFactor = 0.5
yourButton.titleLabel?.numberOfLines = 0
yourButton.titleLabel?.adjustsFontSizeToFitWidth = true
You can also set a User Defined Runtime Attribute in Interface Builder for the button where
titleLabel.adjustsFontSizeToFitWidth = true
to make text horizontally and vertically fit with button bounds :
1 - set button alignment like image (* VERY IMPORTANT *)
2 - add this lines of code in your ViewController
btnTest.setTitle("Test for multi line in button show line in button show Test for multi line in button show line in button show", for: .normal)
btnTest.titleLabel!.textAlignment = .center
btnTest.titleLabel!.numberOfLines = 0
btnTest.titleLabel!.adjustsFontSizeToFitWidth = true
btnTest.titleLabel!.minimumScaleFactor = 0.5
// below line to add some inset for text to look better
// you can delete or change that
btnTest.contentEdgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
note that DON'T using btnTest.titleLabel!.lineBreakMode = NSLineBreakMode.byWordWrapping or other BreakMode in your code . for enable multiline in button . just using from above code
final result :
Try to call the following method.
button.titleLabel?.baselineAdjustment = UIBaselineAdjustment.AlignCenters
try this:
[myButton setFont:[[myButton font] fontWithSize:--originalButtonFontSize]];
textWidth = [text sizeWithFont:[myButton font]].width;
}
In Storyboard, Go to Link Break in Attributes Inspector, see word wrap..or set according to your choice.
In Xcode->Open storyboard->Go to attributes inspector->Control->Alignment->Choose second in both horizontal and vertical.
or
YourButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
If you prefer do in storyboard, just click the button, then show attributes inspector, and set the line break to "Word Wrap".
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!