How to use sizeThatFits in Swift? - ios

I have got a text view and a view like this
let lb = UITextView()
let view = UIView()
background_img_view.addSubview(about_txt)
lb doesn't have fixed height,it can be 30 or 300px,how can i use sizeThatFits to make background_img_view's height depend on lb's?

Try this:
// Get the width you want to fit
let fixedWidth = textView.frame.size.width
// Calculate the biggest size that fixes in the given CGSize
let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
// Set the textView's size to be whatever is bigger: The fitted width or the fixedWidth
textView.frame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
// Make the "background_img_view" height match the textView's height
background_img_view.frame.size.height = textView.frame.size.height

Related

How to get the content Height of dynamically changing Text in textview?

I have a dynamically changing text in TextView.I could not be able to get the content Height of TextView.
Here is what i tried.
let height = self.tvComment.contentSize.height
print("height",height)
let contentSizeComment = self.tvComment.sizeThatFits(self.tvComment.bounds.size)
print("height",contentSizeComment)
Why it's not getting the content height of TextView?
Hope you understand my problem.
Thanks in Advance
Usethis method to get the height -
func heightForString(text:String, font:UIFont, width:CGFloat) -> CGFloat{
let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude))
label.numberOfLines = 0
label.lineBreakMode = NSLineBreakMode.byWordWrapping
label.font = font
label.text = text
label.sizeToFit()
return label.frame.size.height
}
in textdidchange you can use this code,in order to resize when textchange
//approxi should be the width of your textview
let approxi = view.frame.width - 90
//size is the max width and height of textview,1000 can be what ever you want
let size = CGSize(width: approxi, height: 1000)
//dont forget to put your font and size
//chey is the text of thetext view
let attributes = [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 15)]
let estim = NSString(string: chey).boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: attributes, context: nil)
//estim is height
above it the first method,second method will come in edit
second method is
func pva() {
//what was the name of my textfield
let fixedwidth = what.frame.size.width - 40
let newsize = what.contentSize.height
self.hrightext.constant = newsize
self.view.layoutIfNeeded()
}
note: both are tested and works in swift4
Your just write code in below delegate of UITextView:-
func textViewDidChange(_ textView: UITextView!) {
let height = self.tvComment.contentSize.height
print("height",height)
let contentSizeComment = self.tvComment.sizeThatFits(self.tvComment.bounds.size)
print("height",contentSizeComment)
}
I hope it help you,
Thank you.

How can I make a TextField width adapt to his content?

Is there any option that make a TextField adapt to his content?
There is a way to do it manually by adjusting the frame of the textview when a change in it occurs.
var text: String = "Some text is just here..."
let size: CGSize = text.size(attributes: [NSFontAttributeName: UIFont.systemFont(ofSize: 14.0)])
^The code will give you the size needed for the text to be fully displayed and you can resize you textView according to it. //be aware there might be some paddings inside the textview
extension String {
func heightWithConstrainedWidth(width: CGFloat, font: UIFont) -> CGFloat {
let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)
return boundingBox.height
}
}
^If you need dynamic height (multi-lines) constraining the width will help you with the task.
I'm not completely sure what you are trying to accomplish, but I hope this helps a little.
Create a oultet for height constraint of textview. After:
textView.delegate = self
textView.isScrollEnabled = false
func textViewDidChange(_ textView: UITextView) {
let fixedWidth = textView.frame.size.width
textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
var newFrame = textView.frame
newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
heightTextview.constant = newFrame.size.height //update constraint constant with new height
}
textView will change height for fit multiple line content. It works well

How to size a UITextView's height along with the container that it is in?

I'm trying to make a text messaging text box that makes the text view bigger and the UIView (in which the text view is contained) bigger as well. I'm working with constraints. When I reach a certain height, I want it to scroll and stop increasing the heights of the container. I've tried all ways possible, including using this forum (How do I size a UITextView to its content?).
One problem occurs when I type it in, once I reach a certain height, it starts typing out of sight below.
func textViewDidChange(textView: UITextView) {
let fixedWidth = self.chatTextField.frame.size.width
self.chatTextField.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.max))
let newSize = self.chatTextField.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.max))
var newFrame = self.chatTextField.frame
newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
print(textViewAnchorHeight?.constant)
if textView.contentSize.height <= self.chatTextFieldHeightAnchor?.constant {
textView.scrollEnabled = false
self.chatTextField.frame = newFrame
//self.chatTextFieldHeightAnchor?.constant = newSize.height
self.textViewAnchorHeight?.constant = newSize.height
} else {
textView.scrollEnabled = true
self.automaticallyAdjustsScrollViewInsets = true
print("here")
}
What can I do to make the perfect text view?
You can use the code below to achive that dynamic resize. You might want to change differenceOfHeightvalue to your liking.
func textViewDidChange(textView: UITextView) {
var newFrame = textView.frame
var minHeight = 40 // ENTER THE MIN HEIGHT OR THE INITIAL HEIGHT OF THE TEXTVIEW
var maxHeight = 100 // ENTER THE MAX HEIGHT YOU WANT
newFrame.size = textView.sizeThatFits(CGSizeMake(newFrame.size.width, maxHeight))
if newFrame.size.height > minHeight && newFrame.size.height < maxHeight {
let differenceOfHeight = newFrame.size.height - textView.frame.size.height
holderView.frame = CGRectMake(holderView.frame.origin.x, holderView.frame.origin.y - differenceOfHeight, holderView.frame.size.width, newFrame.size.height)
textView.frame = newFrame
}
}

