Autolayout Complains About Constraints for 2 Uitextfields with No Borders

AutoLayout complains about constraints for 2 UITextFields with no borders

"Add Missing Constraints" is not always a good idea to add constraints..rather you should always prefer to add constraints manually...

Here is the image for your UI...I used wAnyhAny layout as it is good practice for add constraints for universal devices...

Sample Image

I used simply width constraint for textfield, rather you should Equal width to super view and add multiplier to resize width according to device width

Here is the output image in different sizes...

Sample Image

Constraints layout to UITextFields in a cell

Make equal widths and horizontal spacing for textfields. Also pin left to left, right to right and center vertically for both.

UPDATED:

Select two textfields and do:

  1. Editor -> Resolve Auto Layout Issues -> Clear Constraints
  2. Editor -> Pin -> Horizontal Spacing and
  3. Editor -> Pin -> Widths Equally
  4. Editor -> Align -> Vertical Centers

Select left textfield and do:

  1. Editor -> Pin -> Leading Space to Superview

Select right textfield and do:

  1. Editor -> Pin -> Trailing Space to Superview.

Xcode 7: UITextview doesn't aligned properly for 3 different sizes iPhone screen

Follow this image and set your constraints like wise....

Sample Image

How can I make UITextField always centered on the screen?

As simple as this:

Sample Image

In the Align menu from the bottom of interface builder if you set this constraint to 0 it will be the center of the view

Auto layout doesn't work on iPhone 6 device but works on emulator

There is a principle that you need to know.. Every view you add to the storyboard must have enough constraints to confirm it's:

  1. Width
  2. Height
  3. X position
  4. Y position

You should review the constrains you added.
Especially the first textfield(Your Full Name).
Seems like it's Y position constrains wrong.

How to animate centered square to the top

While you can use Autolayout to animate - to take the constraint constraining the centerY and set its constant to a value that would move to the top (e.g., constant = -(UIScreen.main.bounds.height / 2)), I would recommend using view's transform property.

So to move the view to the top you can use:

let topMargin = CGFloat(20)
let viewHalfHeight = self.view.bounds.height / 2
let boxHalfHeight = self.box.bounds.height / 2
UIView.animate(withDuration: 0.2) {
box.transform = CGAffineTransform.identity
.translatedBy(x: 0, y: -(viewHalfHeight - (boxHalfHeight + topMargin)))
}

You are moving box.center related to the view.center - so if you want to move the box to the top, you have to move its center by half a view's height (because the view's centerY is exactly height / 2 far from the view's top). That is not enough though, because then only a bottom half of the box is visible (now the box.centerY == view.top). Therefore you have to move it back by the box.bounds.height / 2 (in my code boxHalfHeight) - to make the top half visible. And to that boxHalfHeight you add topMargin so that there is some margin to the top.

Then, to move the box back to original position:

UIView.animate(withDuration: 0.2) {
box.transform = CGAffineTransform.identity
}

EDIT

If you really want to go with autolayout, you have to have a reference to the centerY constraint, so for example if it is created this way:

let boxCenterYConstraint = self.box.centerYAnchor.constraint(equalTo: self.view.centerYAnchor)
boxCenterYConstraint.isActive = true

Then you can try this:

// calculating the translation is the same
let topMargin = CGFloat(20)
let viewHalfHeight = self.view.bounds.height / 2
let boxHalfHeight = self.box.bounds.height / 2
let diff = -(viewHalfHeight - (boxHalfHeight + topMargin))

boxCenterYConstraint.constant = diff
self.view.setNeedsLayout()
UIView.animate(withDuration: 0.2) {
self.view.layoutIfNeeded()
}

And animation back:

boxCenterYConstraint.constant = 0
self.view.setNeedsLayout()
UIView.animate(withDuration: 0.2) {
self.view.layoutIfNeeded()
}

Resize a UITextField while typing (by using Autolayout)

This is what works for me:

- (IBAction) textFieldDidChange: (UITextField*) textField
{
[UIView animateWithDuration:0.1 animations:^{
[textField invalidateIntrinsicContentSize];
}];
}

What's interesting is that it seems as if it SHOULD work out of the box, given this text from the docs:

In addition, if a property of a view changes and that change affects
the intrinsic content size, the view must call
invalidateIntrinsicContentSize so that the layout system notices the
change and can re-layout. In the implementation of your view class,
you must ensure that if the value of any property upon which the
intrinsic size depends changes, you invoke
invalidateIntrinsicContentSize. For example, a text field calls
invalidateIntrinsicContentSize if the string value changes.

My best guess is that the textfield only calls invalidateIntrinsicContentSize once editing has finished, not during.

Edit: A bunch of "This is not working for me". I think the confusion here is perhaps the triggering event that is tied to the textFieldDidChange: handler. The event needs to be UIControlEventEditingChanged. If you're using IB, double check that you're handling the right event.

The UITextField also cannot be constrained in size. You can lock it into position with constraints, but any width constraint, or set of left+right positioning constraints will prevent it from resizing to its intrinsic content size.

split now complains about missing isSeparator

It seems that the order of the parameters changed in Swift 1.2:

let bits = split(value!, maxSplit: Int.max, allowEmptySlices: false,
isSeparator: { $0 == " "})

or, using the default values:

let bits = split(value!, isSeparator: { $0 == " "})

The predicate is now the last parameter and requires an external
parameter name isSeparator because it is preceded by optional parameters.

The advantage of this change is that you can use the trailing closure
syntax
:

let bits = split(value!, maxSplit: Int.max, allowEmptySlices: false) { $0 == " " }

or

let bits = split(value!) { $0 == " " }


Related Topics



Leave a reply



Submit