ios - 为什么我会收到此委托代码的错误?
问题描述
我即将编写一个具有多种游戏模式的小应用程序。现在我希望主类的模式(其中游戏模式使用滑块设置)作为标签显示在不同的类中。我收到错误消息:线程 1:致命错误:在隐式展开可选值时意外发现 nil。
我有几个 ViewController。在第一个我有滑块。在第二个上,我有两个按钮来决定是真还是敢。在第三个上,我有应该更改的标签。在第一个 ViewController 上有一个“开始”按钮,它将启动游戏。
我已经尝试将委托放在 viewDidLoad 函数中,但没有成功。
我的 Slider 在“ViewController”类中,这是主类。chooseButtonTapped 在“ThisViewController”类中。游戏模式应显示在“ThisViewController”中,并使用“ViewController”类中的滑块进行设置。
以下是我的代码的几个部分:
我的代表:
protocol SpielmodusDelegate {
func didChooseGamemode(gm: String)
}
我的滑块:
var selectionDelegate: SpielmodusDelegate!
@IBAction gamemodeSliderChanges(_ sender: UISlider) {
if (currentValue > 0.8 && currentvalue < 1) {
gamemodeLabel.text = dataSource[4]
selectionDelegate.didChooseGamemode(gm: "Extrem") <-------ERROR
}
}
我要导入游戏模式的其他课程:
@IBAction func chooseButtonTapped(_ sender: UIButton) {
let selectionVC = storyboard?.instantiateViewController(withIdentifier:
"ViewController") as! ViewController
selectionVC.selectionDelegate = self
present(selectionVC, animated: true, completion: nil)
}
要导入游戏模式的类的扩展:
extension ThisViewController: SpielmodusDelegate {
func didChooseGamemode(gm: String) {
label.text = gm
}
}
我看过一些教程并阅读了一些关于代表的东西,但我仍然不知道问题是什么。
解决方案
编辑
在来自 OP 的评论和其他信息之后......
您正在尝试以完全错误的方式使用委托/协议。
您要做的是在“下一个”视图控制器中设置变量。
看看这个:
将第ViewController
一个嵌入到UINavigationController
.
FirstViewController
管理滑块。
当您点击“开始”按钮时,它将实例化SecondViewController
并设置其 currentMode
变量,然后将其推送到导航堆栈上。
当您点击“Truth”或“Dare”按钮时,它将实例化ThirdViewController
并设置其 currentMode
和buttonSelected
变量,然后将其推送到导航堆栈上。
这是示例代码:
import UIKit
enum GameModeValues: Int {
case Easy
case Normal
case Difficult
case Extrem
}
class ViewController: UIViewController {
@IBOutlet var theSlider: UISlider!
@IBOutlet var gamemodeLabel: UILabel!
var currentMode: GameModeValues = .Easy
override func viewDidLoad() {
super.viewDidLoad()
theSlider.minimumValue = 0
theSlider.maximumValue = 3.99
theSlider.value = Float(currentMode.rawValue)
gamemodeLabel.text = "\(currentMode)"
}
@IBAction func sliderChanged(_ sender: UISlider) {
let intValue = Int(sender.value)
if currentMode.rawValue != intValue {
currentMode = GameModeValues(rawValue: intValue) ?? GameModeValues.Easy
gamemodeLabel.text = "\(currentMode)"
}
}
@IBAction func startButtonTapped(_ sender: Any) {
if let vc = storyboard?.instantiateViewController(withIdentifier: "SecondViewController") as? SecondViewController {
vc.currentMode = currentMode
self.navigationController?.pushViewController(vc, animated: true)
}
}
}
class SecondViewController: UIViewController {
var currentMode: GameModeValues = .Easy
@IBOutlet var gamemodeLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
gamemodeLabel.text = "\(currentMode)"
}
@IBAction func truthButtonTapped(_ sender: Any) {
gotoThirdViewController("Truth")
}
@IBAction func dareButtonTapped(_ sender: Any) {
gotoThirdViewController("Dare")
}
func gotoThirdViewController(_ truthOrDare: String) -> Void {
if let vc = storyboard?.instantiateViewController(withIdentifier: "ThirdViewController") as? ThirdViewController {
vc.currentMode = currentMode
vc.buttonSelected = truthOrDare
self.navigationController?.pushViewController(vc, animated: true)
}
}
}
class ThirdViewController: UIViewController {
var currentMode: GameModeValues = .Easy
var buttonSelected: String = "Truth"
@IBOutlet var gamemodeLabel: UILabel!
@IBOutlet var buttonSelectedLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
gamemodeLabel.text = "\(currentMode)"
buttonSelectedLabel.text = buttonSelected
}
}
这是故事板源代码,因此您可以直接进入并查看它的实际效果:
<?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="EzF-nU-R7k">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<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>
<!--View Controller-->
<scene sceneID="wYk-Om-cIK">
<objects>
<viewController id="kaD-ge-RGe" customClass="ViewController" customModule="LaunchTest2" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="EDR-jw-bbQ">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="cEy-pg-8yn">
<rect key="frame" x="170.5" y="205" width="34" height="30"/>
<state key="normal" title="Start"/>
<connections>
<action selector="startButtonTapped:" destination="kaD-ge-RGe" eventType="touchUpInside" id="9pa-6m-mdo"/>
</connections>
</button>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.5" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="0UU-3B-stg">
<rect key="frame" x="18" y="295" width="339" height="31"/>
<connections>
<action selector="sliderChanged:" destination="kaD-ge-RGe" eventType="valueChanged" id="rCT-Cq-cKf"/>
</connections>
</slider>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="RIp-YU-EZ0">
<rect key="frame" x="166.5" y="385" width="42" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="View Controller" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kNM-Z6-BFV">
<rect key="frame" x="129" y="124" width="117" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="0UU-3B-stg" firstAttribute="leading" secondItem="V6S-9h-7yR" secondAttribute="leading" constant="20" id="1Bg-Og-bpG"/>
<constraint firstItem="RIp-YU-EZ0" firstAttribute="centerX" secondItem="EDR-jw-bbQ" secondAttribute="centerX" id="GgG-qI-Zhp"/>
<constraint firstItem="0UU-3B-stg" firstAttribute="top" secondItem="cEy-pg-8yn" secondAttribute="bottom" constant="60" id="MMd-ja-8TW"/>
<constraint firstItem="cEy-pg-8yn" firstAttribute="top" secondItem="kNM-Z6-BFV" secondAttribute="bottom" constant="60" id="Rbo-U2-VHe"/>
<constraint firstItem="kNM-Z6-BFV" firstAttribute="top" secondItem="V6S-9h-7yR" secondAttribute="top" constant="60" id="ZDi-Ou-t1c"/>
<constraint firstItem="V6S-9h-7yR" firstAttribute="trailing" secondItem="0UU-3B-stg" secondAttribute="trailing" constant="20" id="n7E-Ik-Znh"/>
<constraint firstItem="RIp-YU-EZ0" firstAttribute="top" secondItem="0UU-3B-stg" secondAttribute="bottom" constant="60" id="pcX-zl-Mf3"/>
<constraint firstItem="cEy-pg-8yn" firstAttribute="centerX" secondItem="EDR-jw-bbQ" secondAttribute="centerX" id="sXu-6I-GZf"/>
<constraint firstItem="kNM-Z6-BFV" firstAttribute="centerX" secondItem="EDR-jw-bbQ" secondAttribute="centerX" id="zKl-Us-iJy"/>
</constraints>
<viewLayoutGuide key="safeArea" id="V6S-9h-7yR"/>
</view>
<navigationItem key="navigationItem" id="qyP-ln-h7M"/>
<connections>
<outlet property="gamemodeLabel" destination="RIp-YU-EZ0" id="zf6-DU-NeT"/>
<outlet property="theSlider" destination="0UU-3B-stg" id="7Ie-7w-jFw"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="geN-ym-2yS" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1068" y="215.44227886056973"/>
</scene>
<!--Second View Controller-->
<scene sceneID="sf5-TB-sau">
<objects>
<viewController storyboardIdentifier="SecondViewController" id="h9x-Im-nTy" customClass="SecondViewController" customModule="LaunchTest2" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="RXf-JA-XkI">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="yLo-sI-rY9">
<rect key="frame" x="169" y="242" width="37" height="30"/>
<state key="normal" title="Truth"/>
<connections>
<action selector="truthButtonTapped:" destination="h9x-Im-nTy" eventType="touchUpInside" id="5xP-1e-c08"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="8BM-bn-86x">
<rect key="frame" x="171" y="332" width="33" height="30"/>
<state key="normal" title="Dare"/>
<connections>
<action selector="dareButtonTapped:" destination="h9x-Im-nTy" eventType="touchUpInside" id="njl-le-CMY"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Second View Controller" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3Od-JO-yEA">
<rect key="frame" x="97.5" y="80" width="180" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Game Mode Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Uct-vv-SSq">
<rect key="frame" x="118" y="161" width="139" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="8BM-bn-86x" firstAttribute="centerX" secondItem="RXf-JA-XkI" secondAttribute="centerX" id="Hrm-TE-ocS"/>
<constraint firstItem="Uct-vv-SSq" firstAttribute="top" secondItem="3Od-JO-yEA" secondAttribute="bottom" constant="60" id="cky-Ow-tOC"/>
<constraint firstItem="8BM-bn-86x" firstAttribute="top" secondItem="yLo-sI-rY9" secondAttribute="bottom" constant="60" id="d8A-4y-Tt7"/>
<constraint firstItem="yLo-sI-rY9" firstAttribute="top" secondItem="Uct-vv-SSq" secondAttribute="bottom" constant="60" id="f3t-gw-hg7"/>
<constraint firstItem="3Od-JO-yEA" firstAttribute="top" secondItem="LzW-mg-KAw" secondAttribute="top" constant="60" id="iKq-Nc-Wpn"/>
<constraint firstItem="Uct-vv-SSq" firstAttribute="centerX" secondItem="RXf-JA-XkI" secondAttribute="centerX" id="oAh-7Z-5Uc"/>
<constraint firstItem="3Od-JO-yEA" firstAttribute="centerX" secondItem="RXf-JA-XkI" secondAttribute="centerX" id="rcc-r2-6jz"/>
<constraint firstItem="yLo-sI-rY9" firstAttribute="centerX" secondItem="RXf-JA-XkI" secondAttribute="centerX" id="ubo-Xt-2bT"/>
</constraints>
<viewLayoutGuide key="safeArea" id="LzW-mg-KAw"/>
</view>
<connections>
<outlet property="gamemodeLabel" destination="Uct-vv-SSq" id="gez-Ie-G4n"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="IIe-79-ZbY" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1746" y="215"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="Gj0-Xb-uvT">
<objects>
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="EzF-nU-R7k" sceneMemberID="viewController">
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="c80-8v-3ra">
<rect key="frame" x="0.0" y="20" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<nil name="viewControllers"/>
<connections>
<segue destination="kaD-ge-RGe" kind="relationship" relationship="rootViewController" id="LEe-hD-Fyl"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="5UX-yJ-buo" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="370" y="215"/>
</scene>
<!--Third View Controller-->
<scene sceneID="XIm-bw-14T">
<objects>
<viewController storyboardIdentifier="ThirdViewController" id="Sg0-vM-Ir7" customClass="ThirdViewController" customModule="LaunchTest2" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="eVd-jb-0fY">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Third View Controller" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="txR-9a-ybO">
<rect key="frame" x="107" y="80" width="161" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Game Mode Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2M0-8h-jtQ">
<rect key="frame" x="118" y="161" width="139" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Button Selected Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Zug-Dn-13z">
<rect key="frame" x="103" y="242" width="169" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="2M0-8h-jtQ" firstAttribute="centerX" secondItem="eVd-jb-0fY" secondAttribute="centerX" id="Eoi-YU-vc6"/>
<constraint firstItem="Zug-Dn-13z" firstAttribute="top" secondItem="2M0-8h-jtQ" secondAttribute="bottom" constant="60" id="EtH-T4-MD5"/>
<constraint firstItem="txR-9a-ybO" firstAttribute="top" secondItem="BOa-UN-1aS" secondAttribute="top" constant="60" id="nyi-KX-pGE"/>
<constraint firstItem="txR-9a-ybO" firstAttribute="centerX" secondItem="eVd-jb-0fY" secondAttribute="centerX" id="qOD-65-vLb"/>
<constraint firstItem="Zug-Dn-13z" firstAttribute="centerX" secondItem="eVd-jb-0fY" secondAttribute="centerX" id="rZa-Xu-pzH"/>
<constraint firstItem="2M0-8h-jtQ" firstAttribute="top" secondItem="txR-9a-ybO" secondAttribute="bottom" constant="60" id="wrI-a0-ak4"/>
</constraints>
<viewLayoutGuide key="safeArea" id="BOa-UN-1aS"/>
</view>
<connections>
<outlet property="buttonSelectedLabel" destination="Zug-Dn-13z" id="GLO-r2-gY6"/>
<outlet property="gamemodeLabel" destination="2M0-8h-jtQ" id="Ay0-dI-rmU"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="TPA-ns-oaF" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="2447" y="215"/>
</scene>
</scenes>
</document>
(这是最初的答案,在评论和附加信息之前)
听起来/看起来您还有其他问题,我们在您的帖子中没有看到。所以......从基础开始,以确保您的协议/委托设置正确。
初始视图控制器属于 类ThisViewController
。它有一个按钮连接到@IBAction func chooseButtonTapped(_ sender: UIButton)
.
另一个视图控制器属于 class ViewController
。它有一个UISlider
连接到@IBAction func gamemodeSliderChanges(_ sender: UISlider)
(确保它有一个ViewController的 Storyboard ID )。
使用此代码:
import UIKit
protocol SpielmodusDelegate: class {
func didChooseGamemode(gm: String)
}
class ViewController: UIViewController {
// use weak var for the delegate
weak var selectionDelegate: SpielmodusDelegate?
@IBAction func gamemodeSliderChanges(_ sender: UISlider) {
if sender.value > 0.8 {
selectionDelegate?.didChooseGamemode(gm: "Extrem")
} else {
selectionDelegate?.didChooseGamemode(gm: "Normal")
}
}
}
class ThisViewController: UIViewController {
@IBAction func chooseButtonTapped(_ sender: UIButton) {
if let vc = storyboard?.instantiateViewController(withIdentifier: "ViewController") as? ViewController {
vc.selectionDelegate = self
present(vc, animated: true, completion: nil)
}
}
}
extension ThisViewController: SpielmodusDelegate {
func didChooseGamemode(gm: String) {
print("Received: " + gm)
}
}
并运行应用程序。
点击按钮应该出现ViewController
滑块。当您拖动滑块时,您应该会在调试控制台中看到重复打印:
Received: Normal
Received: Normal
Received: Normal
Received: Normal
Received: Normal
Received: Extrem
Received: Extrem
Received: Extrem
etc...
那应该行得通。如果是这样,请将其与您当前项目的设置方式进行比较。
推荐阅读
- angular - 无法在 NgFor 循环中获取 API 数据
- python - 根据论文中的说明对编码器-解码器进行建模
- python-3.x - 将 .xlsx 文件保存到 ec2,得到一个空文件作为响应
- r - 将某列的字符修剪到一定长度
- performance - 有没有一种在 GKE 上运行基准测试的好方法?
- c# - 识别任意位置的文本
- altbeacon - altbeacon 和 Android10 前台服务权限
- bash - 如何在 bash 脚本中组合多个 echo 语句的输出以将它们作为单行输出到标准输出
- vb.net - 检查两个数据表是否包含相同的数据
- linux - 打开终端时运行 Python 脚本(xterm)