UIStackView показать / скрыть анимацию - PullRequest
0 голосов
/ 19 сентября 2019

В режиме просмотра стека у меня есть UIPickerView, и я хочу свернуть и развернуть его при нажатии кнопки.Я хочу использовать простую анимацию, но не знаю, как ее достичь, я пробовал много способов, но ни один из них не привел к правильному внешнему виду. Я всегда получаю это

iOS 10 animation

Я хочу, чтобы сборщик тоже развалился, чего не происходит.Он исчезает только после анимации, которая выглядит не очень хорошо.

мой код, где self - это UIStackView:

UIView.animate(withDuration: 0.3, animations: { [unowned self] in
        self.picker.isHidden = !open
        self.layoutIfNeeded()
    })

1 Ответ

1 голос
/ 19 сентября 2019

Анимация автоматического показа / скрытия стека прекрасно работает для некоторых вещей.Для других, например, с видом сборщика, не так много (как вы видели).

Один из подходов будет следующим:

  • встроить вид сборщика в обычный вид
  • ограничить его по центру по вертикали
  • добавить высоту по умолчанию к содержащему представлению (например, немного выше, чем представление выбора)
  • анимировать ограничение высоты представления

Виды сборщика не будут "сжиматься" сами по себе, поэтому вы получите "исчезающий" вид сборщика.Если вы хотите, чтобы он "сжимался" во время анимации, вам также нужно анимировать его преобразование

Вот пример (я использую контрастные цвета, чтобы было удобно видеть элементы, и я замедлилпродолжительность анимации, чтобы сделать это очевидным):

enter image description here

Вот пример кода:

class StackDemoViewController: UIViewController {

    @IBOutlet var pickerHolderView: UIView!
    @IBOutlet var pickerHolderHeightConstraint: NSLayoutConstraint!

    @IBOutlet var normalButton: UIButton!
    @IBOutlet var squeezeButton: UIButton!

    @IBOutlet var thePickerView: UIDatePicker!

    // this will be assigned in viewDidLoad
    var defaultPickerHolderViewHeight: CGFloat = 0.0

    // anim duration - change to something like 1.0 to see the effect in "slo-motion"
    let animDuration = 0.3

    override func viewDidLoad() {
        super.viewDidLoad()

        // get the original picker holder view height constant
        defaultPickerHolderViewHeight = pickerHolderHeightConstraint.constant
    }

    @IBAction func normalAnim(_ sender: Any) {

        // local bool
        let bIsHidden = pickerHolderView.isHidden

        // if the picker holder view is currently hidden, show it
        if bIsHidden {
            pickerHolderView.isHidden = false
        }

        // if picker holder height constant is > 0 (it's open / showing)
        //      set it to 0
        // else
        //      set it to defaultPickerHolderViewHeight
        self.pickerHolderHeightConstraint.constant = self.pickerHolderHeightConstraint.constant > 0 ? 0 : defaultPickerHolderViewHeight

        // animate the change
        UIView.animate(withDuration: animDuration, animations: {
            self.view.layoutIfNeeded()
        }) { finished in
            // if the picker holder view was showing (NOT hidden)
            //  hide it
            if !bIsHidden {
                self.pickerHolderView.isHidden = true
                // disable squeeze button until view is showing again
                self.squeezeButton.isEnabled = false
            } else {
                // re-enable squeeze button
                self.squeezeButton.isEnabled = true
            }
        }
    }

    @IBAction func squeezeAnim(_ sender: Any) {

        // local bool
        let bIsHidden = pickerHolderView.isHidden

        var t = CGAffineTransform.identity

        // if the picker holder view is currently hidden, show it
        if bIsHidden {
            pickerHolderView.isHidden = false
        } else {
            // we're going to hide it
            t = CGAffineTransform(scaleX: 1.0, y: 0.01)
        }

        // if picker holder height constant is > 0 (it's open / showing)
        //      set it to 0
        // else
        //      set it to defaultPickerHolderViewHeight
        self.pickerHolderHeightConstraint.constant = self.pickerHolderHeightConstraint.constant > 0 ? 0 : defaultPickerHolderViewHeight

        // animate the change
        UIView.animate(withDuration: animDuration, animations: {
            self.thePickerView.transform = t
            self.view.layoutIfNeeded()
        }) { finished in
            // if the picker holder view was showing (NOT hidden)
            //  hide it
            if !bIsHidden {
                self.pickerHolderView.isHidden = true
                // disable normal button until view is showing again
                self.normalButton.isEnabled = false
            } else {
                // re-enable normal button
                self.normalButton.isEnabled = true
            }
        }
    }

}

Использование этого макета:

enter image description here

и вот источник раскадровки (так что вы можете быстро попробовать его самостоятельно):

