Dynamically adjust the height of the UITextView depending on its content? [duplicate] - ios

This question already has answers here:
How do I size a UITextView to its content?
(41 answers)
Closed 7 years ago.
I have an UITextView that loads different text depending on the route the user has taken in order to get to the view with the text on it.
How do I dynamically adjust the height of the UITextView depending on its content using Swift?

Setup your constraints so that the edges are pinned but allow the text view to grow vertically. Then set a height constraint (the value doesn't matter here). Create an #IBOutlet for the UITextView and the height constraint. Then we can dynamically change the height in code:
class ViewControler: UIViewController, UITextViewDelegate {
#IBOutlet weak var textView: UITextView!
#IBOutlet weak var textViewHeight: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
self.textView.delegate = self
}
func textViewDidChange(textView: UITextView) {
let sizeToFitIn = CGSizeMake(self.textView.bounds.size.width, CGFloat(MAXFLOAT))
let newSize = self.textView.sizeThatFits(sizeToFitIn)
self.textViewHeight.constant = newSize.height
}
}

Related

autoResizingMask for inputAccessoryView not working

I'm trying to cope with iPhone X with inputAccessoryView. I've added a view to my ViewController like so:
CustomView
I've defined an outlet and attached to it. Returned the same view as inputAccessoryView like so:
class ViewController: UIViewController {
#IBOutlet weak var textFieldContainer: UIView!
override var inputAccessoryView: UIView? {
return textFieldContainer
}
override var canBecomeFirstResponder: Bool {
return true
}
override func viewDidLoad() {
super.viewDidLoad()
textFieldContainer.autoresizesSubviews = true
}
}
I've made sure to add constraints relative to safe area. Here are my constraints:
Constraints
Adjusted autoResizingMask in SB like so:
AutoResizingMask
However, it's still not working. Here's the output:
Output
What did I miss?
Unlike for table view cells, there is no support for dynamic height calculation in input accessory views, as far as I know.
You could use a fixed height for the accessory view.
But I assume, that you want just to change either top, bottom, or height constraint in interface builder and the change is reflected after the next build.
What you could do is, to use a custom view class where you connect your top, bottom and height constraints.
Then override intrinsicContentSize and return the sum of the three constraint constants.
class TextFieldContainer: UIView {
#IBOutlet weak var topConstraint: NSLayoutConstraint!
#IBOutlet weak var bottomConstraint: NSLayoutConstraint!
#IBOutlet weak var heightConstraint: NSLayoutConstraint!
override var intrinsicContentSize: CGSize {
let contentHeight =
self.topConstraint.constant
+ self.heightConstraint.constant
+ self.bottomConstraint.constant
return CGSize(width: UIScreen.main.bounds.width, height: contentHeight)
}
}
Your layout hierarchy could be simplified and look like this:
The autoresizing mask could look like this:
The final result would behave like the following then:
You're giving textfield height and also bottom constraint, try to remove bottom constraint for textfield

Scrollview just show my last array's element in view which i create with storyboard in swift 3?

