Центрирование UIImageView не работает во время анимации - PullRequest
0 голосов
/ 15 марта 2019

Я пытаюсь анимировать наборы изображений в одной и той же точке, например, как работает расширяющееся меню. Страница построена с уже отображаемыми кнопками, и во время viewDidLayoutSubviews () я их анимирую. Когда кнопка нажата, я затем анимирую их в исходное положение, все анимации основаны на изменении центра изображения. У меня проблема по какой-то причине, анимация немного смещена вправо. на больших устройствах это не так уж плохо, но на небольших устройствах это большая проблема. весь пользовательский интерфейс построен с использованием autoLayout:

layout inside the autolayout

Вот код для установки местоположения центра, он запускается до начала анимации:

        micContainerLocation = micContainer.center
        cameraContainerLocation = cameraContainer.center
        pencilContainerLocation = pencilContainer.center
        calendarContainerLocation = calendarContainer.center

Вот код анимации для анимации кнопок:

    UIView.animate(withDuration: 0.3, animations: {
                self.calendarContainer.center = self.calendarContainerLocation
                self.cameraContainer.center = self.cameraContainerLocation
                self.micContainer.center = self.micContainerLocation
                self.pencilContainer.center = self.pencilContainerLocation
                self.sendMessageButton.alpha = 0
                self.openMenuButton.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi / 4))

            })    

Вот результат:

animation result

Любой совет будет принят с благодарностью. Спасибо.

EDIT:

Не уверен, поможет ли это, но вот изображение констант в автоматическом макете.

constriant image

и подробный список ограничений:

Constriant Detail

1 Ответ

1 голос
/ 15 марта 2019

Я подозреваю, что проблема (или, по крайней мере, часть проблемы) заключается в смешении явных значений .center с ограничениями автоматического размещения. Также возможно, что вы не получаете «истинные» значения центра.

Другой подход, использующий только автоматическое размещение, заключается в создании массива ограничений для «скрытых» позиций и другого массива для «видимых» позиций. Затем отключите / активируйте, чтобы показать / скрыть кнопки.

И ... это легче сделать, чем сказать:)

  • Сначала расположите кнопки и контейнеры в раскадровке, как вы уже сделали.
  • Затем выберите каждое из ограничений, влияющих на переднюю и заднюю кромки контейнеров.
  • Установите эти ограничения в качестве заполнителей, чтобы они были удалены во время сборки (мы установим правильные ограничения в коде, поэтому нам не понадобится целый набор @IBOutlet с).
  • Затем, как вы можете догадаться, установите ограничения в своем коде.

Дополнительным преимуществом является то, что кнопки автоматически изменяют размер / положение, даже если ширина суперпредставления изменяется - например, при повороте устройства - без необходимости какого-либо кода для повторной оценки свойств .center.

Вот изображение параметра Placeholder с ограничением раскадровки:

enter image description here

Основная идея будет:

Создайте набор ограничений, чтобы контейнеры кнопок находились вне поля зрения слева от левого края. Это будут «скрытые» ограничения.

Создайте набор ограничений, чтобы контейнеры кнопок находились в поле зрения, и каждый из них был выровнен / соответствующим образом отрегулирован. Это будут «видимые» ограничения.

Это может показаться сложным, но если вы посмотрите на следующий пример, я думаю, вы увидите, что на самом деле очень мало что происходит.

Этот пример должен работать как есть ... просто создайте новую раскадровку и замените источник, а затем используйте следующий класс. Это не совсем точно , что у вас есть, но оно должно быть достаточно близко, чтобы вы могли использовать его в качестве отправной точки.

Вот код:

//
//  AnimButtonsViewController.swift
//
//  Created by Don Mag on 3/15/19.
//

import UIKit

class AnimButtonsViewController: UIViewController {

    @IBOutlet var pencilContainer: UIView!
    @IBOutlet var cameraContainer: UIView!
    @IBOutlet var micContainer: UIView!
    @IBOutlet var calendarContainer: UIView!

