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