Как заставить UIPickerView появляться внутри StackView на игровой площадке, используя ограничения? - PullRequest
0 голосов
/ 22 марта 2019

Я пытаюсь заставить UIPickerView появиться внутри stackView в swift playground.В настоящее время есть только белая коробка без параметров вместо вида. Проблемы с UIPickerView внутри StackView рекомендует добавить ограничения ширины и высоты в представление выбора.Однако, когда я делаю это и пытаюсь загрузить страницу,

она вылетает с

"libc ++ abi.dylib: завершается с необработанным исключением типа NSException"

Ниже приведен код (armorPicker начинает строку 91).Как правильно добавить ограничения, чтобы представление отображалось правильно?

import UIKit
import PlaygroundSupport

class PickerData : NSObject, UIPickerViewDataSource, UIPickerViewDelegate {
    var data = [String]()
    init(data: Array<String>) {
        self.data = data
    }

    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return data.count
    }

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return data[row]
    }
}


public class ArmorPickerController : UIViewController {

    let armorPicker = UIPickerView()
    let stack = UIStackView()
    let nextBtn = UIButton()
    let aboutBtn = UIButton()
    let mainTitle = UILabel()



    public override func viewWillAppear(_ animated: Bool) {
        //Hide the grey bar on top of the screen
        self.navigationController?.setNavigationBarHidden(true, animated: false)
    }

    public override func viewDidLoad() {
        super.viewDidLoad()

        self.navigationController?.setNavigationBarHidden(true, animated: false)

        title = "Build a D&D 5e Fighter ⚔️"



        //Set up main UIStackView
        stack.axis = .vertical
        stack.alignment = .center
        stack.spacing = 20
        stack.translatesAutoresizingMaskIntoConstraints = false

        view.addSubview(stack)

        //Add constraints
        view.addConstraints(
            NSLayoutConstraint.constraints(withVisualFormat: "V:|-60-[stackView]-60-|",
                                           options: NSLayoutConstraint.FormatOptions(rawValue: 0),
                                           metrics: nil,
                                           views: ["stackView": stack])
        )
        view.addConstraints(
            NSLayoutConstraint.constraints(withVisualFormat: "H:|-20-[stackView]-20-|",
                                           options: NSLayoutConstraint.FormatOptions(rawValue: 0),
                                           metrics: nil,
                                           views: ["stackView": stack])
        )

        //Set up mainTitle
        mainTitle.text = "Choose your Armor"
        mainTitle.textAlignment = .center
        mainTitle.textColor = UIColor.black
        mainTitle.font = UIFont(name: "HelveticaNeue-MediumBold", size: 30.0)
        mainTitle.sizeToFit()

        //Set up aboutBtn
        aboutBtn.backgroundColor = .black
        aboutBtn.layer.borderColor = UIColor.white.cgColor
        aboutBtn.layer.borderWidth = 2
        aboutBtn.layer.cornerRadius = 5
        aboutBtn.setTitle("About D&D Armor", for: .normal)
        aboutBtn.titleLabel?.font = UIFont(name: "HelveticaNeue", size: 18.0)
        aboutBtn.setTitleColor(.white, for: .normal)
        aboutBtn.titleLabel?.shadowOffset = CGSize(width: 0.5, height: 0.5)
        aboutBtn.setTitleShadowColor(#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1), for: .highlighted)
        aboutBtn.contentEdgeInsets = UIEdgeInsets.init(top: 10, left: 15, bottom: 10, right: 15)
        aboutBtn.addTarget(self, action: #selector(WeaponPickerController.about), for: .touchUpInside)


        //setup character armor picker
        let armor = PickerData(data: ["Studded Leather ?", "Chain Mail ⛓", "Splint ?", "Plate Mail ⚙️"])
        armorPicker.backgroundColor = .white
        armorPicker.dataSource = armor
        armorPicker.delegate = armor
        armorPicker.reloadAllComponents()

        stack.addConstraints(
            NSLayoutConstraint.constraints(withVisualFormat: "V:|-60-[stackView]-60-|",
                                           options: NSLayoutConstraint.FormatOptions(rawValue: 0),
                                           metrics: nil,
                                           views: ["pickerView": armorPicker])
        )
        stack.addConstraints(
            NSLayoutConstraint.constraints(withVisualFormat: "H:|-20-[stackView]-20-|",
                                           options: NSLayoutConstraint.FormatOptions(rawValue: 0),
                                           metrics: nil,
                                           views: ["pickerView": armorPicker])
        )
        //Set up nextBtn
        nextBtn.backgroundColor = .green
        nextBtn.layer.borderColor = UIColor.black.cgColor
        nextBtn.layer.borderWidth = 2
        nextBtn.layer.cornerRadius = 5
        nextBtn.setTitle("Choose your Weapon", for: .normal)
        nextBtn.titleLabel?.font = UIFont(name: "HelveticaNeue", size: 20.0)
        nextBtn.setTitleColor(.black, for: .normal)
        nextBtn.titleLabel?.shadowOffset = CGSize(width: 1, height: 1)
        nextBtn.setTitleShadowColor(#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1), for: .highlighted)
        nextBtn.contentEdgeInsets = UIEdgeInsets.init(top: 10, left: 15, bottom: 10, right: 15)
        nextBtn.addTarget(self, action: #selector(RacePickerController.nextScene), for: .touchUpInside)

        //add components to view
        stack.addArrangedSubview(mainTitle)
        stack.addArrangedSubview(aboutBtn)
        stack.addArrangedSubview(armorPicker)
        stack.addArrangedSubview(nextBtn)
        view.backgroundColor = UIColor(red: 229.0/255, green: 243.0/255, blue: 255.0/255, alpha: 1.0)

    }

    public override func loadView() {
        self.navigationController?.navigationBar.topItem?.title = ""
        self.navigationController?.setNavigationBarHidden(false, animated: false)
        let view = UIView()
        self.view = view
    }

    @IBAction func nextScene() {
        self.navigationController?.pushViewController(WeaponPickerController(), animated: true)
    }

    @IBAction func about() {
        let alertController = UIAlertController(title: "Chose your character's armor", message: "D&D 5e provides a few options for armor. For light protection that lets you stay evasive, choose studded leather, or choose plate mail to soak up heavy blows.", preferredStyle: UIAlertController.Style.alert)
        alertController.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
        present(alertController, animated: true, completion: nil)
    }
}
...