UITextView Changing Size Dynamically

I am using the following code to dynamically adjust the height of the containerView which contains my UITextView
func textViewDidChange(textView: UITextView) {
let amountOfLinesToBeShown:CGFloat = 6
let maxHeight:CGFloat = textView.font!.lineHeight * amountOfLinesToBeShown
if ((textView.contentSize.height / textView.font!.lineHeight) < 6) {
topConstraint?.constant = -textView.sizeThatFits(CGSizeMake(textView.frame.size.width, maxHeight)).height - keyboardFrameSize!.height
containerView.layoutIfNeeded()
containerView.updateConstraints()
}
}
The problem is, when I am typing, it appears like this:
and the desired effect is this:
The top answer from this post solves this issue. How do I size a UITextView to its content?
The code below is not mine, it is from the answer linked above (simply posting for other's convenience):
let fixedWidth = textView.frame.size.width
textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.max))
let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height:CGFloat.max))
var newFrame = textView.frame
newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
textView.frame = newFrame;
The code below might be the solution for this problem you got.
func textViewDidChange(textView: UITextView) {
var newFrame = textView.frame
var minHeight = 40 // ENTER THE MIN HEIGHT OR THE INITIAL HEIGHT OF THE TEXTVIEW
var maxHeight = 100 // ENTER THE MAX HEIGHT YOU WANT
newFrame.size = textView.sizeThatFits(CGSizeMake(newFrame.size.width, maxHeight))
if newFrame.size.height > minHeight && newFrame.size.height < maxHeight {
// Change the origin.y value which is 10 to your desired margin for top.
textView.frame = CGRectMake(0, 10, textView.frame.size.width, newFrame.size.height)
}
}
Create a function and add this in your viewDidLoad method, try with:
self.addSubview(containerView)
containerView.addSubview(textView)
containerView.bottomAnchor.constraintEqualToAnchor(self.bottomAnchor).active=true
containerView.leftAnchor.constraintEqualToAnchor(self.leftAnchor).active=true
textView.topAnchor.constraintEqualToAnchor(containerView.topAnchor, constant: 3).active=true
textView.leftAnchor.constraintEqualToAnchor(containerView.leftAnchor, constant: 3).active=true
textView.widthAnchor.constraintEqualToAnchor(containerView.widthAnchor).active=true
textView.heightAnchor.constraintEqualToAnchor(containerView.heightAnchor).active=true
use textview textContainerInset method for achieving what u want
//insets are top, left, bottom, top..
tv.textContainerInset = UIEdgeInsetsMake(0,0,0,0);
after setting this method,when textview line starts, increase height of textview for finding the textview next line start,
use method:- TextViewDidChange

Swift: how to get the correct String size

I want to calculate the size of a string, to resize a UILabel. I used three different ways to calculate the size, to be exact, two ways. But I got three different results, and totally confused.
The most confusing thing is that I created a UILabel and use sizeToFit() to get the size. then I use the size to create a real UILabel and display it, but the label is truncated. Then I use sizeToFit() again to adjust the real UILabel, and the size is larger.
I doubted if it's caused by scale differences. But it is still three results on different simulators/devices.
Here's my code:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let items = ["connected devices", "join session", "start host"]
let font = UIFont.systemFontOfSize(16)
var i = 0
for item in items {
let size = item.size(font: font)
print("\(size)")
let attriSize = item.sizeWithAttributes([NSFontAttributeName:font])
print("attriSize\(attriSize)")
let label = UILabel(frame: CGRect(origin: CGPoint(x: 50, y: 50 + i*50), size: size))
label.text = item
label.backgroundColor = UIColor.redColor()
label.sizeToFit()
print("\(label.bounds.size)")
view.addSubview(label)
++i
print("\n")
}
}
}
extension String {
func size(font font: UIFont) -> CGSize {
let label = UILabel(frame: CGRectZero)
label.text = self
label.font = font
label.sizeToFit()
let size = label.bounds.size
return size
}
}
and the results are
(137.333333333333, 19.3333333333333)
attriSize(137.0859375, 19.09375)
(144.666666666667, 20.3333333333333)
(84.3333333333333, 19.3333333333333)
attriSize(84.265625, 19.09375)
(89.0, 20.3333333333333)
(70.0, 19.3333333333333)
attriSize(69.765625, 19.09375)
(73.6666666666667, 20.3333333333333)
I really want to know what's wrong with sizeToFit(). Any help is appreciated.
Hi it is working example that can help you :
let fixedWidth = textView.frame.size.width
textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.max))
let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.max))
var newFrame = textView.frame
newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
textView.frame = newFrame;

Resources