Я пытаюсь заставить 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)
}
}