How to insert UIButton through code with AutoLayout feature enabled - iOS - iphone

I have been trying to insert a UIButton programatically, as I am using Autolayout I have done something like that...
[self.add_scroll_view addConstraints : [NSLayoutConstraint constraintsWithVisualFormat : #"V:[date_picker_btn]-[button(==date_picker_btn)]"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(date_picker_btn, button)]];
I have two questions here...
i) Button inserted is not the same width as date_picker_btn even though I mentioned button(==date_picker_btn).
ii) I have inserted properely, however below views should align accordingly down to accommodate new button... How to do that...
Thanx

When using the visual format language, the superview of the view for which the constraint is being described is represented by the | character.
Example:
V:|-20-[mybutton1(>=70#500)]-[mybutton2(==mybutton1)]-30-[mybutton3]-|
Refer this link

For first question I have mentioned V: so it means (==) will assign height not width. To set width it should start with H:.
Next question, To insert a button between two existing button need to handle already existing constraints, here above I have added new constraints only not handle old existing, so I have to delete the existing constraints, so that it avoid conflicts. Works fine.. Happy coding :)

Related

Autolayout Constraint Error with a single constraint

I have a scence with a bunch of labels and buttons. When you tap on a button a view slides up from the bottom with controls in it, a kind of keyboard so to say. It "looks" like this:
-----------------------------
| |
| [Button 1] [ Slider 1 ] |
| |
| [Button 2] [ Slider 2 ] |
| |
-----------------------------
This "keyboard" is created at the very beginning when the view loads and the animation is done switching its heigth from 0 to its instrinsic content size. This escene only supports landscape mode and it took me quite a while to keep the "keyboard" on the view when the device rotates 180 degrees.
The problem I see pops up with either of the two following situations:
The device rotates 180 degrees.
The "keyboard" is called.
This problem as follows:
Unable to simultaneously satisfy constraints...
.
.
.
.
(
"<NSLayoutConstraint:0x718c6c0 UIButton:0x717e0d0.centerY == UISlider:0x717d9d0.centerY>",
"<NSLayoutConstraint:0x7190a00 UIButton:0x717e0d0.centerY == UISlider:0x717d9d0.centerY>"
)
The error log gives me this error twice, once for each set of button-slider.
What I think is weird is that the conflicting constraints are exactly the same. I thought I did some copy-paste mistake and added the same constraint twice, but it's not the case.
I'm guessing it has something to do with updateViewConstraints being called upon rotation and also whe I perform the animation, but I cannot see why only these constraints are affected since there are some more in this "keyboard" view.
All and all, this Autolayout is beign quite more difficult than Apples whants to claim. In my opinion, of course.
Any ideas?
EDIT: the constrains are set all in code using mainly the visual language format. The constrains of the controls inside the "keyboard" are added into the "keyboard" view which is the normal thing to do, I believe.
Just to try it out, I changed the problematic constraints and, instead to adding them to the "keyboard" subview, I added them to the self.view ("keyboard" superview). All the sudden, no more errors are shown.
Despite of that, I'd really like some discussion on the matter because I still don't know what's wrong and I just had a lucky shot. I'd really like to undestand it.
The fact that the conflicting constraints are exactly the same is in fact the error. With Auto Layout, you can't have a constraint twice. That will generate the error you see above.
Definitely, you have added the constraint twice. You can see this from the memory addresses. You have two different NSLayoutConstraint instances, 0x718c6c0 and 0x7190a00. However, the instances each refers to are both the same. That being that the vertical center centerY of your UIButton instance 0x717e0d0 should be in the middle of the UISlider 0x717d9d0.
Possibly your updateConstraints method has been called and you haven't checked to see if a constraint already exists before adding it again.
I don't know if this may help you but I just used this tutorial for setting up constraints to buttons and labels in my app

UILabel.center is 0? how is that possible?

I'm trying to get the CGPoint from the center property of some UILabels (which is part of an outlet collection). Now, when i do:
for (UILabel *label in labelCollection) {
NSLog(#"%f", label.center.x);
}
It simply returns 0, same with the center.y? how come? i need those coordinates hehe :)
thanks on advance
//EDIT
Uploaded a picture: the labels with "a" "b" "c" "d" is the labels i'm talking about. i tried changing the text.property in the code and that works well, but it just wont give me the coordinates it's on.
Verify that the view has a superview. The value depends on the superview's coordinates.
I figured out the answer, it had to do with the fact that i was doing the whole thing in viewDidLoad, and i should be doing it in viewDidAppear. it must be because on viewDidLoad, it hasn't been placed yet, and therefore i could still change the text, coz the object label was created, but i couldnt get the origin coz it was not placed yet.
thanks for helping lads.
You remove the constraints then run the app may be constraint create the problem because new xcode constraints create problem on some functions and properties so first remove the constraints by uncheck the "Use autlayout "then you check the app

Center Multi-Line Text on UIButton using IB

How do you center text line-by-line in a UIButton using Interface Builder? I am scouring the options and just don't see it. Here's the button:
You can't set the text to be centered in your nib. But you can change the alignment in your code:
- (void)viewDidLoad {
[super viewDidLoad];
self.myButton.titleLabel.textAlignment = UITextAlignmentCenter;
}
I know this is an old question, but I came across it in my own attempt to center the multi-line text of a UIButton in IB. What I found is that by default, when "title" is set to "plain" and "line break" is set to "word wrap" the longest line of the title text is centered and the other lines are left justified to this line (similar to the OP's screen capture).
In order to have all the lines centered properly, "title" needs to be changed to "attributed." This provides many more options to customize the appearance of the title text. Center each of the lines of text (you can now actually change the alignment for each line individually). Also be sure to set "line breaking" to "word wrap" under "more..." above the text. There seems to be a bug with how this line breaking option behaves, at least in Xcode 4.5 at this time, because the text on the button in IB will look incorrect, truncating everything except the first line. It seems the "word wrap" and truncate options are interpreted backwards in IB, but if you run the app it behaves correctly in the simulator.
Actually you can do it in interface builder.
Just set Title to "Attributed" and then choose center alignment.
#from comments : To wrap you need to set Line Break to Character Wrap or Word Wrap.
P.S : This might not render in xcode. But, it will work at runtime.
You can set the center multiline text in UIButton through storyboard.
This is how you make the text have two or more lines.
Set the below key Path at
Identity Inspector --> User defined runtime attributes --> add new key value pair with below
titleLabel.textAlignment - NSNumber - 1
and
titleLabel.numberOfLines - NSNumber - 5 - or use "0" meaning "any number"
It will look like this:
Note that (2016) unfortunately it does not actually show the two or more lines of text in Storyboard (you see only the first one), but it works perfectly when you run in simulator or device.
For IB set Title to "Attributed" and select center alignment (like Alexander Danilov suggested)
But if you want to do it in code using Swift 4:
// center button text
yourButton.titleLabel?.textAlignment = .center
// enable multiline if needed
yourButton.titleLabel?.numberOfLines = 0
Not all options are done using Interface Builder therefore you must do some of them by coding, and usually we do them inside the function viewDidLoad.
To center your text inside a button by code you can use the following:
button1.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
You can use the same technique to align the text to any direction, for example to the left:
button1.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
But this will take the text too much to the left and you might want to have some space before it keeping the alignment to the left, so you add an inset after the aligning code as follows:
button1.contentEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0);
In this case we are pushing the text from the Y axis by 10 points. I say here points not pixels because as you know Apple uses the points technique to measure distances to be able to adapt easily between normal display and retina display (where retina is 2 times the normal one).
I haven't tried it out yet, but I think a way to do it might be create a CGRect on top of your button, then use it as a frame, create a label, and then you can play with the label, set the textAlignment property to be UITextAlignmentCenter, and set the background color to be clear.
This works with uitableview but I don't know whether that will work for button. Hope this helps.

Hide a UITableView by setting row height to 0?

I just inherited code which hides/shows rows a UITableView by using the delegate heightForRowAtIndexPath method and returning height 0 for "hidden rows".
The code works, but it has me concerned there might be fraught with unforeseen complications. Can someone either ease my concerns or give me good reasons why this could cause problems (I couldn't find any issues with initial testing).
The table is fairly small <10 rows total and would require custom row heights even without this hidden row solution.
I do the same thing in the code I just worked on. I am not happy with different behaviour for different table view settings.
The alternative in my case is more complex (a model that adapts to what is visible or not).
For now, I put a //HACK comment on it and document a few peculiarities.
This is what I have found (iOS 5.0 tested):
Set tableView.rowHeight = 1; Zero will give a cell with zero height (as returned by tableView:tableView heightForRowAtIndexPath:) some default height.
You must have a cell separator. If none is selected, then a default height is assigned to zero height rows. The height of 1 is included with the separator.
If your code works in a different way, it would be interesting to know how it is set up.
It would be cleaner to add and remove the rows between two beginUpdates and endUpdates calls, but I don't see why this 0-height method should not work.
If there are no UI-artifacts, that is (e.g. the Delete button showing up overflowing to the next cell).
I use this method of setting hidden cell heights to 0. It works well and also means I can animate the inclusion of new cells by expanding the cell height (such as adding a DatePicker Cell like the calendar app does).
A few things I have had to watch out for in iOS 7.1 are that very squashed text does still appear even when a cell height is = 0 so I've needed to remove cell text in that case. Also, I have change the size of the cell's separatorInset as that was appearing as well.

UIPickerView - changing component width

In my iPhone app I want to have a UIPickerView with 2 components. Initially the left column will be wide and the right column narrow to enable the text on the left to be read easily to allow selection from it.
Once this column has been selected the user will click on the right column to select an item from it : when this happens I want to resize the columns so that the left column is narrow and the right one is wide so that all the text can be read.
I have been experimenting with "pickerView widthForComponent" but this seems to only get called when the view is initially loaded.
Is there any way I can dynamically resize the columns ?
Thanks
You may use [pickerView reloadAllComponents].
Update:
That's weird. You may also try to check the following solution.
Just a reload won't work. You also need to call setNeedsLayout
[pickerView reloadAllComponents];
[pickerView setNeedsLayout];