    @IBOutlet var buttonsContainer: UIView!

    var hiddenConstraints = [NSLayoutConstraint]()
    var visibleConstraints = [NSLayoutConstraint]()

    override func viewDidLoad() {
        super.viewDidLoad()

        var c = NSLayoutConstraint()

        // set up the "hidden" constraints

        // constrain pencilContainer (1) *trailing* to buttonsContainer *leading*
        //  this will place it outside the view (to the left of left edge)

        c = pencilContainer.trailingAnchor.constraint(equalTo: buttonsContainer.leadingAnchor)
        hiddenConstraints.append(c)

        // constrain leading of remaining buttons to leading of pencilContainer
        //  they are now all "overlaid" on top of each other, outside the view

        c = cameraContainer.leadingAnchor.constraint(equalTo: pencilContainer.leadingAnchor)
        hiddenConstraints.append(c)

        c = micContainer.leadingAnchor.constraint(equalTo: pencilContainer.leadingAnchor)
        hiddenConstraints.append(c)

        c = calendarContainer.leadingAnchor.constraint(equalTo: pencilContainer.leadingAnchor)
        hiddenConstraints.append(c)


        // set up the "visible" constraints

        // constrain first button (pencilContainer (1)) *leading* to buttonsContainer *leading*
        //  and each remaining button constrain its leading to the previous button's trailing

        c = pencilContainer.leadingAnchor.constraint(equalTo: buttonsContainer.leadingAnchor)
        visibleConstraints.append(c)

        c = cameraContainer.leadingAnchor.constraint(equalTo: pencilContainer.trailingAnchor)
        visibleConstraints.append(c)

        c = micContainer.leadingAnchor.constraint(equalTo: cameraContainer.trailingAnchor)
        visibleConstraints.append(c)

        c = calendarContainer.leadingAnchor.constraint(equalTo: micContainer.trailingAnchor)
        visibleConstraints.append(c)

        // contrain last button (calendarContainer (4)) trailing to buttonsContrainer trailing

        c = calendarContainer.trailingAnchor.constraint(equalTo: buttonsContainer.trailingAnchor)
        visibleConstraints.append(c)

        // activate the hidden constraints
        NSLayoutConstraint.activate(hiddenConstraints)

    }

    @IBAction func showHideTapped(_ sender: Any) {

        if let b = sender as? UIButton {

            // just for demo purposes,
            //  if the button title is "+" we need to "show" the buttons
            //  if the button title is "X" we need to "hide" the buttons

            let t = b.currentTitle

            if t == "+" {
                NSLayoutConstraint.deactivate(hiddenConstraints)
                NSLayoutConstraint.activate(visibleConstraints)
                b.setTitle("X", for: .normal)
            } else {
                NSLayoutConstraint.deactivate(visibleConstraints)
                NSLayoutConstraint.activate(hiddenConstraints)
                b.setTitle("+", for: .normal)
            }

             UIView.animate(withDuration: 0.3, animations: {
                self.view.layoutIfNeeded()
            })

        }

    }

}

и вот источник раскадровки:

