JSQMessagesViewController Custom Cell Auto layout Issue - IOS - ios

I am using JSQMessagesViewController and I created a custom cell according to this answer.
How to add custom view to JSQMessagesViewController cell so that it includes one view with some buttons and text view?
Now I am struggling to set auto layout constrains correctly. So, the message bubble not display correctly. Please help me set the constraints correctly

So lets take a stab at this. So first things that I would do it set a constraint for the first button to be equal hight of the other. You can accomplish a couple of ways but I will only describe one here for brevity. You can do hold the control button on your computer and select button1 and drag to button2. This will present you with a couple of options that look like this.
You want to select Equal Heights this will make it so both your buttons have the same hight. Then you will want to give it a hight. Once again hold down the control button on your keyboard but this time click button1 drag and release within button1. you should get something along the lines of this.
If you do not get the desired options try dragging in a diagonal direction. Xcode is tying to guess what constraints you want based on the direction of your drag. I.E. If you drag vertically you should get the Height option.
Then you can go to the properties inspector on the right and set a number for how high you would like. Text is normally around 12pt so I would go with about 30pt or more for the hight of a button. Then add a constraint for spacing between them and leading and trailing to the containing view or you could give them a standard width and center them in the view. Which ever fits best for you.
Edit:
You should also adjust the bubble size calculation.
It can be found in the JSQMessagesBubblesSizeCalculator class.
Eg: In the
- (CGSize)messageBubbleSizeForMessageData {
if([messageData isOptionMessage]){
// add button height also (In this case i have set constant 200. But we have to calculate the actual button heights instead)
finalSize = CGSizeMake(finalWidth, stringSize.height + verticalInsets + 200)
} else {
finalSize = CGSizeMake(finalWidth, stringSize.height + verticalInsets)
}
}
Let me know if you need any more help and keep up the good work. 👍🏼 🚜

Related

Find height of UILabel when number of lines increases/decreases dynamically

I am trying to find the height/space occupied by an UILabel on the screen programmatically whose number of lines increases or decreases based on different devices and string internalization. So I tried to get the height of the UILable by the following method.
uiLable.bounds.size.height/ uilable.frames.size.height
This method was implemented in both viewDidAppear and viewDidLoad methods. In both methods, the height returned is same on all devices and when the number of lines increases/decreases. Please find the screenshot of the UI that I have. I have to align the switch button to the centre of both text (Remember for all meetings and These can be changed in settings).
Any help would be appreciated. Thanks in Advance
After updating the text in your label you can force the layout system to update its UI and then get the correct bounds of your label.
// set your label text
label.text = "multiline text here"
// Now force layout system to update its UI instantly
self.view.setNeedsLayout()
self.view.layoutIfNeeded()
// Now you will get the correct bounds
let bounds = label.bounds
I am trying to find the height/space occupied by an UILabel on the screen programmatically whose number of lines increases or decreases based on different devices and string internalization.
Do not try to do that. You have no reason to want to know it.
Please find the screenshot of the UI that I have. I have to align the switch button to the centre of both text
Then align it with auto layout. That is exactly what it is for. Let the runtime take care of the problem for you. You cannot possibly internationalize successfully without using auto layout to take care of this sort of thing.
You can place both the label in a single view and set autolayout as verticalCenter of view is equal to vertical center of toggle button.

Dynamic scrollView size for variable content

I stand in front of a new problem for me. I have the following layout in my storyboard.
In this Layout you see a scrollView that have always the same content on top and some boxes at the bottom. These boxes should be variable, so I want some of them turned off and some turned on. I already tried to say something like mapBox.hidden = true or mapBox.removeFromSuperview().
The problem with that is if I do that the box is hidden, but the space of it is always there, because of the constraints I think.
I already done it on Android, there you can give them boxes just a margin and when you make dem hidden the following box have just its margin to whatever was on top of the hidden box.
What I want is the possibility to turn some of the boxes on and off with always the same distance between all not hidden boxes and a scrollview thats just big as its content.
I hope you can read my maybe unintelligible english and can give me a hint.
What you could do here instead: Make the whole layout a table view. Then, the top part (that always stays the same) could be added as the table header. The mapbox and headline boxes would both be table cells (use custom XIB files). Then, you can have one array that represents which boxes, along with which other cells you would like to display, and update that array depending on the situation. A Table view will adjust the size of its scroll view based on the size of content.
You probably know that the big issue here is the basic design. As #IanRichard said, this should be done using a table view. However you still can make some workarounds if there's no other way out.
You can set the constraints in such way so that an "undesired" view gets hidden. Here's an example for textBox and mapBox, but can use the same for all boxes:
You probably have one constraint connecting the bottom of the textBox and the top of the mapBox, and the priority is probably 1000. Change this priority to 999. Then add one more constraint connecting the TOP of the textBox and TOP of the mapBox. Set the priority to 1 and constant to 0. Next, in the same way as you were making outlet connections for other view elements, make two more outlet connections for this both constraints. You'll need them later when you will switch the priorities.
Here's how your outlets should look like:
IBOutlet var myConstraintBotTop : NSLayoutConstraint!
IBOutlet var myConstraintTopTop : NSLayoutConstraint!
Then in your code you can "turn your views off" by just setting the appropriate constraints:
func turnOffMyBox() {
myConstraintBotTop.priority = 1
myConstraintTopTop.priority = 999
}
And here's the inverted version for "turn on" in case you need it:
func turnOffMyBox() {
myConstraintBotTop.priority = 999
myConstraintTopTop.priority = 1
}
Note: this approach works by just overlapping your boxes. Those boxes still exists. You may want to hide them to prevent from being seen by the user.