<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Zg0-f1-bBK">
    <device id="retina4_7" orientation="portrait">
        <adaptation id="fullscreen"/>
    </device>
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <scenes>
        <!--Stack Demo View Controller-->
        <scene sceneID="Itw-fL-6gO">
            <objects>
                <viewController id="Zg0-f1-bBK" customClass="StackDemoViewController" customModule="TranslateTest" customModuleProvider="target" sceneMemberID="viewController">
                    <view key="view" contentMode="scaleToFill" id="rze-A8-JnC">
                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="vDP-gh-oah">
                                <rect key="frame" x="8" y="120" width="359" height="338"/>
                                <subviews>
                                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="clh-vv-1e4">
                                        <rect key="frame" x="0.0" y="0.0" width="359" height="50"/>
                                        <subviews>
                                            <stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="VMQ-JX-yNt">
                                                <rect key="frame" x="8" y="8" width="343" height="34"/>
                                                <subviews>
                                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Zb9-rN-qPb">
                                                        <rect key="frame" x="0.0" y="0.0" width="163.5" height="34"/>
                                                        <color key="backgroundColor" red="0.99806135890000003" green="0.96808904409999996" blue="0.12760734560000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                        <state key="normal" title="Normal"/>
                                                        <connections>
                                                            <action selector="normalAnim:" destination="Zg0-f1-bBK" eventType="touchUpInside" id="zwU-Bs-ZlI"/>
                                                        </connections>
                                                    </button>
                                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="v2b-2E-upp">
                                                        <rect key="frame" x="179.5" y="0.0" width="163.5" height="34"/>
                                                        <color key="backgroundColor" red="0.99806135890000003" green="0.96808904409999996" blue="0.12760734560000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                        <state key="normal" title="With Squeeze"/>
                                                        <connections>
                                                            <action selector="squeezeAnim:" destination="Zg0-f1-bBK" eventType="touchUpInside" id="ARc-fQ-XRE"/>
                                                        </connections>
                                                    </button>
                                                </subviews>
                                            </stackView>
                                        </subviews>
                                        <color key="backgroundColor" red="1" green="0.14913141730000001" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                        <constraints>
                                            <constraint firstAttribute="trailing" secondItem="VMQ-JX-yNt" secondAttribute="trailing" constant="8" id="T0v-du-5Aj"/>
                                            <constraint firstItem="VMQ-JX-yNt" firstAttribute="top" secondItem="clh-vv-1e4" secondAttribute="top" constant="8" id="Y2j-KP-ylE"/>
                                            <constraint firstItem="VMQ-JX-yNt" firstAttribute="leading" secondItem="clh-vv-1e4" secondAttribute="leading" constant="8" id="mKK-5Q-IhS"/>
                                            <constraint firstAttribute="bottom" secondItem="VMQ-JX-yNt" secondAttribute="bottom" constant="8" id="uJf-Y8-Uun"/>
                                        </constraints>
                                    </view>
                                    <view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="6L1-Bv-SxB">
                                        <rect key="frame" x="0.0" y="58" width="359" height="232"/>
                                        <subviews>
                                            <datePicker contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" datePickerMode="dateAndTime" minuteInterval="1" translatesAutoresizingMaskIntoConstraints="NO" id="0A6-0Z-m7u">
                                                <rect key="frame" x="8" y="8" width="343" height="216"/>
                                                <color key="backgroundColor" red="1" green="0.83234566450000003" blue="0.47320586440000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                <date key="date" timeIntervalSinceReferenceDate="590598642.83352995">
                                                    <!--2019-09-19 15:10:42 +0000-->
                                                </date>
                                            </datePicker>
                                        </subviews>
                                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                        <constraints>
                                            <constraint firstItem="0A6-0Z-m7u" firstAttribute="centerY" secondItem="6L1-Bv-SxB" secondAttribute="centerY" id="Eqi-Od-JBH"/>
                                            <constraint firstItem="0A6-0Z-m7u" firstAttribute="leading" secondItem="6L1-Bv-SxB" secondAttribute="leading" constant="8" id="IEp-7K-buG"/>
                                            <constraint firstAttribute="height" constant="232" id="e1y-wA-jqj"/>
                                            <constraint firstAttribute="trailing" secondItem="0A6-0Z-m7u" secondAttribute="trailing" constant="8" id="hLe-WM-Qnx"/>
                                        </constraints>
                                    </view>
                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Standard UILabel" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="X5m-RD-zx4">
                                        <rect key="frame" x="0.0" y="298" width="359" height="40"/>
                                        <color key="backgroundColor" red="0.46202266219999999" green="0.83828371759999998" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                        <constraints>
                                            <constraint firstAttribute="height" constant="40" id="4c2-X0-9Kb"/>
                                        </constraints>
                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                        <nil key="textColor"/>
                                        <nil key="highlightedColor"/>
                                    </label>
                                </subviews>
                            </stackView>
                        </subviews>
                        <color key="backgroundColor" red="0.52747867609999999" green="1" blue="0.55622484120000004" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                        <constraints>
                            <constraint firstItem="k9S-Qf-yG1" firstAttribute="trailing" secondItem="vDP-gh-oah" secondAttribute="trailing" constant="8" id="5C9-Ef-syQ"/>
                            <constraint firstItem="vDP-gh-oah" firstAttribute="top" secondItem="k9S-Qf-yG1" secondAttribute="top" constant="100" id="cuG-HE-aDz"/>
                            <constraint firstItem="vDP-gh-oah" firstAttribute="leading" secondItem="rze-A8-JnC" secondAttribute="leading" constant="8" id="f5f-qW-BJ2"/>
                        </constraints>
                        <viewLayoutGuide key="safeArea" id="k9S-Qf-yG1"/>
                    </view>
                    <connections>
                        <outlet property="normalButton" destination="Zb9-rN-qPb" id="0sr-a2-wa9"/>
                        <outlet property="pickerHolderHeightConstraint" destination="e1y-wA-jqj" id="t7m-zQ-RwA"/>
                        <outlet property="pickerHolderView" destination="6L1-Bv-SxB" id="hkf-zy-GIS"/>
                        <outlet property="squeezeButton" destination="v2b-2E-upp" id="fFe-hm-qzd"/>
                        <outlet property="thePickerView" destination="0A6-0Z-m7u" id="ubt-fR-mx9"/>
                    </connections>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="e1N-yd-USh" userLabel="First Responder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="2244" y="126.38680659670166"/>
        </scene>
    </scenes>
</document>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...