<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Msu-cJ-7P1">
    <device id="retina4_7" orientation="portrait">
        <adaptation id="fullscreen"/>
    </device>
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <scenes>
        <!--Anim Buttons View Controller-->
        <scene sceneID="LEr-rD-3kQ">
            <objects>
                <viewController id="Msu-cJ-7P1" customClass="AnimButtonsViewController" customModule="XC10SWScratch" customModuleProvider="target" sceneMemberID="viewController">
                    <view key="view" contentMode="scaleToFill" id="Efg-NM-r2G">
                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="tXi-AX-zDz" userLabel="Red View">
                                <rect key="frame" x="30" y="278.5" width="315" height="110"/>
                                <subviews>
                                    <view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="BDK-vE-tUk">
                                        <rect key="frame" x="4" y="30" width="273" height="50"/>
                                        <subviews>
                                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="EbR-gU-YBO">
                                                <rect key="frame" x="0.0" y="0.0" width="68.5" height="50"/>
                                                <subviews>
                                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="unV-LI-1jJ">
                                                        <rect key="frame" x="14" y="5" width="40" height="40"/>
                                                        <color key="backgroundColor" red="1" green="0.83234566450000003" blue="0.47320586440000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                        <constraints>
                                                            <constraint firstAttribute="height" constant="40" id="F0Z-oi-HlI"/>
                                                            <constraint firstAttribute="width" constant="40" id="P3x-Ak-lZY"/>
                                                        </constraints>
                                                        <state key="normal" title="1"/>
                                                    </button>
                                                </subviews>
                                                <color key="backgroundColor" red="0.0" green="0.99143940210000003" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                <constraints>
                                                    <constraint firstItem="unV-LI-1jJ" firstAttribute="centerX" secondItem="EbR-gU-YBO" secondAttribute="centerX" id="ZEb-9h-WvV"/>
                                                    <constraint firstItem="unV-LI-1jJ" firstAttribute="centerY" secondItem="EbR-gU-YBO" secondAttribute="centerY" id="mB2-5w-Egs"/>
                                                    <constraint firstAttribute="width" relation="greaterThanOrEqual" secondItem="unV-LI-1jJ" secondAttribute="width" id="mYy-gx-PT4"/>
                                                </constraints>
                                            </view>
                                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="QjG-7X-1Sa">
                                                <rect key="frame" x="68.5" y="0.0" width="68" height="50"/>
                                                <subviews>
                                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qYS-Qj-f9n">
                                                        <rect key="frame" x="14" y="5" width="40" height="40"/>
                                                        <color key="backgroundColor" red="1" green="0.83234566450000003" blue="0.47320586440000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                        <constraints>
                                                            <constraint firstAttribute="height" constant="40" id="To5-l0-frk"/>
                                                            <constraint firstAttribute="width" constant="40" id="m9L-d5-Mac"/>
                                                        </constraints>
                                                        <state key="normal" title="2"/>
                                                    </button>
                                                </subviews>
                                                <color key="backgroundColor" red="0.0" green="0.99143940210000003" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                <constraints>
                                                    <constraint firstItem="qYS-Qj-f9n" firstAttribute="centerX" secondItem="QjG-7X-1Sa" secondAttribute="centerX" id="nNp-T0-rxc"/>
                                                    <constraint firstItem="qYS-Qj-f9n" firstAttribute="centerY" secondItem="QjG-7X-1Sa" secondAttribute="centerY" id="pDK-Y0-lag"/>
                                                </constraints>
                                            </view>
                                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="5IF-rt-c8a">
                                                <rect key="frame" x="136.5" y="0.0" width="68.5" height="50"/>
                                                <subviews>
                                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="E15-8G-pOx">
                                                        <rect key="frame" x="14" y="5" width="40" height="40"/>
                                                        <color key="backgroundColor" red="1" green="0.83234566450000003" blue="0.47320586440000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                        <constraints>
                                                            <constraint firstAttribute="height" constant="40" id="ADz-st-xYC"/>
                                                            <constraint firstAttribute="width" constant="40" id="rIE-3o-Yih"/>
                                                        </constraints>
                                                        <state key="normal" title="3"/>
                                                    </button>
                                                </subviews>
                                                <color key="backgroundColor" red="0.0" green="0.99143940210000003" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                <constraints>
                                                    <constraint firstItem="E15-8G-pOx" firstAttribute="centerY" secondItem="5IF-rt-c8a" secondAttribute="centerY" id="NW3-qd-aRL"/>
                                                    <constraint firstItem="E15-8G-pOx" firstAttribute="centerX" secondItem="5IF-rt-c8a" secondAttribute="centerX" id="cyb-wZ-bhq"/>
                                                </constraints>
                                            </view>
                                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kHB-hc-CY5">
                                                <rect key="frame" x="205" y="0.0" width="68" height="50"/>
                                                <subviews>
                                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="QrB-eG-9oo">
                                                        <rect key="frame" x="14" y="5" width="40" height="40"/>
                                                        <color key="backgroundColor" red="1" green="0.83234566450000003" blue="0.47320586440000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                        <constraints>
                                                            <constraint firstAttribute="width" constant="40" id="4Qh-a1-bzP"/>
                                                            <constraint firstAttribute="height" constant="40" id="maJ-ei-IEH"/>
                                                        </constraints>
                                                        <state key="normal" title="4"/>
                                                    </button>
                                                </subviews>
                                                <color key="backgroundColor" red="0.0" green="0.99143940210000003" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                <constraints>
                                                    <constraint firstItem="QrB-eG-9oo" firstAttribute="centerX" secondItem="kHB-hc-CY5" secondAttribute="centerX" id="Enu-M7-oc0"/>
                                                    <constraint firstItem="QrB-eG-9oo" firstAttribute="centerY" secondItem="kHB-hc-CY5" secondAttribute="centerY" id="iwr-AG-t6j"/>
                                                </constraints>
                                            </view>
                                        </subviews>
                                        <color key="backgroundColor" red="0.45009386540000001" green="0.98132258650000004" blue="0.4743030667" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                        <constraints>
                                            <constraint firstItem="kHB-hc-CY5" firstAttribute="centerY" secondItem="EbR-gU-YBO" secondAttribute="centerY" id="17U-hP-XiO"/>
                                            <constraint firstItem="EbR-gU-YBO" firstAttribute="height" secondItem="BDK-vE-tUk" secondAttribute="height" id="2Kc-yZ-8EB"/>
                                            <constraint firstItem="QjG-7X-1Sa" firstAttribute="width" secondItem="EbR-gU-YBO" secondAttribute="width" id="3bm-Ya-pZA"/>
                                            <constraint firstItem="EbR-gU-YBO" firstAttribute="leading" secondItem="BDK-vE-tUk" secondAttribute="leading" placeholder="YES" id="6E3-jg-Ku3"/>
                                            <constraint firstItem="EbR-gU-YBO" firstAttribute="centerY" secondItem="BDK-vE-tUk" secondAttribute="centerY" id="8hy-lM-jcp"/>
                                            <constraint firstAttribute="trailing" secondItem="kHB-hc-CY5" secondAttribute="trailing" placeholder="YES" id="HQQ-As-qWL"/>
                                            <constraint firstItem="QjG-7X-1Sa" firstAttribute="height" secondItem="EbR-gU-YBO" secondAttribute="height" id="HRx-Ud-bkP"/>
                                            <constraint firstItem="5IF-rt-c8a" firstAttribute="height" secondItem="EbR-gU-YBO" secondAttribute="height" id="L5Q-Ee-ZSx"/>
                                            <constraint firstItem="QjG-7X-1Sa" firstAttribute="leading" secondItem="EbR-gU-YBO" secondAttribute="trailing" placeholder="YES" id="NMH-3d-uhZ"/>
                                            <constraint firstItem="5IF-rt-c8a" firstAttribute="centerY" secondItem="EbR-gU-YBO" secondAttribute="centerY" id="Nma-OU-J25"/>
                                            <constraint firstItem="kHB-hc-CY5" firstAttribute="height" secondItem="EbR-gU-YBO" secondAttribute="height" id="WXs-c8-mbJ"/>
                                            <constraint firstItem="kHB-hc-CY5" firstAttribute="width" secondItem="EbR-gU-YBO" secondAttribute="width" id="Y87-Ph-wOu"/>
                                            <constraint firstAttribute="height" constant="50" id="YRG-m1-zQ0"/>
                                            <constraint firstItem="5IF-rt-c8a" firstAttribute="leading" secondItem="QjG-7X-1Sa" secondAttribute="trailing" placeholder="YES" id="cTU-cd-6gQ"/>
                                            <constraint firstItem="QjG-7X-1Sa" firstAttribute="centerY" secondItem="EbR-gU-YBO" secondAttribute="centerY" id="fd7-iE-WFg"/>
                                            <constraint firstItem="5IF-rt-c8a" firstAttribute="width" secondItem="EbR-gU-YBO" secondAttribute="width" id="jAO-LF-jvX"/>
                                            <constraint firstItem="kHB-hc-CY5" firstAttribute="leading" secondItem="5IF-rt-c8a" secondAttribute="trailing" placeholder="YES" id="kNi-xf-omT"/>
                                        </constraints>
                                    </view>
                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="smc-cM-nTo">
                                        <rect key="frame" x="281" y="40" width="30" height="30"/>
                                        <color key="backgroundColor" red="0.75406885150000003" green="0.75408679249999999" blue="0.75407713649999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                        <state key="normal" title="+">
                                            <color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                        </state>
                                        <connections>
                                            <action selector="showHideTapped:" destination="Msu-cJ-7P1" eventType="touchUpInside" id="spY-Hq-Xeu"/>
                                        </connections>
                                    </button>
                                </subviews>
                                <color key="backgroundColor" red="1" green="0.14913141730000001" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                <constraints>
                                    <constraint firstAttribute="trailing" secondItem="smc-cM-nTo" secondAttribute="trailing" constant="4" id="3Ry-gN-0Z4"/>
                                    <constraint firstItem="smc-cM-nTo" firstAttribute="leading" secondItem="BDK-vE-tUk" secondAttribute="trailing" constant="4" id="I2C-fT-Op3"/>
                                    <constraint firstItem="smc-cM-nTo" firstAttribute="centerY" secondItem="tXi-AX-zDz" secondAttribute="centerY" id="Mmb-uk-L5E"/>
                                    <constraint firstItem="BDK-vE-tUk" firstAttribute="leading" secondItem="tXi-AX-zDz" secondAttribute="leading" constant="4" id="NXB-2K-Egb"/>
                                    <constraint firstAttribute="height" constant="110" id="inu-kU-GH9"/>
                                    <constraint firstItem="BDK-vE-tUk" firstAttribute="centerY" secondItem="tXi-AX-zDz" secondAttribute="centerY" id="kDF-XJ-qkj"/>
                                </constraints>
                            </view>
                        </subviews>
                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                        <constraints>
                            <constraint firstItem="tXi-AX-zDz" firstAttribute="leading" secondItem="12L-io-1Iw" secondAttribute="leading" constant="30" id="30d-ds-ZVg"/>
                            <constraint firstItem="12L-io-1Iw" firstAttribute="trailing" secondItem="tXi-AX-zDz" secondAttribute="trailing" constant="30" id="ofy-ZY-LjW"/>
                            <constraint firstItem="tXi-AX-zDz" firstAttribute="centerY" secondItem="Efg-NM-r2G" secondAttribute="centerY" id="rtS-1o-e1I"/>
                        </constraints>
                        <viewLayoutGuide key="safeArea" id="12L-io-1Iw"/>
                    </view>
                    <connections>
                        <outlet property="buttonsContainer" destination="BDK-vE-tUk" id="qkA-Rn-M8Z"/>
                        <outlet property="calendarContainer" destination="kHB-hc-CY5" id="red-ot-mmb"/>
                        <outlet property="cameraContainer" destination="QjG-7X-1Sa" id="P94-ES-YRb"/>
                        <outlet property="micContainer" destination="5IF-rt-c8a" id="ipp-Bt-B2m"/>
                        <outlet property="pencilContainer" destination="EbR-gU-YBO" id="Fr9-7f-BIa"/>
                    </connections>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="Y2G-rV-gCJ" userLabel="First Responder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="-478" y="2845"/>
        </scene>
    </scenes>
</document>

Результат (нажатие на серую кнопку приведет к анимации кнопок в и из):

enter image description here

...