0

I want my textFields to hid behind the screen when "viewDidLoad" calls and then appearing smoothly on view by pushing a button. I just have a function like:

UIView.animate(duration: 0.5, options: .curveEaseIn) {
    textField.center.x -= view.frame.width
}

And it was working until added constraints. And now the textField just hiding behind the screen and returning back immediately. I think solution in using "Dispatch.main" but i didn't have success. Click here to look

Can somebody help with it?

Edited

I have a similar app with the same animation and it works with all constraints. Thats the code and Storyboard. Why it possible to do with UIView?

Fiesta
  • 3
  • 2

1 Answers1

0

You cannot change the frame of a view that is using constraints for auto-layout.

Instead, you need to animate changes to the constraints.

Various ways to do this -- here is one approach.

In Storyboard, layout your fields like this:

enter image description here

Each field has a CenterX constraint... but we will set the Priority to High (750):

enter image description here enter image description here

Then, we'll add "hidden" constraints as properties in the view controller:

var nameHiddenConstraint: NSLayoutConstraint!
var surnameHiddenConstraint: NSLayoutConstraint!

and in viewDidLoad we'll create Priority : Required constraints to start those fields "off-screen." To animate the fields into-view, we can deactivate the "hidden" constraints and let auto-layout use the Storyboard-created CenterX constraints.

Here's some example code:

class ConAnimVC: UIViewController {
    
    @IBOutlet var nameField: UITextField!
    @IBOutlet var surnameField: UITextField!

    var nameHiddenConstraint: NSLayoutConstraint!
    var surnameHiddenConstraint: NSLayoutConstraint!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // constraints created via code have a default Priority of Required
        //  so they will "override" the centerX constraints created in Storyboard
        
        // constrain Trailing of nameField 20-points to the left of view.leading
        nameHiddenConstraint = nameField.trailingAnchor.constraint(equalTo: view.leadingAnchor, constant: -20.0)
        // constrain Leading of surnameField 20-points to the right of view.trailing
        surnameHiddenConstraint = surnameField.leadingAnchor.constraint(equalTo: view.trailingAnchor, constant: 20.0)

        // activate those two constraints
        nameHiddenConstraint.isActive = true
        surnameHiddenConstraint.isActive = true
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        // deactivate the code-created constraints
        nameHiddenConstraint.isActive = false
        surnameHiddenConstraint.isActive = false
        // animate the constraint changes
        UIView.animate(withDuration: 0.5, delay: 0.0, options: .curveEaseIn, animations: {
            self.view.layoutIfNeeded()
        }, completion: nil)
    }
    
}

and here's the source code for that Storyboard:

<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Y6W-OH-hqX">
    <device id="retina4_7" orientation="portrait" appearance="light"/>
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
        <capability name="System colors in document resources" minToolsVersion="11.0"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <scenes>
        <!--Con AnimVC-->
        <scene sceneID="s0d-6b-0kx">
            <objects>
                <viewController id="Y6W-OH-hqX" customClass="ConAnimVC" customModule="QuickTest" customModuleProvider="target" sceneMemberID="viewController">
                    <view key="view" contentMode="scaleToFill" id="5EZ-qb-Rvc">
                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="name" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="19l-e9-8x6">
                                <rect key="frame" x="37.5" y="40" width="300" height="34"/>
                                <color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                <textInputTraits key="textInputTraits"/>
                            </textField>
                            <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="surname" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="LRb-yP-Zgy">
                                <rect key="frame" x="37.5" y="82" width="300" height="34"/>
                                <color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                <textInputTraits key="textInputTraits"/>
                            </textField>
                        </subviews>
                        <viewLayoutGuide key="safeArea" id="vDu-zF-Fre"/>
                        <color key="backgroundColor" systemColor="systemGray5Color"/>
                        <constraints>
                            <constraint firstItem="19l-e9-8x6" firstAttribute="width" secondItem="5EZ-qb-Rvc" secondAttribute="width" multiplier="0.8" id="UPO-jI-q7U"/>
                            <constraint firstItem="LRb-yP-Zgy" firstAttribute="centerX" secondItem="5EZ-qb-Rvc" secondAttribute="centerX" priority="750" id="VV4-3M-Y1v"/>
                            <constraint firstItem="LRb-yP-Zgy" firstAttribute="top" secondItem="19l-e9-8x6" secondAttribute="bottom" constant="8" id="c4i-Eb-DGs"/>
                            <constraint firstItem="19l-e9-8x6" firstAttribute="centerX" secondItem="5EZ-qb-Rvc" secondAttribute="centerX" priority="750" id="iDc-Rz-7R9"/>
                            <constraint firstItem="LRb-yP-Zgy" firstAttribute="width" secondItem="5EZ-qb-Rvc" secondAttribute="width" multiplier="0.8" id="m27-e9-kZQ"/>
                            <constraint firstItem="19l-e9-8x6" firstAttribute="top" secondItem="vDu-zF-Fre" secondAttribute="top" constant="40" id="s3k-lV-qLH"/>
                        </constraints>
                    </view>
                    <connections>
                        <outlet property="nameField" destination="19l-e9-8x6" id="ZGF-91-Shz"/>
                        <outlet property="surnameField" destination="LRb-yP-Zgy" id="xWU-uW-fTZ"/>
                    </connections>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="Ief-a0-LHa" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="71" y="96"/>
        </scene>
    </scenes>
    <resources>
        <systemColor name="systemGray5Color">
            <color red="0.89803921568627454" green="0.89803921568627454" blue="0.91764705882352937" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
        </systemColor>
    </resources>
</document>
DonMag
  • 69,424
  • 5
  • 50
  • 86
  • I was sure it is possible to do like i tried. Thanks for your help and showing me the right way to reach it. I like this decision) – Fiesta Oct 06 '22 at 17:41
  • But i also have one question. I have another app ( i did when was practicing in Animation) and there with UIView it works even with all constraints. I edited my question. – Fiesta Oct 06 '22 at 18:32
  • @Fiesta - your "other code" does not work like you think it does. As soon as UIKit runs another layout pass (anything else changes that would affect the layout), your image view's constraints will be re-applied. Trying to do that with text fields - particularly multiple text fields - will trigger a call to layout. That's why it *seems* to work differently. – DonMag Oct 06 '22 at 22:31