Анимация автоматического показа / скрытия стека прекрасно работает для некоторых вещей.Для других, например, с видом сборщика, не так много (как вы видели).
Один из подходов будет следующим:
- встроить вид сборщика в обычный вид
- ограничить его по центру по вертикали
- добавить высоту по умолчанию к содержащему представлению (например, немного выше, чем представление выбора)
- анимировать ограничение высоты представления
Виды сборщика не будут "сжиматься" сами по себе, поэтому вы получите "исчезающий" вид сборщика.Если вы хотите, чтобы он "сжимался" во время анимации, вам также нужно анимировать его преобразование
Вот пример (я использую контрастные цвета, чтобы было удобно видеть элементы, и я замедлилпродолжительность анимации, чтобы сделать это очевидным):
Вот пример кода:
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
}
}
}
}
Использование этого макета:
и вот источник раскадровки (так что вы можете быстро попробовать его самостоятельно):
<?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>