Почему я получаю ошибку для этого кода делегата? - PullRequest
0 голосов
/ 25 июня 2019

Я собираюсь запрограммировать небольшое приложение с несколькими режимами игры.Теперь я хочу, чтобы режимы основного класса (в которых режим игры установлен с помощью ползунка) отображались в другом классе в качестве метки.Я получаю сообщение об ошибке: Поток 1: Неустранимая ошибка: неожиданно обнаружен ноль при неявном развертывании необязательного значения.

У меня есть несколько ViewControllers.На первом у меня есть слайдер.На втором у меня есть две кнопки, чтобы выбрать между правдой или вызовом.И на третьем у меня есть ярлык, который должен быть изменен.На первом ViewController есть кнопка «Пуск», которая запускает игру.

Я уже пытался поместить делегата в функцию viewDidLoad, но это не сработало.

Мой ползунокнаходится в классе "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
  }
}

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

1 Ответ

0 голосов
/ 25 июня 2019

Редактировать

После комментариев и дополнительной информации от ОП ...

Вы пытаетесь использовать делегат / протокол совершенно неправильно.

То, что вы хотите сделать, это установить переменные в ваших «следующих» контроллерах представления.

Взгляните на это:

enter image description here

Вставить Первый ViewController в UINavigationController.

Первый ViewController управляет ползунком.

Когда вы нажимаете кнопку «Пуск», он создает экземпляр SecondViewController и устанавливает ее currentMode переменную, а затем помещает ее в стек навигации.

Когда вы нажимаете кнопки «Правда» или «Смелость», он создает экземпляр 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>

(Это был первоначальный ответ, до комментариев и дополнительной информации)

Звучит / похоже, что у вас есть что-то ещеидет не так, чего мы не видим в вашем посте.Итак ... начнем с основ, чтобы убедиться, что ваш протокол / делегат настроен правильно.

enter image description here

Контроллер начального представления имеет класс ThisViewController.Он имеет кнопку, подключенную к @IBAction func chooseButtonTapped(_ sender: UIButton).

Другой контроллер представления имеет класс ViewController.UISlider подключен к @IBAction func gamemodeSliderChanges(_ sender: UISlider) (убедитесь, что у него Storyboard ID ViewController ).

Используйте этот код:

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...

Это должно работать.Если это так, сравните это с тем, как настроен ваш текущий проект.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...