I want to add a few view in scrollview. But I dont want to this view programmatically. I want to create with storyboard. This view include an image. I added scrollview and added to view. But in scrollview I just showing my last view. I want to 2 view and 2 image like my view. How can i fix this?
This is my code:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var mainScrollView: UIScrollView!
var imageArray = [UIImage]()
#IBOutlet weak var myView: UIView!
#IBOutlet weak var imgv: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
imageArray = ["image","image2"]
for i in 0..<imageArray.count{
mainScrollView.contentSize.width = mainScrollView.frame.width * CGFloat(i + 1)
myView.layer.frame.size.width = myView.frame.width * CGFloat(i + 1)
imgv.image = imageArray[i]
mainScrollView.addSubview(myView)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
This is storyboard and controller looks like
You are having an issue with constraints from what I see and that is why you might not see every element that you put on your storyboard. You need to correct those errors for everything to show up correctly in your scrollview. Keep in mind, you need to tell the scrollview what its height and width should be in the storyboard. They need to be defined in some way. This is a common mistake when working with scrollviews.
You can put a view in your scrollview and define its height and width property. You can set its width to be equal to the screen's width and you can set a constant for your height.

Dynamic UITextView mislocation behavior

I am trying to have a textview similar to iPhone messages, where the textview initially has a constraint (height <= 100) and the scrollEnabled = false
This is a link to the project:
https://github.com/akawther/TextView
The text view increases in height based on the content size as in the image on the left until it reaches the height of 100, then the scrollEnabled is set to true. It works perfectly until I click the "send" button on the lower right where the textView should become empty and go back to the original height and scrollEnabled becomes false. The middle image shows what happens when I click the button. When I start typing the textview moves down as you see in the last image on the right.
I want to be able to click the button and eliminate the behavior shown on the middle image, how can I fix this?
import UIKit
class ViewController: UIViewController, UITextViewDelegate {
#IBOutlet weak var bottomConstraint: NSLayoutConstraint!
#IBOutlet weak var messageTextView: UITextView!
#IBOutlet weak var parent: UIView!
let messageTextViewMaxHeight: CGFloat = 100
override func viewDidLoad() {
super.viewDidLoad()
self.messageTextView.delegate = self
}
#IBAction func Reset(sender: AnyObject) {
messageTextView.text = ""
messageTextView.frame.size.height = messageTextView.contentSize.height
messageTextView.scrollEnabled = false
self.parent.layoutIfNeeded()
}
func textViewDidChange(textView: UITextView) {
if textView.frame.size.height >= self.messageTextViewMaxHeight {
textView.scrollEnabled = true
} else {
textView.scrollEnabled = false
textView.frame.size.height = textView.contentSize.height
}
}
}
You can replicate my issue by following these steps in the github project:
1. keep typing words and pressing enters until you start seeing the scroll
2. Click the button you will see that the textview goes up in the blue
container. This is the issue I want to eliminate!
Try bellow code :-
#IBAction func Reset(sender: AnyObject) {
messageTextView.scrollEnabled = false
messageTextView.text = ""
messageTextView.frame.size.height = messageTextView.contentSize.height
parent.frame.size.height = 20
self.view.layoutIfNeeded()
}
func textViewDidChange(textView: UITextView) {
if textView.contentSize.height >= self.messageTextViewMaxHeight {
textView.scrollEnabled = true
} else {
textView.frame.size.height = textView.contentSize.height
textView.scrollEnabled = false
}
}
Your issue is that the UITextView has conflicting properties:
Place on the screen
Size
The size being constrained will cause an issue when you need a resizable TextView. Also, when the TextView is resized, its location is being changed in this case.
Alternate method to approach the issue:
Try setting constraints to its location in relation to the bottom of the screen. When the Keyboard appears, you should move the TextView up with it. Also setting constraints on the height of a resizable TextView is bad practice unless you are planning on forcing the user to scroll.
Hope this helps.
If you are using auto layout, you should be updating to constraint instead of updating the textView.frame.Try create a IBOutlet for your textView heightConstraint then set the updated height to it.
IBOutlet weak var textViewHeightConstraint: NSLayoutConstraint!
//calculate the height and update the constant
textViewHeightConstraint.constant = textView.contentSize.height

Animate automatic UILabel text size change [duplicate]

This question already has answers here:
Animating UILabel Font Size Change
(9 answers)
Closed 6 years ago.
I have set my UILabel to scale text automatically to fit within the labels frame. During runtime I am changing the size of this frame to make space for things underneath, but I really want the size change to be animated, since the text jumps from one size to a smaller one, which doesn't look very good.
Is there any way to accomplish this?
To animate the height change use UIView.animateWithDuration. Here's an example animating the height change of a UILabel with a 2 second duration:
#IBOutlet weak var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
let updatedHeight: CGFloat = 100.0
let updatedFrame = CGRect(origin:label.frame.origin,
size: CGSize(width:label.frame.width, height: updatedHeight))
UIView.animateWithDuration(2.0, animations: {
self.label.frame = updatedFrame
})
}

Set max lines to 3 and adjust height according to label content

I've created a label in a tableViewCell which contain a string of text. The size of the string can vary however it should maximum be 3 lines. However i can't seem to do this? What is the easiest way to create such a functionality in this label so far i've just created this label in my tableViewCell Subclass.
#IBOutlet weak var dummyLabel: UILabel!
In your custom UITableViewCell class add this:
override func layoutSubviews() {
super.layoutSubviews()
dummyLabel.sizeToFit()
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
dummyLabel.numberOfLines = 3
}
Similar post here about label resize in UITableViewCell: Swift : align UILabel text in the top rather in the middle

Resources