UITableView, CollectionView or AutoLayout?

I was using the Uber app last time, and their button group (Paypal, Price Estimate, Promo Code) looked good - Lyft has the same design - and I was wondering how could I achieve the same result in my app ?
I already tried Layout. I think there's a quicker solution using TableView or CollectionView maybe ? it looks more like a TableView but I don't know how could I put 1 plain row, and then have a row with 2 buttons ...
In my storyboard I have the above. But I cannot "stick" the 2 buttons to my label, there is a guide-line which block me just below the label.
Hope I was clear enough and in advance sorry for the "No code post".
Thanks for your help !
You should do this using UIStackView. This needs iOS 9 as target. If you are on a lower version, you can use TZSTackView
Even if you use a tableView the autoLayout is required. So try resolving the autoLayout issues.
place the buttons alongside
provide the following constraints
Button 1:
leading: superview
top: label (set suitable distance)
trailing: button 2
aspectRatio
Button 2:
top: label (same distance as button 1)
trailing: superview
aspectRatio
Also select both the buttons and set equalWidths. Now Update Frames and you are good to go.
simply use TableView with custom tableview cell by putting uilabel on the top and uibuttons below and set the constraints using size inspector > Autoresizing ..
Its easy just follow these steps.
use tableview for this.
1.take 2 views First for your top stuff and second for button.
2.add constraint on 1st view.
2.1 add top,leading,trailing and give equal width to the context view and change the multiplier to 0.5;
3.add constraint on Second view leading ,trailing and bottom and top to first view.
3.1 add button inside second view and give leading ,top , bottom and equal width to parent view and change multiplier to 0.5.
3.2 add second button and put top,bottom ,trailing and horizontal spacing to first button to zero.

UIScrollView and variable text size

I'm creating an app with quite a lot of text. It will be of variable size, so I was wondering if there is a way to adapt my ScrollView to the size of the UILabel, not knowing in the IB what will be the number of lines of that label. I'm doing it from the IB, drag n dropping it, then I'm putting 4 elements inside : an image for the logo, a title, another image, and then the label.
My question is : how can I tell my ScrollView to adapt to the text ? With constraints ? In the code ? I'm sooooo lost with that scrolling thing…
I think I need a very very good tutorial about autolayout…
Here's some screenshots of my project
The project on simulator
The layout
Thanks a lot!
You have to add the constraints to your label so that it will always have the same spacing to the scroll view. Also, you will have to set your labels lines to 0.
Don't press Add Missing Constraints because it will probably set your height and you don't want that to happen. Use the Pin button to set the spacing to nearest neighbor.
These are the buttons you will have to use, they are bottom right.
First of all, press the one in the right and select All Views > Clear Constraints.
Then, select your label in the storyboard and press the button with a square Pin, here you will have to select everything until you have something like this with different values... Also click in the red lines so that you get a continuous red line. Don't check any of the boxes you see.
After this, you have to do the same process for your Scroller.
It should be enough. I will also need to know where your scroller is.
If you have anything else in your view, do the same.

Resize button in swift/xcode with Autolayout enabled

I have read in several other SO posts about this topic, and it's my understanding that to resize an object when AutoLayout is enabled, you can simply change the constant properties of their constraints in your code.
I have two buttons side by side, like this
[delete][ post ]
and they take up the entire width of the screen. I want to hide the delete button for certain views, and when that happens, stretch the post button to take up the entire width of the screen. In my code, I have:
self.postButtonLeadingConstraint.constant = self.deleteButtonLeadingConstraint.constant
self.deleteButton.hidden
My delete button hides just fine, but my post button stays exactly where it is at. What is it that I am doing wrong? Any input is greatly appreciated.
EDIT: If it matters, my buttons are constrained as follows:
Delete button leading constrained to leading edge of view
Post button leading constrained to trailing edge of delete button
Delete and post button set to equal each others' widths
both buttons have their tops and buttons constrained to the view they are in, but I don't see how those could be relevant.
If you're targeting iOS 9 and higher then I'd suggest using UIStackView. This is super easy that way, just a matter of adding and/or removing the button from/to stack view. Here's little sample to help you understand.
Try this:
self.postButtonLeadingConstraint.constant -= self.deleteButton.frame.size.width
self.deleteButton.hidden = true
The problem is that although you are hiding the button, it's width remains unchanged. If you use
self.deleteButtonWidthConstraint.constant = 0
Where deleteButtonWidthConstraint is an #IBOutlet hooked up to the delete button's width constraint.

Resources