简单的 UIImage 动画滞后

Simple UIImage animation lags

我正在编写一个简单的应用程序,其中的云向飞机移动。平面可以在滑块的帮助下移动。由于时间可以通过标签显示,所以飞机的位置总是跳回默认值并且滞后。有没有人给我小费?我找不到错误:(

问候菲利普

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var slider: UISlider!
    
    @IBOutlet weak var Label2: UILabel!
    
    @IBOutlet weak var airplane: UIImageView!
    @IBOutlet weak var cloud1: UIImageView!
    
    let screenWidth = UIScreen.main.bounds.size.width
    
    override func viewDidLoad() {
        super.viewDidLoad()
        loop()
    }
    
    
    @IBAction func moveSlider(_ sender: UISlider) {
        let currentValue :Float = sender.value
        
        airplane.center.x = CGFloat(currentValue) * screenWidth

    }
        
    func loop() {
               
        let startDate = Date()
        
        Timer.scheduledTimer(withTimeInterval: 0.05, repeats: true) { (aTimer) in
                       
            RunLoop.current.add(aTimer, forMode: .common)
            aTimer.tolerance = 0.1

            DispatchQueue.main.async {
                self.cloud1.frame.origin.y += 1.0
                self.Label2.text = String(format: "%.1f", aTimer.fireDate.timeIntervalSince(startDate))
            }
        }
    }
}

演示:https://imgur.com/a/sgK3xXo

这是我的故事板和约束:

问题是您已经为您的飞机图像视图设置了 CenterX 约束,但是您试图通过更改其 frame.origin.x.因此,每次屏幕更新时,自动布局都会将该图像视图移回其 CenterX 约束位置。

您需要为该 CenterX 约束添加 @IBOutlet,然后更新其 .constant 值以移动它。

它应该是这样的(只是滑块和飞机图像视图):

如果您查看 Airplane CenterX 列在约束中的位置,那是 imageView 水平约束到滑块(centerX 到 centerX)。

这是视图控制器 class 的样子:

class MovePlaneViewController: UIViewController {

    @IBOutlet var slider: UISlider!
    @IBOutlet var airplane: UIImageView!
    
    @IBOutlet var airplaneCenterX: NSLayoutConstraint!

    var sliderInnerWidth: CGFloat = 0

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        // because the slider Thumb goes edge-to-edge
        //  we only want to use the ThumbCenter-to-ThumbCenter range
        //  for later positioning
        let trackRect = slider.trackRect(forBounds: slider.bounds)
        let thumbRect = slider.thumbRect(forBounds: slider.bounds, trackRect: trackRect, value: 0)
        sliderInnerWidth = slider.frame.width - thumbRect.size.width
        
        // call your loop func here
        //loop()
    }

    @IBAction func moveSlider(_ sender: UISlider) {
        let currentValue: CGFloat = CGFloat(sender.value)
        
        var xOffset: CGFloat = sliderInnerWidth * currentValue
        // this will make the offset
        //  less-than Zero if slider is less-than 50%
        //  greater-than Zero if slider is greater-than 50%
        xOffset -= sliderInnerWidth / 2.0
        
        // update the airplane's centerX constant
        airplaneCenterX.constant = xOffset
        
    }

}

这是 Storyboard 源代码,因此您可以轻松试用(然后使用其余代码和 UI 元素实现它):

<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="q2w-Zv-3Jg">
    <device id="retina4_7" orientation="portrait" appearance="light"/>
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
        <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>
        <!--Move Plane View Controller-->
        <scene sceneID="jAY-b9-7YF">
            <objects>
                <viewController id="q2w-Zv-3Jg" customClass="MovePlaneViewController" customModule="PanZoom" customModuleProvider="target" sceneMemberID="viewController">
                    <view key="view" contentMode="scaleToFill" id="2bg-MF-Dfi">
                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.5" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="12v-ia-vOX">
                                <rect key="frame" x="14" y="607" width="347" height="31"/>
                                <connections>
                                    <action selector="moveSlider:" destination="q2w-Zv-3Jg" eventType="valueChanged" id="pHV-BI-Zst"/>
                                </connections>
                            </slider>
                            <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="arrow.up" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="11P-52-E7Q">
                                <rect key="frame" x="67.5" y="473" width="240" height="111"/>
                                <color key="backgroundColor" red="0.45009386540000001" green="0.98132258650000004" blue="0.4743030667" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                <constraints>
                                    <constraint firstAttribute="width" constant="240" id="LYK-Lp-n78"/>
                                    <constraint firstAttribute="height" constant="113" id="sGv-Ri-i7J"/>
                                </constraints>
                            </imageView>
                        </subviews>
                        <viewLayoutGuide key="safeArea" id="Yqd-3m-a1U"/>
                        <color key="backgroundColor" systemColor="systemBackgroundColor"/>
                        <constraints>
                            <constraint firstItem="Yqd-3m-a1U" firstAttribute="bottom" secondItem="12v-ia-vOX" secondAttribute="bottom" constant="30" id="0Hj-gj-Hfm"/>
                            <constraint firstItem="12v-ia-vOX" firstAttribute="leading" secondItem="Yqd-3m-a1U" secondAttribute="leading" constant="16" id="1YJ-9h-PtM"/>
                            <constraint firstItem="12v-ia-vOX" firstAttribute="top" secondItem="11P-52-E7Q" secondAttribute="bottom" constant="22" id="9nV-Wx-JhH"/>
                            <constraint firstItem="Yqd-3m-a1U" firstAttribute="trailing" secondItem="12v-ia-vOX" secondAttribute="trailing" constant="16" id="aR0-q8-Slq"/>
                            <constraint firstItem="11P-52-E7Q" firstAttribute="centerX" secondItem="12v-ia-vOX" secondAttribute="centerX" id="q20-KD-Bjr"/>
                        </constraints>
                    </view>
                    <connections>
                        <outlet property="airplane" destination="11P-52-E7Q" id="bNF-1y-ciX"/>
                        <outlet property="airplaneCenterX" destination="q20-KD-Bjr" id="Gd3-s2-Y9e"/>
                        <outlet property="slider" destination="12v-ia-vOX" id="NYl-Lw-OPy"/>
                    </connections>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="Z13-sS-hmx" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="120.8" y="2189.9550224887557"/>
        </scene>
    </scenes>
    <resources>
        <image name="arrow.up" catalog="system" width="120" height="128"/>
        <systemColor name="systemBackgroundColor">
            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
        </systemColor>
    </resources>
</document>